背景
最近接到一个客户需求,要求将学生的考试结果分析表格和图表导出到 PDF。表格使用的是普通的 table,图表引用了 https://www.chartjs.org/ 遇到的问题详见 wkhtmltopdf chatjs
思路
在网上查了下前后端都可以将 html 生成 pdf,考虑到实现效果以及效率,最后决定将转化工作在服务端使用 PHP 完成。本着最好不要额外安装软件的原则,搜索过后分别尝试了 TCPDF MPDF FPDF html2pdf 等等。但是实现效果都与预期差距较大。最后不得不尝试需要额外安装的 wkhtmltopdf。
wkhtmltopdf 简介
引用 官网 介绍:wkhtmltopdf 是 wkhtmltox 中的一个工具,另一个是 wkhtmltoimage。它们是开源(LGPLv3)命令行工具,使用 Qt WebKit 渲染引擎将 HTML 呈现为 PDF 和各种图像格式。它们不需要显示或显示服务。值得一提的是谷歌浏览器 chrome 也使用的是 Qt WebKit 渲染引擎。
wkhtmltopdf 安装
安装是在 docker 中进行的,使用开源项目 docker-lnmp。但该 php 使用的是 alpine 版本,遂把镜像改回默认的 debian 版本,后由于客户使用的是 centos,又单独下载了 centos7 的镜像。
debian 安装
# wget https://downloads.wkhtmltopdf.org/0.12/0.12.5/wkhtmltox_0.12.5-1.jessie_amd64.deb
# dpkg -i wkhtmltox_0.12.5-1.jessie_amd64.deb
这里安装会提示缺少依赖信息,其他信息可以直接通过 apt-get install 进行安装,但是这两个需要注意下:
dpkg: dependency problems prevent configuration of wkhtmltox:
wkhtmltox depends on libpng12-0; however:
Package libpng12-0 is not installed.
wkhtmltox depends on libssl1.0.0; however:
Package libssl1.0.0 is not installed.
这两个包直接去仓库中搜索安装即可,然后再次执行安装命令,就会成功安装了
# dpkg -i wkhtmltox_0.12.5-1.jessie_amd64.deb
# wkhtmltopdf -V
# wkhtmltopdf –enable-forms https://www.baidu.com baidu.pdf
centos 安装
# wget https://downloads.wkhtmltopdf.org/0.12/0.12.5/wkhtmltox-0.12.5-1.centos7.x86_64.rpm
# rpm -ivh wkhtmltox-0.12.5-1.centos7.x86_64.rpm
正常系统安装并 update 后会提示缺少依赖信息:
error: Failed dependencies:
fontconfig is needed by wkhtmltox-1:0.12.2.1-1.x86_64
freetype is needed by wkhtmltox-1:0.12.2.1-1.x86_64
libpng is needed by wkhtmltox-1:0.12.2.1-1.x86_64
libjpeg is needed by wkhtmltox-1:0.12.2.1-1.x86_64
libX11 is needed by wkhtmltox-1:0.12.2.1-1.x86_64
libXext is needed by wkhtmltox-1:0.12.2.1-1.x86_64
libXrender is needed by wkhtmltox-1:0.12.2.1-1.x86_64
xorg-x11-fonts-Type1 is needed by wkhtmltox-1:0.12.2.1-1.x86_64
xorg-x11-fonts-75dpi is needed by wkhtmltox-1:0.12.2.1-1.x86_64
这里直接按照提示的安装包就可以了
# yum install fontconfig freetype libpng libjpeg libX11 libXext libXrender xorg-x11-fonts-Type1 xorg-x11-fonts-75dpi
然后再次执行安装命令,就会成功安装了
# rpm -ivh wkhtmltox-0.12.5-1.centos7.x86_64.rpm
# wkhtmltopdf -V
# wkhtmltopdf –enable-forms https://www.baidu.com baidu.pdf
wkhtmltopdf 问题
这里需要注意的是部分系统可能会抛出异常 QXcbConnection: Could not connect to display Aborted (core dumped) 这里需要安装 xvfb 然后使用 xvfb 运行
# xvfb-run wkhtmltopdf –enable-forms https://www.baidu.com baidu.pdf
导出的 pdf 中文会有乱码,可以将 windows 系统 c 盘 system32 目录下的 Fonts 里面的字体拷贝到 linux 的 /usr/share/fonts 下重新运行就可以了
wkhtmltopdf 是跨平台的软件,和后端使用那种语言是没有关系的。PHP 有直接可以用的框架 https://github.com/KnpLabs/snappy 和 laravel 框架 https://github.com/barryvdh/laravel-snappy 当然直接使用 PHP 执行 shell 也及其简单,但要注意防范 webshell。