纯前端实现html导出PDF并自动分页
在做html导出PDF需求时,遇到分页文字、图片、表格等被中间切断,对PDF文件的预览体验不是很好。从网上找了一些方案都不是十分的如意,难以兼容多种场景,于是呼,结合多种方案,自己开发了一个工具,专门用于分页处理,使用简单,兼容各种尺寸的页面。
基础场景
实现原理
插件@wk-tools/html-to-pdf利用html2canvas 将Element元素生成一个Canvas,再根据PDF的高度进行分页计算,根据每一页的分页节点(Y坐标)截取部分内容,通过创建一个虚拟canvas,连同页眉页脚,绘制整个PDF单页,通过 jspdf将多个单页合并成一个完整的PDF文件。
计算分页节点,会遇到文字、图片、表格、canvas等被切断,本插件会按照一定规则优化切断处Y坐标,避免内容被切断。
- 段落文案内容分页 - 通过段落的高度和行高比对,精确找出被合理分段的Y坐标,在该坐标位置进行分页。
- 图片、canvas、表格、自定义整体内容等分页 - 图片和canvas是一个整体;表格单行内容复杂,多个td内容无法精准对齐,故将表格的整行tr看作一个整体;图文组合、定位等脱离文档流的布局,都需看作一个整体。对整体内容分页,规则比较简单,当页无法容纳整体内容,则顺移到下一页。特殊情况,若整体内容超过PDF的单页高度,则默认不处理,即内容会被正常切断(若是有大量该场景,后期考虑予以支持)。
- 插件机制,使工具具有更强的扩展性,目前工具内置了页眉页脚插件,提供封面/底插件,后续会增加水印、目录等插件。
安装
# 使用npm
npm i -S @wk-tools/html-to-pdf
# 使用yarn
yarn add @wk-tools/html-to-pdf
用法
// ...
import HtmlToPdf from "@wk-tools/html-to-pdf";
function exportPDF() {
Loading.show();
const element = document.getElementById("pdf-container");
const htmlToPdf = new HtmlToPdf(element, {
name: "葵花宝典",
});
htmlToPdf
.save()
.catch(() => {
Message.error("下载失败");
})
.finally(() => {
Loading.hide();
});
}