结论
倾向于通过wkhtmltopdf+消息队列实现。
工作流程:
- 用户保存表单
- 推送生成pdf的任务到队列
- 同时页面显示「正在生成PDF文档,请稍候」并轮询后端接口
- PDF生成后,页面显示下载按钮
后端
dompdf
纯PHP实现。工作原理是把HTML转换成PDF。
优点:
- 不需要PHP调用命令行,安全性高。
缺点:
参考:
mpdf
纯PHP实现。工作原理是把HTML转换成PDF。
优点:
- 不需要PHP调用命令行,安全性高。
缺点(未实测):
- HTML/CSS支持不完整。
- 生成PDF耗时长。
参考:
PDFtk Server
PDFtk Server是个命令行程序。工作原理是利用FDF表单替换PDF模板中的占位符。实现方案有:纯PHP实现FDF + PDFtk、FPDI + PDFtk。
优点:
- 直接替换PDF模板,实现成本低,最大程度保证生成的PDF的效果。
缺点:
- 需要允许PHP调用命令行,有安全隐患。
- 只能实现简单的字符串替换(例如公司名称),不能替换有格式文本。
参考:
wkhtmltopdf
wkhtmltopdf是个命令行程序。工作原理是转换HTML到PDF。实现方案是laravel-snappy。
优点:
- 由于内嵌webkit核心,HTML/CSS的支持没有问题。
缺点:
- 需要允许PHP调用命令行,有安全隐患。
- wkhtmltopdf体积40M,并发较多时影响服务器性能和稳定性(需要考虑用队列辅助实现,异步执行,需要需求变更交互方式)。
参考:
CutyCapt
命令行程序。工作原理和wkhtmtopdf相同。
优缺点同wkhtmltopdf,但是最近的更新在13年。
参考:
Prince
命令行程序。工作原理是转换HTML到PDF。
优点:
- HTML/CSS的支持很好。
- 文档很全
缺点:
- 收费,而且很贵。(免费版会在输出的文档右上角打一个Logo)
- 需要允许PHP执行命令行,有安全隐患。
- 需要考虑用队列辅助实现,异步执行,需要需求变更交互方式。
参考:
前端
jsPDF
工作原理有两种:编程方式动态生成和转换HTML到PDF。有三个插件支持转换HTML到PDF:fromHTML、addHTML和html2pdf。
fromHTML最老,优点是直接转换HTML到PDF,缺点是对复杂的HTML/CSS支持得不好。实测结果,UTF-8编码的中文网页,转换到PDF都是乱码。
addHTML较新,但目前处于deprecated状态,利用html2canvas/rasterizeHTML创建一个canvas,然后把HTML转换成图片、再转换成PDF。实测结果,对中文网页和CSS支持得都不错,但是对分页支持得不好,指定分页选项后图片被拉伸并强行分割,很难看。
html2pdf是正在开发的功能,还没完成。
参考:
pdfkit
只能通过编程(//调用接口指定内容、分页等相关属性//)生成PDF,不支持从HTML转换到PDF。
pdfmake
据说扩展自pdfkit。只能通过编程(//调用接口指定内容、分页等相关属性//)生成PDF,不支持从HTML转换到PDF。而且需要引用字体文件转换成的js文件,不适合中文内容。
变通方案
利用浏览器打印PDF
Chrome、Firefox、Safari的最新版都支持打印网页到PDF,Edge未测试。
优点:
- 实现成本低。
缺点:
- 用户体验差。
导出word文档
优点:
- 实现成本低。(未证实)
缺点:
- 用户可更改文档。