php 使用html 生成pdf word wkhtmltopdf 系列1
php 使用html 生成 pdf word
上一篇文章介绍了一下 wkhtmltopdf 相关工具和命令
这个我们来生成一个 pdf 实操一下
初步设计
- 我们将我们想要生成的内容封装切割成一个一个小块的html 最后再用php命令生成出来
- 文章主要有6个模块 安装 → 初始化配置 → 内容设置 → 生成 / 输出 → 配置优化 → 错误处理
- 注意事项
1. 安装 mikehaertl/phpwkhtmltopdf
首先,通过 Composer 安装 PHP WkHtmlToPdf:
composer require mikehaertl/phpwkhtmltopdf
简单示例
<?php
use mikehaertl\wkhtmlto\Pdf;
try {
// 创建 Pdf 实例,可以传递文件路径、HTML 字符串、URL 或选项数组
$pdf = new Pdf('./page.html');
// 如果需要,设置 wkhtmltopdf 可执行文件的路径 php 使用html 生成pdf word wkhtmltopdf 系列 1这里已经配置了 这里就用不上了
// $pdf->binary = 'C:\path\wkhtmltopdf';
// 保存 PDF 文件
if (!$pdf->saveAs('./page.pdf')) {
$error = $pdf->getError();
// 处理错误
}
} catch (\Exception $e) {
echo "错误:" . $e->getMessage();
}
这里一定要确定命令行可以使用 wkhtmltopdf 命令
2.初始化配置
初始化可以理解成 php 构造函数 __construct() 自动加载
这里主要说一下 ‘binary’ 这个函数 如果能预判自己或项目的系统环境可以提前下载好放入指定目录可以省去 [php 使用html 生成pdf word wkhtmltopdf 系列1] 一些安装步骤 简化项目的迁移难度
use mikehaertl\wkhtmlto\Pdf;
// 1. 基础初始化(默认查找系统wkhtmltopdf)
$pdf = new Pdf();
// 2. 指定wkhtmltopdf路径(推荐,避免环境变量问题)
$pdf = new Pdf([
'binary' => '/usr/local/bin/wkhtmltopdf', // Linux路径
// 'binary' => 'C:\wkhtmltopdf\bin\wkhtmltopdf.exe', // Windows路径
]);
// 3. 初始化时附带全局配置(如默认页面大小A4、边距)
$pdf = new Pdf([
'binary' => '/usr/local/bin/wkhtmltopdf',
'pageSize' => 'A4', // 页面大小(A4/A3/Letter等)
'marginTop' => 10, // 上margin(单位mm,默认0)
'marginRight' => 10, // 右margin
'marginBottom' => 15, // 下margin(留空放页眉)
'marginLeft' => 10, // 左margin
'javascriptEnabled' => true, // 是否执行HTML中的JS(默认true)
]);
3. 设置 PDF 内容(核心功能)
指定要转换为 PDF 的内容(HTML 字符串、远程 URL、本地 HTML 文件),支持单页或多页。
3.1 setHtml(string $html)
作用:直接传入 HTML 字符串作为 PDF 内容(最常用场景,如动态生成的报表、合同)。
参数:$html:完整的 HTML
代码(需包含
<head>
,支持外部 CSS/JS 链接)。
示例
$html = '
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<style>
.title { text-align: center; color: #2c3e50; }
.table { margin: 20px 0; width: 100%; }
</style>
</head>
<body>
<h1 class="title">订单报表</h1>
<table class="table table-bordered">
<tr><th>订单ID</th><th>金额</th><th>状态</th></tr>
<tr><td>1001</td><td>¥99.00</td><td>已支付</td></tr>
<tr><td>1002</td><td>¥199.00</td><td>已发货</td></tr>
</table>
</body>
</html>';
$pdf->setHtml($html); // 将HTML字符串设为PDF内容
3.2 setUrl(string $url)
作用:将远程 URL 或本地 HTML 文件转换为 PDF(如转换在线网页、本地静态 HTML)。
参数:$url:远程 URL(如https://baidu.com)或本地绝对路径(如/var/www/test.html)。
示例:
// 转换远程网页
$pdf->setUrl('https://github.com/mikehaertl/phpwkhtmltopdf');
// 转换本地HTML文件(必须是绝对路径)
$pdf->setUrl('/var/www/project/templates/report.html');
3.3 addPage(mixed $content, array $options = [])
作用:添加多页 PDF 内容(支持为单页单独配置,如不同页面大小、边距)。
参数:
$content:页面内容(HTML 字符串或 URL,同setHtml/setUrl);
$options(可选):当前页面的单独配置(覆盖全局配置,如[‘pageSize’ => ‘Letter’])。
示例:
// 第1页:封面(单独设置页面大小为A3)
$pdf->addPage('<h1 style="text-align:center">PDF封面</h1>', ['pageSize' => 'A3']);
// 第2页:订单内容(使用全局A4配置)
$pdf->addPage($orderHtml);
// 第3页:附录(远程URL内容)
$pdf->addPage('https://example.com/appendix.html', ['marginTop' => 20]);
4. 生成 / 输出 PDF
将配置好的内容生成 PDF,并指定输出方式(保存文件、浏览器下载、返回二进制字符串)。
4.1. save(string $path)
作用:将 PDF 保存到服务器指定路径(最常用的「本地存储」场景)。
参数:$path:保存路径(需确保 PHP 有写入权限,如/var/www/output/order_1001.pdf)。
返回值:bool:成功返回true,失败返回false(需结合错误处理判断)。
示例:
$savePath = '/var/www/pdf/order_1001.pdf';
if ($pdf->save($savePath)) {
echo "PDF已保存:{$savePath}";
} else {
echo "保存失败:" . $pdf->getError();
}
4.2. output(bool $asString = false)
作用:输出 PDF 内容(支持「浏览器下载」或「返回二进制字符串」)。
参数:$asString:false(默认,直接输出到浏览器下载)、true(返回 PDF 二进制字符串,可用于存储到数据库或二次处理)。
示例 1:浏览器下载 PDF:
// 设置HTTP头(告诉浏览器这是PDF文件,触发下载)
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="订单报表_1001.pdf"'); // 下载文件名
header('Content-Length: ' . $pdf->getPdfSize()); // 可选,显示文件大小
// 输出PDF到浏览器
$pdf->output();
示例 2:返回二进制字符串(存入数据库):
// 获取PDF二进制内容
$pdfContent = $pdf->output(true);
// 存入数据库(假设$pdo是PDO实例)
$stmt = $pdo->prepare("INSERT INTO pdf_files (order_id, pdf_content) VALUES (?, ?)");
$stmt->execute([1001, $pdfContent]);
5. 配置优化 (页眉、页脚、图片等)
通过以下方法配置 wkhtmltopdf 的高级功能,解决复杂场景需求(如页眉页脚、图片渲染、页面编号)。
5. 1. setOptions(array $options)
作用:动态设置全局或页面级配置(覆盖构造函数的初始配置,对应 wkhtmltopdf 的所有命令行参数)。
常用选项(对应 wkhtmltopdf 参数,完整选项见wkhtmltopdf 文档)https://wkhtmltopdf.org/usage/wkhtmltopdf.txt
选项 | 说明 | 示例值 |
---|---|---|
pageSize | 页面大小 ‘A4’, | ‘Letter’ |
marginTop | 上 margin(单位 mm) | 10 |
javascriptEnabled | 是否执行 HTML 中的 JS | true/false |
images | 是否加载 HTML 中的图片 | true/false |
dpi | 图片渲染分辨率(解决图片模糊问题) | 300 |
zoom | 页面缩放比例 | 1.2 |
noBackground | 不渲染 HTML 背景色(节省墨水) | true |
5. 2. setHeader(string $html) / setFooter(string $html)
作用:设置 PDF 的页眉 / 页脚(支持 HTML 格式,可包含页码、总页数等占位符)。
占位符(wkhtmltopdf 内置,直接在 HTML 中使用):
{page}:当前页码;
{topage}:总页数;
{date}:当前日期;
{time}:当前时间。
示例:带页码的页眉页脚:
// 页眉(左侧标题,右侧日期)
$headerHtml = '
<div style="font-size:8px; text-align: right; padding-right: 10mm;">
订单报表 | {date}
</div>';
$pdf->setHeader($headerHtml);
// 页脚(居中页码)
$footerHtml = '
<div style="font-size:8px; text-align: center;">
第 {page} 页 / 共 {topage} 页
</div>';
$pdf->setFooter($footerHtml);
// 注意:需预留页眉页脚的margin(否则会被内容覆盖)
$pdf->setOptions([
'marginTop' => 15, // 给页眉留15mm空间
'marginBottom' => 15 // 给页脚留15mm空间
]);
5. 3. setPageOptions(array $options)
作用:为「下一页」设置单独配置(仅对后续调用的addPage生效,不影响之前的页面)。
示例:某一页单独隐藏页眉:
// 第1页:显示页眉
$pdf->addPage($coverHtml);
// 第2页:隐藏页眉(单独配置)
$pdf->setPageOptions(['header-html' => '']); // 清空页眉
$pdf->addPage($contentHtml);
// 第3页:恢复全局页眉
$pdf->setPageOptions(['header-html' => $headerHtml]);
$pdf->addPage($appendixHtml);
6. 错误处理(调试必备)
当 PDF 生成失败时(如 wkhtmltopdf 路径错误、HTML 语法错误),通过以下方法排查问题。
- hasError()
作用:判断 PDF 生成过程是否有错误。
返回值:bool:有错误返回true,无错误返回false。 - getError()
作用:获取具体的错误信息(如 wkhtmltopdf 路径不存在、HTML 中图片路径错误)。
返回值:string:错误描述。
示例:完整的错误处理流程
// 尝试生成PDF
$savePath = '/var/www/pdf/order_1001.pdf';
if ($pdf->save($savePath)) {
echo "PDF生成成功:{$savePath}";
} else {
// 输出错误信息(调试用)
echo "生成失败:" . $pdf->getError();
// 可选:输出完整的wkhtmltopdf命令(便于定位参数问题)
echo "<br>执行的命令:" . $pdf->getCommand();
}
7.注意事项
- wkhtmltopdf 路径问题:务必通过binary参数指定正确路径(避免依赖系统环境变量);
- HTML 路径问题:HTML 中的图片、CSS
- 文件需用绝对路径(如https://xxx.com/img/logo.png或/var/www/img/logo.png),否则无法渲染;
- 权限问题:保存 PDF 的目录需给 PHP 写入权限(如chmod 755 /var/www/pdf);
- JS 渲染问题:若 HTML 依赖 JS 动态生成内容(如 echarts 图表),需确保javascriptEnabled:true,并可通过javascriptDelay: 1000(延迟 1 秒执行 JS)等待渲染完成。