把网页导出成 PDF 本质上就是把 html 代码(包括 css 样式)转换成 PDF
用浏览器的 api 生成 | 用各类工具库把 html 生成 PDF | |
---|---|---|
在前端生成 | 1. 直接调用 print 事件 2. 把 html 代码添加进一个隐藏的 iframe 标签里,然后调用 iframe 标签的 print 事件 |
1. 先通过 html2canvas 把网页转换成图片,再用 jsPDF 来生成 PDF 2. 只使用 jsPDF 来生成 PDF |
在后台生成 | 1. 直接用 headless 浏览器的命令行生成 2. 用 Playwright 这类工具操作 headless 浏览器生成 |
用 spipu/html2pdf 这类库解释 html 后生成 PDF |
在后台生成,能保持一致的样式,且不需要浏览器支持,但会占用服务器资源。生成速度大概率会比在前端慢。
在前端生成,各个浏览器生成的 PDF 样式可能会有一点差异,但不占用服务器资源。如果是调用 print 事件方式生成的,速度肯定比在后台生成快。
(function(){
let printCode = `<h1>test</h1>`;
var iframe = document.createElement("iframe");
iframe.id = 'iframe_print_' + Math.round(new Date().getTime());
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.contentWindow.document.write(printCode); // 一定要用 write 方法, innerHTML 属性有时会打印失败
iframe.contentWindow.focus();
iframe.contentWindow.print();
setTimeout(function(){
// 如果还没渲染完pdf就移除 iframe 的标签,会打印失败,等待的时间可以调整,甚至一直留着 iframe 标签都可以
document.getElementById(iframe.id).parentNode.removeChild(iframe);
}, 3000);
})();
Opera 浏览器(77.0.4054.203)有一个把页面另存为 PDF 的功能(不是打印预览),几乎可以把页面的样式完整地保留下来(不是打印的样式就是当前渲染的样式)而且还能保持 a 标签的链接。但只能通过图形界面操作,没有命令行参数,也不能通过 Playwright 这类工具来操作浏览器生成。
可以弄一个单独的 Windows 服务器,用 autoit 这类工具操作 Opera 浏览器把页面另存为 PDF 。
save as pdf 和 pirnt to pdf 是不一样的, 具体区别还不清楚,其中一个区别是 save as pdf 里的文字是可以选中的, save as pdf 可以保留链接
https://community.adobe.com/t5/framemaker-discussions/quot-save-as-pdf-quot-vs-quot-print-quot-as-pdf/m-p/3571101
https://answers.microsoft.com/en-us/msoffice/forum/all/save-as-pdf-vs-print-to-pdf-quality-issues/28c536c6-6fb2-4484-b28b-1e15ce4aac75