Thursday, June 29, 2017

Yii2: Integrate FPDF in Yii2




Do you ask yourself how can I make a pdf document that are more complex than using standard html to generate pdf files? If that is your thinking, then this tutorial is for you. Here, I used FPDF or you can also use TCPDF. TCPDF is also derived from FPDF, but be aware that TCPDF has different syntax and features. I used Linux based  Operating system for this tutorial, particularly CentOS version 7. I did not include it to my composer because of the issues that I found in the github. I also used sublime for CentOS 7 for editing files inside my framework directory and lastly, the very important one that I used here is yii2 advanced template for this tutorial. So lets get started. 

1. Download FPDF in this site and extract the zip file and put the folder inside vendor. In this example I extracted my FPDF folder in /var/www/html/coms/vendor/. You can actually delete some bloated files there like tutorial, FAQ, etc. The most important one is the fpdf.php library because we are going to include that in our php files later on. 



2.  Lets create our sample database. Take note that I'm using phpmyadmin in creating tables here, but you can use other database management system which you prefer.  In this example, I'm using the database 'coms', and I created a table called test which we are going to use in creating a PDF file. The structure of my table are id, name, address, amount and email. But can actually change this or add more field to the table name test.


3. Generate crud in gii and populate some data. Below is my sample output. If you have any questions in generating crud, feel free to ask questions below. Maybe you can add more data to get a more realistic approach. 



4. Add sample drop-down button in our index. There is nothing fancy about the codes below. I just want it to be more presentable. 

    <div class="pull-right">
        <div class="dropdown">
            <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown"> <span class="glyphicon glyphicon-export">        
               </span> Export All <span class="caret"></span></button>
                    <ul class="dropdown-menu">
                        <li><?= Html::a('PDF', ['test/export-to-pdf', 'model'=>get_class($searchModel)], ['target'=>'_blank']) ?></li>
                    </ul>
        </div>
    </div>




5. Sample below is the generated dropdown button for our test pdf. 

sample button on the right side
5. Add session and create function which I called getExportData on TestSearch.php. Take note that I'm using frontend model for this tutorial. You can change the model that you prefer like backend or common. The getExportData function just get the session data of the function search and export it into the url frontend/views/test/testpdf. I also called session_start(); at the beginning of the class to work perfectly.

<?php

namespace frontend\models;

use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use frontend\models\Test;

session_start();

class TestSearch extends Test
{
    public function rules()
    {
        return [
            [['id'], 'integer'],
            [['name', 'address', 'email', 'amount'], 'safe'],
        ];
    }

    public function scenarios()
    {
        return Model::scenarios();
    }

    public function search($params)
    {
        $query = Test::find();

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $_SESSION['exportData'] = new ActiveDataProvider([
            'query' => $query,
            'sort' => false,

        ]);

        $this->load($params);

        if (!$this->validate()) {
            return $dataProvider;
        }

        unset($_SESSION['exportData']);

        $_SESSION['exportData'] = $dataProvider;

        $query->andFilterWhere(['like', 'name', $this->name])
            ->andFilterWhere(['like', 'address', $this->address])
            ->andFilterWhere(['like', 'email', $this->email]);

        return $dataProvider;
    }
    public static function getExportData() 
    {
        $data = [
                'data'=>$_SESSION['exportData'],
                'fileName'=>'Report', 
                'title'=>'Report',
                'exportFile'=>'@frontend/views/test/testpdf',
            ];

        return $data;

    }
}



6. Add new function in TestController.php. This function in our controller will get the data in our searchModel. 


    public function actionExportToPdf($model)
    {
        $data = $model::getExportData();

        return $this->render($data['exportFile'], [
            'data'=> $data['data'],
            ]);


    }


7. Add new php file in views which I called testpdf.php. This will be our generated test pdf file. You also need to include the fpdf library in this php file to work perfectly. 


<?php

use frontend\models\Test;
use yii\web\Session;

$session = Yii::$app->session;

$path = Yii::getAlias("@vendor/fpdf/fpdf.php");
require_once($path);

class PDF extends FPDF
{

  function Header()
  {

    $this->SetY(10);
    $this->SetX(10);
    $this->setFont('Arial','',10);
    $this->setFillColor(255,255,255);
    $this->cell(277,5,"ORDER OF PAYMENTS",0,1,'C',1); 
    $this->SetX(10);
    $this->cell(277,5,"FEDERAL BUREAU OF ARBITRATION",0,1,'C',1);  

  }

function Content($data)
{
   
  $y_axis_initial = 30;
  $row_height= 11;
  $y_axis = 24;
  $y_axis = $y_axis + $row_height;

  $i = 0;
  $a = 0;

  $max = 30;
  $row_height = 6;

  foreach ($data->models as $row)
  { 

    if ($i == $max)
     {
          $this->AddPage();
          $y_axis = 35;
          $i = 0;

      }
          $id = $row->id;
          $name = $row->name;
          $amount = $row->amount;
          $address = $row->address;
          $email = $row->email;

          $this->SetFillColor(232,232,232);
          $this->SetFont('Arial','',6);
          $this->SetY(28);
          $this->SetX(10);
          $this->Cell(20,7,'ID',1,0,'C',1);
          $this->Cell(90,7,'NAME',1,0,'C',1);
          $this->Cell(90,7,'ADDRESS',1,0,'C',1);
          $this->Cell(40,7,'EMAIL',1,0,'C',1);
          $this->Cell(40,7,'AMOUNT',1,0,'C',1);

          $this->SetFillColor(255,255,255);
          $this->SetY($y_axis);
          $this->SetX(10);
          $this->Cell(20,7,$id,1,0,'L',1);
          $this->Cell(90,7,$name,1,0,'R',1);
          $this->Cell(90,7,$address,1,0,'R',1);          
          $this->Cell(40,7,$email,1,0,'R',1);
          $this->Cell(40,7,number_format($amount, 2),1,0,'R',1);


          $y_axis = $y_axis + $row_height;
          $i = $i + 1;
          $a = $a + $amount;
  }

          $this->SetY($y_axis);
          $this->SetX(10);
          $this->SetFont('Arial','B',6);
          $this->Cell(240,7,"TOTAL",1,0,'C',1);
          $this->Cell(40,7, number_format( $a,2),1,0,'R',1); 
       
}

  function Footer()
  {

    $this->SetY(-8);
    $this->SetFont('Arial','',7);
    $this->Cell(0,10,'Page '.$this->PageNo().' of {nb}',0,0,'R');
  }
}

$pdf = new PDF('L', 'mm', 'A4');
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->Content($data);
$pdf->Output();

exit;





8. Finally, we can test our button to see the changes. By clicking the pdf button, it will generate a pdf page in our browser.  If you have questions and comments, you can ask me at the comment section below. Thanks for viewing.






generated pdf

3 comments:

  1. FPDF is available via Composer https://packagist.org/packages/setasign/fpdf so it makes no sense to manually extract and unpack it.

    ReplyDelete
    Replies
    1. Thanks for visiting. Maybe I can update this post if I have time. 😊

      Delete
  2. gracias me ayudo mucho.Pero se me presento un problema al momento que quiero exportar cierta cantidad de datos de la búsqueda del gridview no me muestra todos en el pdf. Al parecer el problema es el paginaitor que solo muestra datos de 30 en 30 por default. Le puse paginaitor=false pero por la gran cantidad de datos que manejo no seria dable. Me podrías ayudar y gracias.

    ReplyDelete