jspdf & html2canvas 导出pdf(所见即所得)
- 引入html2canvas
import html2canvas from "html2canvas"; - 引入jsPDF
import jsPDF from "jspdf"; - 分不同状况使用,如下:
一、完全不分页
const container = 要导出的div;
// 将html转为canvas
html2canvas(container, {
allowTaint: true,
useCORS: true, // 允许图片跨域,不开启这项的话会导致图片无法下载
scale: 2,
dpi: "192"
}).then(canvas => {
const { width, height } = canvas;
const url = canvas.toDataURL("image/jpeg", 1.0); // 将canvas转为url
const pdfWidth = (width / 2) * 0.75; // 计算pdf的宽度
const pdfHeight = (height / 2) * 0.75; // 计算pdf的高度
const displayWidth = pdfWidth;
const displayHeight = (height / 2) * 0.75;
const pdf = new jsPDF("", "pt", [pdfWidth, pdfHeight]); // 生成pdfWidth宽、pdfHeight高的pdf
pdf.addImage(url, "jpeg", 0, 0, displayWidth, displayHeight); // 将图片写入pdf中
pdf.save(`${自定义文件名}.pdf`);
});
二、超过A4纸高度直接分页(为了打印)
const container = 要导出的div;
html2canvas(container, {
allowTaint: true,
useCORS: true,
scale: 2,
dpi: "192"
}).then(canvas => {
const { width, height } = canvas;
// 一页pdf显示html页面生成的canvas高度;
const pageHeight = (width / 592.28) * 841.89;
// 未生成pdf的html页面高度
let leftHeight = height;
//页面偏移
var position = 0;
// a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
const imgWidth = 595.28;
const imgHeight = (592.28 / width) * height;
const pageData = canvas.toDataURL("image/jpeg", 1.0);
const pdf = new jsPDF("", "pt", "a4");
// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
// 当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
pdf.addImage(pageData, "JPEG", 0, 0, imgWidth, imgHeight);
} else {
// 分页
while (leftHeight > 0) {
pdf.addImage(
pageData,
"JPEG",
0,
position,
imgWidth,
imgHeight
);
leftHeight -= pageHeight;
position -= 841.89;
//避免添加空白页
if (leftHeight > 0) {
pdf.addPage();
}
}
}
pdf.save(`${this.wish.name}.pdf`);
})
三、超过A4纸高度动态分页
const A4_WIDTH = 595.28; // A4纸宽度
const A4_HEIGHT = 841.89; // A4纸高度
// 分割页面函数
// 最小单位的class => minimum-unit
dividePage (dom) {
const pageOffsetTop = dom.offsetTop; // 获取当前dom相对top
const pageOffsetWidth = dom.offsetWidth; // 获取当前dom的宽度
const unitDoms = dom.querySelectorAll('.minimum-unit'); // 获取所有的最小单位的子元素
const perPageHeight = pageOffsetWidth / A4_WIDTH * A4_HEIGHT; // 一页pdf显示html页面生成的canvas高度
const pages = [
[
{ // 起点初始化
top: 0, // 当前元素的底部距离dom最顶点的距离
offsetTop: 0 // 当前元素的顶部距离dom最顶点的距离,用来做分割的位置信息
}
]
]
// 遍历最小单元格
// 获取单元格底部距离顶部的高度 top,以及 offsetTop
// 根据 top 值,算出该单元格的页码,放入数组 pages
unitDoms.forEach(item => {
const offsetTop = item.offsetTop - pageOffsetTop; // 计算距离dom最顶点的距离
const top = offsetTop + item.offsetHeight; // 计算当前元素的底部距离dom最顶点的距离,用来判断元素放在哪一页的依据
const pageIndex = parseInt(top / perPageHeight); // 算出当前元素的页码
// 若还未有此页码,则新开一页
if (!pages[pageIndex]) {
pages[pageIndex] = []
}
// 当前元素放入对应页码中
pages[pageIndex].push({
top,
offsetTop
})
});
return pages;
}
handleDownload () {
const container = 要导出的div;
const scale = 2; // 放大的倍数
html2canvas(container, {
allowTaint: true,
useCORS: true,
scale,
dpi: "192"
})
.then(canvas => {
const { width, height } = canvas;
const imgHeight = (A4_WIDTH / width) * height;
const img = new Image();
img.src = canvas.toDataURL("image/png", 1.0);
img.onload = () => {
const pages = this.dividePage(container, height); // 分页
const pdf = new jsPDF("", "pt", "a4");
pages.forEach((page, index) => {
const { offsetTop } = page[0]; // 获取分割位置
const { top } = page[page.length - 1]; // 获取当前页最末尾的位置
const previewCanvas = document.createElement('canvas'); // 获取备用画布, 分割图片
// 必须设定宽高,不然会有默认宽高,导致显示的内容不对
previewCanvas.width = width; // html2canvas返回的canvas的宽度
previewCanvas.height = height; // html2canvas返回的canvas的高度
const previewCtx = previewCanvas.getContext("2d");
previewCtx.drawImage(img, 0, offsetTop * scale, width, (top - offsetTop) * scale, 0, 0, width, (top - offsetTop) * scale); // 截取指定范围内的图片
previewCtx.putImageData(previewCtx.getImageData(0, 0, width, (top - offsetTop) * scale), 0, 0); // 将图片传至canvas中,以便转化为dataurl
// 给previewCanvas不足的完整高度的部分设置底色
previewCtx.fillStyle = 'rgba(255,255,255,1)';
previewCtx.fillRect(0, (top - offsetTop) * scale, previewCanvas.width, previewCanvas.height - ((top - offsetTop) * scale));
const pageData = previewCanvas.toDataURL("image/jpeg", 1.0);
// 当需要分页的时候,添加分页
if (index > 0) {
pdf.addPage()
}
pdf.addImage(pageData, 'JPEG', 0, 0, A4_WIDTH, imgHeight); // 对应截好的图写入pdf中
})
pdf.save(`${自定义文件名}.pdf`);
}
})
}
版权声明:本文为jarisMA原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。