Laravel - Outputting a view styled with TailwindCSS as PDF

Viewed 4550

I'm trying to make generate a pdf from a view but the styles just won't come out. I've tried using 3 different libraries but the results aren't much different. Am I missing something?

view

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Test View</title>
  <link rel="stylesheet" type="text/css" media="screen" href="{{ asset('css/app.css') }}">
  <script src="{{ asset('js/app.js') }}" defer></script>
</head>
<body class="font-sans antialiased">

<div class="grid grid-cols-3">
  <div class="bg-red-200 col-span-2 h-screen"></div>
  <div class="bg-blue-200 h-screen">
    <div class="grid grid-cols-8">
      <div class="col-span-7">
        <div class="rounded-t-full w-full h-screen flex items-center justify-center bg-green-600">
          <div class="h-60 w-60 rounded-full bg-blue-500">TEST</div>
        </div>
      </div>
    </div>
  </div>
</div>

</body>
</html>

appearance

enter image description here


dompdf export method

protected function dompdfImplementation()
{
    $dompdf = new Dompdf;
    $dompdf->getOptions()->setChroot(public_path());
    $dompdf->loadHtml(view('view')->render());

    $dompdf->stream('view.pdf', ['Attachment' => false]);
}

dompdf export result

enter image description here


mpdf export method

protected function mpdfImplementation()
{
    $mpdf = new Mpdf;
    $mpdf->WriteHTML(view('view')->render());

    $mpdf->output();
}

mpdf export result

enter image description here


tcpdf export method

protected function tcpdfImplementation()
{
    $tcpdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
    $tcpdf->AddPage();
    $tcpdf->writeHTML(view('view')->render());

    $tcpdf->Output('view.pdf', 'I');
}

tcpdf export result

enter image description here


Is it not possible to export views to pdf without a css inliner?

Am I better off just manually taking a full page screenshot, pasting it into a text document and saving it as a pdf file?

3 Answers

This package works like a charm (as usual with spatie) : https://github.com/spatie/browsershot

According to the doc :

The package can convert a webpage to an image or pdf. The conversion is done behind the scenes by Puppeteer which controls a headless version of Google Chrome.

If you need support for modern CSS features such as flexbox, which I suppose your Tailwind example utilizes, you'll be better off using headless chrome (or a bit older wkhtmltopdf) to generate the PDF.

An example using chrome-php/chrome:


<?php

use HeadlessChromium\BrowserFactory;
use HeadlessChromium\Page;

require_once __DIR__ . '/vendor/autoload.php';

$browserFactory = new BrowserFactory();

$browser = $browserFactory->createBrowser([
    'noSandbox' => true,
    'customFlags' => [
        '--proxy-server="direct://"',
        '--proxy-bypass-list=*',
        '--font-render-hinting=none',
    ],
]);

$page = $browser->createPage();

$tempname = '//<path to your HTML over HTTP>';

$page->navigate('file://' . $tempname)
    ->waitForNavigation(Page::NETWORK_IDLE);

$outputPath = __DIR__ . '/output.pdf';

$page->pdf([
    'printBackground' => true,
    'preferCSSPageSize' => true,
    'marginTop' => 0.4,
    'marginBottom' => 0.2,
    'marginLeft' => 0.2,
    'marginRight' => 0.2,
])->saveToFile($outputPath);

Use PHP PDF libraries to leverage some of their benefits over browser approach - color handling, pre-print, barcodes support, headers and footers, page numbering, TOCs, etc, but given their support for HTML and CSS, expect a tailored template and stylesheet will most likely be needed.

Of course, the previous paragraph also applies when you are unable to run other software than PHP with your hosting provider.

After

  • trying barryvdh/laravel-dompdf instead of dompdf/dompdf
  • using media="print" on my stylesheet
  • using TailwindCSS's print:* classes
  • trying to get chrome-php to work to no avail
  • trying barryvdh/excel's pdf exports.

Nothing worked so the solution I have reached is a bad one.

  1. Open view in firefox.
  2. Screenshot whole page (not just visible content).
  3. Use the first online PNG to PDF converter I find.

I wish there'd be a less painful way to do this but it doesn't look like it. This bad solution actually works.

Related