Laravel - Outputting a view styled with TailwindCSS as PDF
Asked Answered
S

4

6

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?

Shropshire answered 27/5, 2021 at 21:35 Comment(2)
Have you gone throughTailwind Docs # Styling for print or write your own custom css with @media ruleProtolanguage
scoping the stylesheet to media="print" doesn't seem to work either. I think I'm going to look for an inliner.Shropshire
S
-6

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.

Shropshire answered 29/5, 2021 at 19:45 Comment(2)
If this is an acceptable solution, why not print the page to PDF directly with, say, PDFCreator?Tawanda
That could be a solution but I'm not familiar with that software. It's the first time I've heard of it. IF it works, I'd consider it an acceptable solution as well.Shropshire
M
2

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.

Moriyama answered 24/9, 2021 at 10:54 Comment(0)
T
0

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.

Tawanda answered 28/5, 2021 at 6:2 Comment(5)
This is for a personal project so I don't strictly need it to be completely automatic. I'm not sure how to use a headless chrome to achieve what I want. Can you elaborate on that? I just tried wkhtmltopdf and the results were the same. (Just text, no styling)Shropshire
github.com/chrome-php/headless-chromium-phpTawanda
That library looks promising, too bad it's not mantained and just doesn't work.Shropshire
There are many others, just pick. Do some work yourself. packagist.org/packages/chrome-php/chromeTawanda
I'll try that code out tomorrow, but the last time I tried chrome-php it didn't get past the stage of createBrowser(). It threw me errors about the browser not starting and diving into the source code revealed it did not properly support windows .At first glance it does, but for example the first step that library does to create a browser is checking the chrome version... with a command that is meaningless in windows, causing a timeout. Even commenting out that entire section or tripling the timeout didn't help.Shropshire
A
0

This answer might solve the problem: https://mcmap.net/q/277851/-wkhtmltopdf-not-loading-local-css-and-images

Basically you need to add a base tag in the head of your document.

<html>
<head>
...
<base href="http://www.example.com/">
<link href="/assets/css/style.css" rel="stylesheet">
...
</head>

Worked for me with wkhtmltopdf. Might be a similar issue.

Auk answered 19/11, 2023 at 6:46 Comment(0)
S
-6

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.

Shropshire answered 29/5, 2021 at 19:45 Comment(2)
If this is an acceptable solution, why not print the page to PDF directly with, say, PDFCreator?Tawanda
That could be a solution but I'm not familiar with that software. It's the first time I've heard of it. IF it works, I'd consider it an acceptable solution as well.Shropshire

© 2022 - 2025 — McMap. All rights reserved.