Laravel - 将使用 TailwindCSS 设置样式的视图输出为 PDF
Laravel - Outputting a view styled with TailwindCSS as PDF
我正在尝试从视图生成 pdf,但样式就是出不来。我试过使用 3 个不同的库,但结果差别不大。我错过了什么吗?
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
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
mpdf export method
protected function mpdfImplementation()
{
$mpdf = new Mpdf;
$mpdf->WriteHTML(view('view')->render());
$mpdf->output();
}
mpdf export result
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
如果没有 css 内联器,是否无法将视图导出为 pdf?
我是否最好手动截取整页屏幕截图,将其粘贴到文本文档中并另存为 pdf 文件?
如果您需要支持现代 CSS 功能,例如 flexbox,我想您的 Tailwind 示例使用了它,您最好使用 headless chrome(或更旧的 wkhtmltopdf)来生成 PDF。
使用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);
使用 PHP PDF 库来利用它们相对于浏览器方法的一些优势 - 颜色处理、预打印、条形码支持、页眉和页脚、页码、TOC 等,但考虑到它们对 HTML 和 CSS,预计很可能需要定制的模板和样式表。
当然,当您无法通过托管服务提供商 运行 除 PHP 以外的其他软件时,上一段也适用。
之后
- 尝试
barryvdh/laravel-dompdf
而不是 dompdf/dompdf
- 在我的样式表上使用
media="print"
- 使用 TailwindCSS 的
print:*
类
- 试图让
chrome-php
工作无济于事
- 正在尝试
barryvdh/excel
的 pdf 导出。
没有任何效果,所以我找到的解决方案很糟糕。
- 在 firefox 中打开视图。
- 整个页面的屏幕截图(不仅仅是可见内容)。
- 使用我找到的第一个在线 PNG 到 PDF 转换器。
我希望有一种不那么痛苦的方法来做到这一点,但它看起来不像。这个糟糕的解决方案实际上有效。
这个包很有魅力(和 spatie 一样):
https://github.com/spatie/browsershot
根据文档:
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.
我正在尝试从视图生成 pdf,但样式就是出不来。我试过使用 3 个不同的库,但结果差别不大。我错过了什么吗?
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
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
mpdf export method
protected function mpdfImplementation()
{
$mpdf = new Mpdf;
$mpdf->WriteHTML(view('view')->render());
$mpdf->output();
}
mpdf export result
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
如果没有 css 内联器,是否无法将视图导出为 pdf?
我是否最好手动截取整页屏幕截图,将其粘贴到文本文档中并另存为 pdf 文件?
如果您需要支持现代 CSS 功能,例如 flexbox,我想您的 Tailwind 示例使用了它,您最好使用 headless chrome(或更旧的 wkhtmltopdf)来生成 PDF。
使用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);
使用 PHP PDF 库来利用它们相对于浏览器方法的一些优势 - 颜色处理、预打印、条形码支持、页眉和页脚、页码、TOC 等,但考虑到它们对 HTML 和 CSS,预计很可能需要定制的模板和样式表。
当然,当您无法通过托管服务提供商 运行 除 PHP 以外的其他软件时,上一段也适用。
之后
- 尝试
barryvdh/laravel-dompdf
而不是dompdf/dompdf
- 在我的样式表上使用
media="print"
- 使用 TailwindCSS 的
print:*
类 - 试图让
chrome-php
工作无济于事 - 正在尝试
barryvdh/excel
的 pdf 导出。
没有任何效果,所以我找到的解决方案很糟糕。
- 在 firefox 中打开视图。
- 整个页面的屏幕截图(不仅仅是可见内容)。
- 使用我找到的第一个在线 PNG 到 PDF 转换器。
我希望有一种不那么痛苦的方法来做到这一点,但它看起来不像。这个糟糕的解决方案实际上有效。
这个包很有魅力(和 spatie 一样): https://github.com/spatie/browsershot
根据文档:
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.