jsPDF 是一个基于用于生成 PDF 文档 JS 库
GitHub: https://github.com/MrRio/jsPDF 官方文档: http://raw.githack.com/MrRio/jsPDF/master/docs/ 用例网上真的挺多的,一搜一大推,代码少,简洁明了,粘过来就能用,真省事。
就是用例好像都是千篇一律的风格,互抄的吗?好吧,港正经话。
网上实例导出的是 A4 大小,用到的是 addImage ,以及需要 html2canvas 库。
其实就是把需要导出的网页,利用 html2canvas 生成图片,在 addImage 至 PDF 中
至于为什么需要先转成图片呢,直接网页转不是很好吗,还能文字复制。因为不支中文,而且,样式还原度也不高。当然,执意于文本复制,网上也有解决方式(搜索关键字:jsPDF 中文)。
不是吗?不分页,啥问题都没。
这个问题就是,为什么要分页?讲真,没有分页需求,也没有打印需求,没必要分页,不是吗?整个页面导成图片就行:
import jsPDF from 'jspdf' import html2canvas from 'html2canvas' function exportPDF (dom, filename) { const scale = 2 // 滚动到顶部,避免打印不全 document.documentElement.scrollTop = 0 html2canvas(this.$refs.pdf, { allowTaint: true, // Whether to allow cross-origin images to taint the canvas scale // The scale to use for rendering. Defaults to the browsers device pixel ratio. }).then((canvas) => { const contentWidth = canvas.width / scale const contentHeight = canvas.height / scale const pdf = new jsPDF('', 'pt', [contentWidth, contentHeight]) const pageData = canvas.toDataURL('image/jpeg', 1.0) pdf.addImage(pageData, 'JPEG', 0, 0, contentWidth, contentHeight) pdf.save(`${filename}.pdf`)
2. 分页
好吧,还是兜到分页这个坑里。
2.1 纯静态页面
这个比较简单,根据 A4 的尺寸比例,预留好间隔,这样,裁剪的时候,便不会出现文本或者其他内容被裁成两半。
- 就是文字、图片、表格,本应该是一个整体的东西好吧,有点眉目了。
页面上的内容,其实,就是一块块的块拼接在一起的,每一块,都是一个不可分割的单元,只要保证切开的地方,不是在单元格里面就行。
示意如下图,要且在单元格(内容)间隙处(绿线),而不是单元格里面(红线)。
是的,代码还真不知道哪里能不能分割,除非你代码,简洁到没有嵌套,一个标签就是一个整体。
那,人肉标记呗。
人工标记最小单元格,给这个标签加上一个 class ,然后 js 获取这些元素,判断这些元素距离顶部的高度,以及自身的高度,来判断这个元素在那哪一页。
const A4_WIDTH = 595.28 const A4_HEIGHT = 841.89 function splitPage ($dom) { const pageOffsetTop = $dom.offsetTop const pageOffsetWidth = $dom.offsetWidth const pageOffsetHeight = $dom.offsetHeight const $unitElements = $dom.querySelectorAll('.minimum-unit') const peerPageHeight = pageOffsetWidth / A4_WIDTH * A4_HEIGHT // 获取缩放后的一页页面高度 const pages = [ top: 0, // 起点初始化 offsetTop: 0 // 遍历最小单元格 // 获取单元格底部距离顶部的高度 top,以及 offsetTop // 根据 top 值,算出该单元格的页码,放入数组 pages $unitElements.forEach($element => { const offsetTop = $element.offsetTop - pageOffsetTop const top = offsetTop + $element.offsetHeight const pageIndex = parseInt(top / peerPageHeight) // 新的一页 if (typeof pages[pageIndex] === 'undefined') { pages[pageIndex] = [] pages[pageIndex].push({ offsetTop console.log(pages) return pages
导出就是(导出代码有问题,缩放比列和 pt 有问题,待解决,仅供思路参考):
function exportPDF ($dom, filename) { // 滚动到页面顶部,避免导出不全 document.documentElement.scrollTop = 0 html2canvas($dom, { allowTaint: true, scale: 2 }).then((canvas) => { const pdf = new jsPDF('', 'pt', 'a4') const contentWidth = canvas.width const contentHeight = canvas.height const pageData = canvas.toDataURL('image/jpeg', 1.0) const pageHeight = contentWidth / A4_WIDTH * A4_HEIGHT // 内容缩放后的高度 const pages = splitPage() pages.forEach((page, index) => { const {offsetTop} = page[0] const {top} = page[page.length - 1] if (index > 0) { pdf.addPage() pdf.addImage(pageData, 'JPEG', 0, -1 * offsetTop, A4_WIDTH, top) pdf.save(`${filename}.pdf`)
分割的代码待解决,先小计一下