教你如何使用 PHP 优雅的生成 PDF 和 Image
导读:本人初次写博客,有不足之处,请多多指教 。
起因
因为项目中有需求,要动态的生成一些图片,图片的格式要求也比较严格就像是这样的
表格中的数据如 单价 数量都是动态的数据, 刚开始准备用 GD库
来操作,后来想想不太现实所以去找了找有没有比较成熟的 php
类库。有不少的类库,可以实现直接生成 PDF
而没有可以直接生成 Image
的扩展包。
后来发现了一个 开源的软件 wkhtmltox
该软件支持读取本地和网络端的网页,直接在本地生成 pdf
或 image
。wkhtmltox官方地址
- 该软件有 Window 版本和 Linux 版本(具体支持详情可以查看其官网)
- 下载之后需要将可执行文件的路径添加到环境变量中
具体的使用大概是这样的
$ D:/wktopdf/wkhtmltopdf/bin/wkhtmltoimage --format "jpg" "./1-夏天/夏天.html" "./1-夏天/夏天.jpg"
$ wkhtmltopdf --format "pdf" "./1-夏天/夏天.html" "./1-夏天/夏天.pdf"
支持中文路径和中文文件名, 但是用户可不会这种操作,所以需要一些封装(将执行流程抽象化),有一个哥们已经为我们做了,所以不需要我们去造轮子了。
PHP实现方式一
KnpLabs/snappy
一个基于 wkhtmltox
的 php
扩展包 扩展包GitHup地址
使用方式
$ composer require knplabs/knp-snappy
<?php
require __DIR__ . '/vendor/autoload.php';
use Knp\Snappy\Image;
$snappy = new Image('D:/wktopdf/wkhtmltopdf/bin/wkhtmltoimage'); // 如果你是window环境, 需要将该路径添加到环境变量中
$snappy = new Image(__DIR__ . '/vendor/h4cc/wkhtmltoimage-amd64/bin/wkhtmltoimage-amd64'); // 如果你是linux环境
$str = <<<'EOD'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
@font-face {
font-family: myFirstFont;
src: url('C:/Users/Administrator/Desktop/snopy/Microsoft Yahei.ttf');
}
body {
font-family: myFirstFont;
}
</style>
<body>
</body>
</html>
EOD;
$path = __DIR__ .'/我的/';
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
// 实际生产环境中为了不报错,需要进行异常处理
try {
// 第一个参数是需要转换的 html
// 第二个参数是文件保存路径
$result = $snappy->generateFromHtml($str, $path . '夏天.jpg');
} catch( Exception $e) {
var_dump($e->getMessage());
}
你也可以从 compoer
中安装需要的 wkhtmltox
依赖,
由于
wkhtmltox
是基于QtWebKit rendering engine
, 所以理论上是可以,生成比较复杂的Css
写的够好。同时也支持网络协议,可以从网页中生成Image
。
如果要引入一些外部的css
字体
图片
请使用 绝对路径, 生成的
重点该扩展包会使用 proc_open
函数 去执行生成的 shell
脚本,所以对生产环境的安全有一定的威胁,最后被砍掉了。
安全的实现方式
由于安全原因,自己做的东西被砍了以后,也尝试了别的方式去实现这个功能,但是都不太如意,因为需要生成的
Image
比较复杂,要么是css
支持的不是很好,要么就是字体和图片无法引入的错乱。最后想到了在服务端window
的批处理文件.bat
文件来实现。后来也实现了,可是使用的复杂程度就上去了。
最后在php
的官方文档中发现了这个
查看了一下也是基于 wkhtmltox
的一个 php 的扩展包,于是就动手去实现了一下。
依赖项
wkhtmltox
软件 liunx 版本(目前个人只是编译了linux的扩展,如果有兴趣的可以尝试去编译 window版本的)
具体步骤(linux环境)
- 首先需要到官网去下载软件 软件下载地址
- 扩展需要编译的源码 源码下载地址
- 请注意
wkhtmltox
区分操作系统是32位还是64位的 - 个人服务器环境是centos7, 使用的
wkhtmltox
的版本是0.124
0.124版软件包下载地址
开始编译需要的php扩展
git clone https://github.com/krakjoe/wkhtmltox
cd wkhtmltox
phpize
// 这里因为每个人安装环境不一样 /path/to/wkhtmltox/installation 请将这个地址替为wkhtmltox真实的安装路径
/// PATH 替换为真实的php配置路径
./configure --with-wkhtmltox=/path/to/wkhtmltox/installation --with-php-config = PATH
make
make install
- 修改配置文件 ,将生成的
wkhtmltox.so
添加到php.ini
的配置中,重启php - 安装成功效果
- 然后就可以 开始愉快的使用这个强大的工具了
HELLO PDF
use wkhtmltox\PDF\Converter as PDFConverter;
use wkhtmltox\PDF\Object as PDFObject;
$converter = new PDFConverter([
"out" => "test.pdf"
]);
$converter->add(new PDFObject(
file_get_contents("http://www.baidu.com")));
$converter->convert();
HELLO IMAGE
use wkhtmltox\Image\Converter as ImageConverter;
// 这里第一个参数可以传入 ` html ` 的字符串
$converter = new ImageConverter(null, [
"fmt" => "png",
"in" => "http://www.baidu.com",
"out" => "test.png"
]);
$converter = new ImageConverter($str, [
"fmt" => "jpg",
"out" => "test.jpg"
]);
$converter->convert();
这个安全的实现方式,不会使用到一些会威胁到服务器安全的函数
本作品采用《CC 协议》,转载必须注明作者和本文链接
@Summer 大神你好,可以申精吗
性能如何,刚做完一个需要PDF的需求,用的phpoffice
@66 因为是基于第三方的来源软件,速度很快。
@66 phpoffice 性能太差劲了吧 我之前用的是这个 tcpdf 还凑合吧
@hainuo php官方推荐的这个使用起来,比较简单,是以php扩展形式使用的,性能和安全性上都比较高
phantomjs了解一下
兄弟,错别字~GitHub地址
@bestcyt 很强大兄弟^_^, 已改谢谢提醒。
@CareyWang 前端很好用的截图包,不知道为什么停止更新了。发个教程?
@xihanshui 恩 看了 这个必须要安装第三方软件效率上肯定比 tcpdf要好,看了下还支持 win 抽空试一下
支持老铁
@pigsney 哪一步出错?
@xihanshui 输php-config的时候就报这个错误 然后我就分开来写 好像成功了 然后make的时候就报另一个错误
@pigsney 试试这样,先清除一下失败的编译信息,然后这样
这个里面路径是你的系统中
wkhtmltox
软件的主目录@xihanshui
试试这样,先清除一下失败的编译信息,然后这样
./configure --with-wkhtmltox=/path/to/wkhtmltox/installation
这个里面路径是你的系统中
wkhtmltox
软件的主目录已经安装成功
2个wkhtmltox目录下都没有installation,--with-wkhtmltox 没设置,但是可以编译成功
php -m 显示成功 phpinfo 里却找不到,怎么解决。。。。
@feijin_zzz 有没有将扩展名添加到php.ini 文件中,重启php 试试。
尝试了很多,最后还是决定用 itext7。
!!! --- 语言只是工具,不要被工具限制住了。
我想请教一下,使用php 扩展 wkhtmltox.so 来将html 代码转换成图片,能将方法写在控制器当中,然后通过浏览器访问,来触发wkhtmltox.so 将html 代码转换成图片。
我在我自己的本地服务器上面尝试过,发现通过在服务器上面运行脚本的方式: php convert_html_to_image.php 可以快速生成图片,但是通过 http://www.xxx.com/convert_html_to_image.p... 不能生成图片,并且,尝试通过url 访问的方式去生成图片的时候,apache 的cpu 占用十分高,容易导致服务器宕机。
@joylee109 我使用的也是Apache 没有出现你说的问题 ,可以私聊下
太赞了,正好需要
太赞了,office文档->pdf->svg有什么好的方法吗
wkhtmltoimage 这个生成图片可是二维码图片不显示 是怎么回事呢
@xihanshui 您好,按您的代码,安全的实现方式 pdf可以生成,但是报错说找不到图片,我只编译了php扩展,在官网下载了wkhtmltox_0.12.5-1.bionic_amd64.deb这个,这个是要安装的吗
make安装之后,报这个错误,请问怎么解决
macOS编译出错的fixed: github.com/krakjoe/wkhtmltox/pull/...
jquery导出JSON、XML、PNG、CSV、TXT,SQL,MS-Word,Ms-Excel Ms-Powerpoint、PDF插件www.yujianni.top/news/comp_artinfo...
ImageConverter convert调用之后直接502,少数据测试都报这个,有人遇到吗
我一直在使用bookjs-eazy, 对于高品质PDF 生成效果很好。兼容wkhtmltopdf,支持目录书签页码、页眉页脚、预览。
很可惜我用不了,达梦数据库相关需要用到openssl-1.1.1f,这个需要用到openssl-3,我还是用TCPDF吧。