Problem to generate reports with DOMPDF + Codeigniter

Asked

Viewed 1,094 times

1

Hello,

I am trying to generate a report using Dompdf but am encountering the following error

A PHP Error was encountered

Severity: Notice

Message: Undefined property: Relatorio::$dompdf

Filename: controllers/Relatorio.php

Line Number: 24

Backtrace:

File: C:\xampp\htdocs\ci_ads\application\controllers\Relatorio.php
Line: 24
Function: _error_handler

File: C:\xampp\htdocs\ci_ads\index.php
Line: 315
Function: require_once

My view:

    <!doctype html>
    <html lang="pt-br">
    <head>
    <meta charset="UTF-8">
    </head>
    <body>
    <style>
    table {
    width: 100%;
    height: 100%;
    }

    body {
    font-family: Arial, Helvetica, sans-serif;
    }

    table thead tr th td {
    border: 1px solid black;
    }

    table thead tr th {
    background-color: #bac6cb;
    font-size: 17px;
    }

    table tbody tr td {
    background-color: #9ba7ac;
    font-size: 14px;
    }
    </style>

    <div id="flex-box">
    <table>
    <thead>
    <tr>
    <td style="text-align: center" colspan="2"><h2>Alunos com maior número de locação</h2></td>
    </tr>
    <tr style="text-align: center">
    <th>Nome do aluno</th>
    <th>Quantidade de locação</th>
    </tr>
    </thead>
    <tbody>
    <?php foreach ($rel as $linha) {
    echo '<tr>';
    echo "<td style=\"text-align: center\">" . $linha['nome'] . "</td>";
    echo "<td style=\"text-align: center\">" . $linha['count'] . "</td>";
    echo '</tr>';
    } ?>
    </tbody>
    </table>
    <p>
    Relatório de alunos que mais locaram E-Book &reg;
   </p>
    </div>
    </body>
    </html>

My Controller

class Report extends Ci_controller {

function __construct() {
    parent::__construct();
    $this->load->model('relatorio_model');
}

public function index() {
    $this->load->view('template/header');
    $this->load->view('relatorio/index');
    $this->load->view('template/footer');
}



public function geraRelatorio() {
    $dados = $this->input->post();
    if ($dados['tipo_relatorio'] == 'REL_LIVRO_MAIS_LOCADO') {
         $data['rel'] = $this->relatorio_model->queryAlunosMaisLocaram();
        $this->load->library('pdf');
        $html = $this->load->view('relatorio/livros_mais_locados', $dados, true);
        $this->dompdf->load_html($html);
        $this->dompdf->set_paper("A4", "portrait"); // to change page orientation to landscape, change the parameter “portrait” to “landscape”
        $this->dompdf->render();
        $filename = "mypdf.pdf";
        $this->dompdf->stream($filename); // to Download PDF
    }
    if ($dados['tipo_relatorio'] == 'REL_ALUNOS_MAIS_LOCARAM') {
        $data['rel'] = $this->relatorio_model->queryAlunosMaisLocaram();
        $this->load->library('pdf');
        $html = $this->load->view('relatorio/alunos_mais_locaram', $dados, true);
        $this->dompdf->load_html($html);
        $this->dompdf->set_paper("A4", "portrait"); // to change page orientation to landscape, change the parameter “portrait” to “landscape”
        $this->dompdf->render();
        $filename = "mypdf.pdf";
        $this->dompdf->stream($filename); // to Download PDF
    }
}
}

Would anyone have any suggestions? Thank you

1 answer

1

To begin with, I would recommend a more versatile and less complicated library, such as the mPDF. But if you really want to keep using this one, at least look for the latest version: dompdf.

This error means that the class Relatorio doesn’t have the property $dompdf that you are invoking. This is because of the way you are loading the library into CodeIgniter. Before using an external library on CodeIgniter read this here attentively.

Aware of these specifications, one of the correct ways to do this would be to declare dompdfas a library in /application/libraries/PdfCreator.php:

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class PdfCreator {

    public function __construct() {
        require_once('/usr/share/php/dompdf/vendor/autoload.php');
        $this->dompdf = new Dompdf\Dompdf();
    }

}
$ci = & get_instance();
$ci->PdfCreator = new PdfCreator();

Declared library, load in instance (I prefer autoload /application/config/autoload.php). In case, you’ll carry it on libraries:

$autoload['libraries'] = array(
    'PdfCreator'
);

Another thing you need to understand is that the dompdf will not render the $html the way you’re doing because the method $this->load->view() returns a object, and not a string. But you can fix this by using the correct property of the returned object, which is final_output. In his controller, the method that creates the pdf gets like this:

function geraRelatorio(){
    $dompdf = $this->PdfCreator->dompdf;
    $dompdf->set_option('isHtml5ParserEnabled', true);
    $data['rel'] = [0=>['nome'=>'teste','count'=>'2']];
    $view = $this->load->view('pages/dompdf',$data);
    $html = $view->output->final_output;
    $dompdf->loadHtml($html);
    $dompdf->setPaper('A4', 'portrait');
    $dompdf->render();
    $dompdf->stream();
}

Plus: you are creating $data['rel'] but it’s just passing $dados to the view. However, its view makes a foreach in the array $rel. Be careful with this, or you will have another problem when generating the document, because the program will look for a variable $rel that does not exist in his scope.

More: dompdf has serious problems to render html ill-formed, and the developer himself says so. Therefore, any error when declaring elements will generate "unexpected" failures. I say this because in your view you are declaring the <style> in the body of the document html, and it will give you a headache when using this library. I tried to avoid this with $dompdf->set_option('isHtml5ParserEnabled', true);, but it seems that it was not enough.

I made a view so it worked:

<!DOCTYPE html>
<html>
    <head>
        <title>Teste</title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="../assets/dompdf.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div id="flex-box">
            <table>
                <thead>
                    <tr>
                        <td style="text-align: center" colspan="2"><h2>Alunos com maior número de locação</h2></td>
                    </tr>
                    <tr style="text-align: center">
                        <th>Nome do aluno</th>
                        <th>Quantidade de locação</th>
                    </tr>
                </thead>
                <tbody>
                    <?php
                    foreach ($rel as $linha) {
                        echo '<tr>';
                        echo "<td style=\"text-align: center\">" . $linha['nome'] . "</td>";
                        echo "<td style=\"text-align: center\">" . $linha['count'] . "</td>";
                        echo '</tr>';
                    }
                    ?>
                </tbody>
            </table>
            <p>
                Relatório de alunos que mais locaram E-Book &reg;
            </p>
        </div>
    </body>
</html>

That’s it.

  • The mPDF library is very complicated and unusual, I strongly recommend the Phpjasper library: https://github.com/geekcom/phpjasper

  • It means that it works very well up to a certain limit of data, for example: very large reports with several joins, you have to write a lot to generate, and it takes time, although it is very good in small and medium reports, unusual pq you need to write a lot to generate a medium to large report.

  • Exactly why I wrote as a comment (suggestion or tip) and not as a response ;)

  • The important thing is that the solution works well for the colleague who asked, I hope that is the case.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.