注意点: element图标库图标html2canvas生成pdf丢失,建议使用img静态文件
本文代码中涉及页面组件子节点隐藏/展示,所以转pdf前需要展开全部子节点便于获取全部页面元素。
downloadBefore函数主要进行下载前的一些操作(调整滚动条位置/展开子节点等)。
download函数进行转pdf操作,并恢复下载前页面状态
const downloadBefore = () => {
//下载按钮loading
loadingKey.value = true;
// 如果存在滚动条,先滚动到顶部(规避pdf只能截取一部分dom内容),下载完成后回到底部
if (scrollContainer.value) {
scrollContainer.value.scrollTop = 0;
}
if (allexpanded.value) {
// 是否全部展开
proxy?.$nextTick(() => {
download();
});
} else {
// 如未全部展开,则展开全部(暂未考虑已手动全部展开)
setTimeout(() => {
// 异步展开,规避vue批量策略导致loading未及时渲染
allexpanded.value = true;
const copyList = JSON.parse(JSON.stringify(onlineObj.rgs)); // 拷贝下载前数据,便于下载完成后恢复下载前子节点的展开情况
onlineObj.rgs = expandList(onlineObj.rgs || []);
proxy?.$nextTick(() => {
download(() => {
onlineObj.rgs = copyList;
allexpanded.value = false;
});
});
}, 100);
}
};
const download = (cb?: Function) => {
const dom = document.getElementById(`report-root`);
const pdf = new jsPDF(undefined, 'pt', 'a4');
// 插件生成base64img图片。
html2canvas(dom, {
useCORS: true,
// 画布开始渲染的y坐标位置
y: 0,
}).then((canvas) => {
let contentWidth = canvas.width;
let contentHeight = canvas.height;
// 一页pdf显示html页面生成的canvas高度;
let pageHeight = (contentWidth / 700) * 841.89;
// 未生成pdf的html页面高度
let leftHeight = contentHeight;
// 页面偏移
let position = 0;
// a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
let imgWidth = 593;
let imgHeight = (700 / contentWidth) * contentHeight;
let pageData = canvas.toDataURL("image/jpeg", 1.0);
// 有两个高度需要区分,一个是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('report.pdf');
if (cb) {
cb();
}
if (scrollContainer.value) { // 滚轮回到底部
scrollContainer.value.scrollTo({ top: scrollContainer.value.scrollHeight, behavior: 'smooth' });
}
loadingKey.value = false;
});
};