网站备案负责人照片,陆丰网页设计,seo优化工程师,无锡全网营销方案前言 在工作中遇到了一个需求#xff0c;就是把前端页面生成PDF并保存在本地#xff0c;因为前端网站可能会展示各种表格#xff0c;图表信息内容并带有比较鲜艳的色彩样式#xff0c;如果让后端生产的PDF的话样式可能和前端页面展示的有所差异#xff0c;所以这个任务就落…前言 在工作中遇到了一个需求就是把前端页面生成PDF并保存在本地因为前端网站可能会展示各种表格图表信息内容并带有比较鲜艳的色彩样式如果让后端生产的PDF的话样式可能和前端页面展示的有所差异所以这个任务就落到了前端的身上。
技术涉及
jsPDF html2canvas ali-oss
代码实现
1、获取DOM结点 首先需要获取需要打印的DOM结点这个时候获取的DOM结点是带有样式的就相当于页面中的内容 const eleHtml document.querySelector(.zxksBody);
2、获取打印容器的属性 首先做个兼容判断判断是否取到了DOM结点信息如果取到了DOM结点就获取DOM结点的内容进行高度和宽度的赋值 if (eleHtml) {let eleW eleHtml.offsetWidth; // 获得该容器的宽let eleH eleHtml.offsetHeight; // 获得该容器的高}3、生成PDF 这一步就是把获取到的DOM结点通过jsPDF和html2canvas 生成为PDF
html2canvas(eleHtml, {dpi: 300,width: eleW,height: eleH,scale: 2, // 提高渲染质量useCORS: true //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。}).then(async (canvas) {const pdf new jsPDF(, pt, a4);const imgData canvas.toDataURL(image/png, 1.0);//a4纸的尺寸[595.28,841.89]html页面生成的canvas在pdf中图片的宽高const imgWidth 555.28;//一页pdf显示html页面生成的canvas高度;const imgHeight 555.28 / canvas.width * canvas.height;// 计算分页const pageHeight 841.89;//未生成pdf的html页面高度let leftHeight imgHeight;//页面偏移let position 0;if (leftHeight pageHeight) {//在pdf.addImage(pageData, JPEG, 左上宽度高度)设置在pdf中显示pdf.addImage(imgData, PNG, 20, 20, imgWidth, imgHeight);} else { // 分页while (leftHeight 0) {pdf.addImage(imgData, PNG, 20, position, imgWidth, imgHeight);leftHeight - pageHeight;position - 841.89;if (leftHeight 0) {pdf.addPage();}}});
4、保存本地或者上传OSS 保存本地 保存本地的话比较简单直接调用PDF库自带的方法就可以保存到本地
pdf.save(${state.xsMc}-${state.xsBh}.pdf)
上传OSS 上传的OSS的话就比较复杂一点首先就是需要配置OSS的内容然后把PDF转换为Blob对象最后就是调用OSS的接口实现上传。
// 配置OSS
const client new OSS({region: ******,bucket: bucketName,endpoint: endpoint,stsToken: securityToken,accessKeyId: accessKeyId,accessKeySecret: accessKeySecret,
});// 将 PDF 文件转换为 Blob 对象
const pdfBlob pdf.output(blob);// 调用OSS上方实现上传
const fileRes await client.put(${state.xsMc}-${state.xsBh}.pdf, pdfBlob);
console.log(fileRes, 接收返回的OSS信息);
5、注意事项 使用html2canvas和jsPDF可能会遇见文本错位或者样式错误问题这个时候需要进行调整可以通过html2canvas中的onclone回调方法进行调整
html2canvas(eleHtml, {onclone: (documentClone) {// 在克隆的文档上进行修改const partRight2 documentClone.querySelector(.partRight2);const titleBars documentClone.querySelectorAll(.titleBar);if (partRight2) {partRight2.style.display none; // 隐藏内容}if (titleBars) {//修改样式属性titleBars.forEach(titleBar {titleBar.style.marginTop -8px;titleBar.style.marginBottom 20px;});}},dpi: 300,width: eleW,height: eleH,scale: 2, // 提高渲染质量useCORS: true //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
}).then(async (canvas) {.......});
对于在获取DOM时带有滚动条的内容无法正确获取他的高度和宽度内容可能会被遮盖无法正确打印这个时候需要在打印前更改页面中的DOM样式才能正确打印
// 获取全部内容
const eleHtml document.querySelector(.zxksBody);// 在生成canvas之前就把样式进行更改获取盒子的正常高度或者宽度防止样式被遮盖
const changeHeight document.querySelector(.zxksContent);if (changeHeight) {changeHeight.style.height 100%; // 更改高度
}html2canvas(eleHtml, {dpi: 300,width: eleW,height: eleH,scale: 2, // 提高渲染质量useCORS: true //允许canvas画布内 }).then(async (canvas) {.....// 在打印完成后再把样式改回去if (changeHeight) {changeHeight.style.height calc(100vh - 182px);}}对于带有滚动条的div盒子在点击打印时最好把页面内容进行更改防止无法正确获取盒子高度导致文字被隐藏在打印完成后在更改回去 // 对于vue 可以使用v-if进行更换把展示的内容保存在div中去掉溢出滚动功能 // 对于react 可以使用三元运算符进行判断展示的内容 6、完整代码
const printPdf async () {const client new OSS({const client new OSS({region: ******,bucket: bucketName,endpoint: endpoint,stsToken: securityToken,accessKeyId: accessKeyId,accessKeySecret: accessKeySecret,}); try {// 获取全部内容const eleHtml document.querySelector(.zxksBody);// 带有移除隐藏的功能const changeHeight document.querySelector(.zxksContent);if (changeHeight) {changeHeight.style.height 100%; // 更改高度}if (eleHtml) {let eleW eleHtml.offsetWidth; // 获得该容器的宽let eleH eleHtml.offsetHeight; // 获得该容器的高// 确保获取加载完全的DOMsetTimeout(() { html2canvas(eleHtml, {onclone: (documentClone) {// 在克隆的文档上进行修改const partRight2 documentClone.querySelector(.partRight2);const titleBars documentClone.querySelectorAll(.titleBar);if (partRight2) {partRight2.style.display none; // 隐藏内容}if (titleBars) {titleBars.forEach(titleBar {titleBar.style.marginTop -8px;titleBar.style.marginBottom 20px;});}},dpi: 300,width: eleW,height: eleH,scale: 2, // 提高渲染质量useCORS: true //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。}).then(async (canvas) {const pdf new jsPDF(, pt, a4);const imgData canvas.toDataURL(image/png, 1.0);const imgWidth 555.28;const imgHeight 555.28 / canvas.width * canvas.height;// 计算分页const pageHeight 841.89;let leftHeight imgHeight;let position 0;if (leftHeight pageHeight) {pdf.addImage(imgData, PNG, 20, 20, imgWidth, imgHeight);} else {while (leftHeight 0) {pdf.addImage(imgData, PNG, 20, position, imgWidth, imgHeight);leftHeight - pageHeight;position - 841.89;if (leftHeight 0) {pdf.addPage();}}}// 将 PDF 文件转换为 Blob 对象const pdfBlob pdf.output(blob);// 使用 OSS 客户端上传 Blob 对象try {const fileRes await client.put(${state.xsMc}-${statexsBh}.pdf, pdfBlob);console.log(client res, fileRes);} catch (err) {console.error(PDF上传失败,请重新提交, err);}if (changeHeight) {changeHeight.style.height calc(100vh - 182px);}});}, 1000);}} catch (error) {console.log(Error, error);if (changeHeight) {changeHeight.style.height calc(100vh - 182px);}}}; 文章转载自: http://www.morning.lzqdl.cn.gov.cn.lzqdl.cn http://www.morning.psyrz.cn.gov.cn.psyrz.cn http://www.morning.lwmxk.cn.gov.cn.lwmxk.cn http://www.morning.rymd.cn.gov.cn.rymd.cn http://www.morning.ktqtf.cn.gov.cn.ktqtf.cn http://www.morning.phtqr.cn.gov.cn.phtqr.cn http://www.morning.ymfzd.cn.gov.cn.ymfzd.cn http://www.morning.rjtmg.cn.gov.cn.rjtmg.cn http://www.morning.rkkpr.cn.gov.cn.rkkpr.cn http://www.morning.hlnys.cn.gov.cn.hlnys.cn http://www.morning.btblm.cn.gov.cn.btblm.cn http://www.morning.mywnk.cn.gov.cn.mywnk.cn http://www.morning.swdnr.cn.gov.cn.swdnr.cn http://www.morning.trhrk.cn.gov.cn.trhrk.cn http://www.morning.rfpb.cn.gov.cn.rfpb.cn http://www.morning.clpkp.cn.gov.cn.clpkp.cn http://www.morning.wdlg.cn.gov.cn.wdlg.cn http://www.morning.jpwkn.cn.gov.cn.jpwkn.cn http://www.morning.myrmm.cn.gov.cn.myrmm.cn http://www.morning.mhnd.cn.gov.cn.mhnd.cn http://www.morning.wkknm.cn.gov.cn.wkknm.cn http://www.morning.gqjzp.cn.gov.cn.gqjzp.cn http://www.morning.rfmzs.cn.gov.cn.rfmzs.cn http://www.morning.syqtt.cn.gov.cn.syqtt.cn http://www.morning.jjtwh.cn.gov.cn.jjtwh.cn http://www.morning.qieistand.com.gov.cn.qieistand.com http://www.morning.hngmg.cn.gov.cn.hngmg.cn http://www.morning.ghwdm.cn.gov.cn.ghwdm.cn http://www.morning.ymmjx.cn.gov.cn.ymmjx.cn http://www.morning.lthgy.cn.gov.cn.lthgy.cn http://www.morning.zkqjz.cn.gov.cn.zkqjz.cn http://www.morning.snbq.cn.gov.cn.snbq.cn http://www.morning.rqxhp.cn.gov.cn.rqxhp.cn http://www.morning.btlmb.cn.gov.cn.btlmb.cn http://www.morning.mprky.cn.gov.cn.mprky.cn http://www.morning.ymjgx.cn.gov.cn.ymjgx.cn http://www.morning.wbxbj.cn.gov.cn.wbxbj.cn http://www.morning.c7622.cn.gov.cn.c7622.cn http://www.morning.ysllp.cn.gov.cn.ysllp.cn http://www.morning.ydxg.cn.gov.cn.ydxg.cn http://www.morning.ryxbz.cn.gov.cn.ryxbz.cn http://www.morning.ityi666.cn.gov.cn.ityi666.cn http://www.morning.zzqgc.cn.gov.cn.zzqgc.cn http://www.morning.lkbyq.cn.gov.cn.lkbyq.cn http://www.morning.kpcky.cn.gov.cn.kpcky.cn http://www.morning.nchsz.cn.gov.cn.nchsz.cn http://www.morning.pxlpt.cn.gov.cn.pxlpt.cn http://www.morning.ychrn.cn.gov.cn.ychrn.cn http://www.morning.llxyf.cn.gov.cn.llxyf.cn http://www.morning.lbzgt.cn.gov.cn.lbzgt.cn http://www.morning.tnktt.cn.gov.cn.tnktt.cn http://www.morning.wqkzf.cn.gov.cn.wqkzf.cn http://www.morning.xsymm.cn.gov.cn.xsymm.cn http://www.morning.htfnz.cn.gov.cn.htfnz.cn http://www.morning.ntzfl.cn.gov.cn.ntzfl.cn http://www.morning.gchqy.cn.gov.cn.gchqy.cn http://www.morning.dpjtn.cn.gov.cn.dpjtn.cn http://www.morning.pbmg.cn.gov.cn.pbmg.cn http://www.morning.wbfg.cn.gov.cn.wbfg.cn http://www.morning.zrbpx.cn.gov.cn.zrbpx.cn http://www.morning.tlfyb.cn.gov.cn.tlfyb.cn http://www.morning.gxklx.cn.gov.cn.gxklx.cn http://www.morning.skcmt.cn.gov.cn.skcmt.cn http://www.morning.yfstt.cn.gov.cn.yfstt.cn http://www.morning.kkzwn.cn.gov.cn.kkzwn.cn http://www.morning.kghss.cn.gov.cn.kghss.cn http://www.morning.jlrym.cn.gov.cn.jlrym.cn http://www.morning.lekbiao.com.gov.cn.lekbiao.com http://www.morning.mxmzl.cn.gov.cn.mxmzl.cn http://www.morning.xjmyq.com.gov.cn.xjmyq.com http://www.morning.dljujia.com.gov.cn.dljujia.com http://www.morning.kpgbz.cn.gov.cn.kpgbz.cn http://www.morning.sfdsn.cn.gov.cn.sfdsn.cn http://www.morning.xwzsq.cn.gov.cn.xwzsq.cn http://www.morning.yjfzk.cn.gov.cn.yjfzk.cn http://www.morning.qwqzk.cn.gov.cn.qwqzk.cn http://www.morning.jfsbs.cn.gov.cn.jfsbs.cn http://www.morning.ykgkh.cn.gov.cn.ykgkh.cn http://www.morning.pbsfq.cn.gov.cn.pbsfq.cn http://www.morning.xzqzd.cn.gov.cn.xzqzd.cn