Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

CuddlyHammy's avatar

HTML2PDF in Laravel

I have a button for creating/viewing a PDF file. This is the controller:

    public function viewCompiledReport($id) 
    {
        ob_start();
        include('view.php');
        $content = ob_get_clean();
        $html2pdf_path = base_path() . '\vendor\spipu\html2pdf\html2pdf.class.php';
        File::requireOnce($html2pdf_path);
        
        try {
            $html2pdf = new \HTML2PDF('P', 'Legal', 'en', true, 'UTF-8', array(25.4, 20.4, 25.4, 20.4));
            $html2pdf->pdf->SetTitle('HTML2PDF Sample');
            $html2pdf->WriteHTML($content);
            $html2pdf->Output('example.pdf');

            ob_flush();
            ob_end_clean();
        }
        catch (HTML2PDF_exception $e) {
            echo $e;
            exit;
        }
    }

view.php is where I get the data I need from the database. This is also where I fix the layout for the pdf. For example:

<page>
Hello World
<img src='images\subreports\GSA\sample-1.png' style='float:center; width:100%'>

<?php
    $projects = DB::table('projects')-> …
    foreach($projects as $project) {
        // echo something
        …
    }
?>
<div>
    // do something else, etc
</div>
</page>

It works the way I want it to but I want to 'laravelize' it (if there's such a word lol). Like separating it into views and controller? I think just doing include('view.php') is not that good. I'm not so sure though. Should I change nothing? If otherwise, any tips on how I should do it? Thanks in advance.

0 likes
5 replies
spekkionu's avatar
Level 47

Instead of including a view.php you could just use $content = view('path/to/template', $variables)->render() to render a blade template and return it as a string.

Since you installed the library with composer and it has an autoload section you should need to manually include the library.

Instead of using output buffering you can pass 'S' as the second parameter to the Output() method to have it return the pdf content as a string rather than outputting it directly. Then you can use it as the content for your response for a more Laravel way of doing it.

$pdf= $html2pdf->Output('', 'S'); // The filename is ignored when you use 'S' as the second parameter.

return response($pdf)
                  ->header('Content-Type', 'application/pdf')
                  ->header('Content-Length', strlen($pdf))
                  ->header('Content-Disposition', 'inline; filename="example.pdf");

Once you've gotten that working I'd extract as much as possible to a separate class.
You can have this class be responsible for all of the interactions with HTML2PDF.
It would return the pdf content as a string which you can pass along to the response.
This would also make it reusable in case you wanted to do something like send the pdf as an attachment in an email or something.

1 like
CuddlyHammy's avatar

@spekkionu Thank you, this is very helpful. Generally, it's working but when I try to access $variables in template.blade.php, (I set $variables = [0, 1, 2, 3] before $content = ...just to try it out. ), it says Undefined variable: variables. What else do I need for this to work?

CuddlyHammy's avatar

Anyway, I already figured it out. I should pass ['variables' => $variables] instead of just $variables. Thank you!

siller's avatar

hi everyone:)...how to incorporate html2pdf in laravel 6...?i hope you can help me..thank you very much..:)

Benjaminhu's avatar

@siller This works for me with Laravel 8:

$content = '';
$filename = 'download.pdf';
$html2pdf = new Html2Pdf('P', 'A4', 'en', true, 'UTF-8');
$html2pdf->setDefaultFont('helvetica');
$html2pdf->writeHTML($content);
$pdf = $html2pdf->output($filename, 'S');

return response()->make($pdf, 200, [
    'Content-Type' => 'application/pdf',
    'Content-Length' => strlen($pdf),
    'Content-Disposition' => sprintf('inline; filename="%s"', $filename)
]);

Please or to participate in this conversation.