网站开发范例文档,定制规划设计公司,延边app网站开发,网站电话转化率目前市面上常用的前端导出PDF库组合一般为#xff1a;
1. html2canvas js-pdf
2. html2canvaspdf-lib
3. domtoimagepdf-lib
因本人项目中导出pdf需求为导出30页及以上的多页pdf#xff0c;考虑性能问题#xff0c;选择了 html2canvaspdf-lib 及domtoimagepdf-lib两种方…目前市面上常用的前端导出PDF库组合一般为
1. html2canvas js-pdf
2. html2canvaspdf-lib
3. domtoimagepdf-lib
因本人项目中导出pdf需求为导出30页及以上的多页pdf考虑性能问题选择了 html2canvaspdf-lib 及domtoimagepdf-lib两种方式尝试实现
html2canvaspdf-lib个人推荐因为适配ios Safari浏览器 本人是先尝试使用的domtoimagepdf-lib方案但实测中发现H5在ios Safari浏览器端倒不出来故有个html2canvaspdf-lib方案经实战测试该方案能够适配ios Safari浏览器导出
代码如下
首先引入必要插件
yarn add pdf-lib
yarn add html2canvas
yarn add file-saver
file-saver 插件很重要使用a.click方案导出的pdf在Safari中不是直接下载而是打开一个类似预览页的页面查看pdf需用户分享导出比较麻烦。
async downloadPDF() {// 创建一个新的 PDF 文档const pdfDoc await PDFDocument.create();// 处理需转pdf的dom的id数组const pdfDoms await this.handlePDFPageDom();this.allNum pdfDoms.length;for (let i 0; i pdfDoms.length; i) {this.loadText 文件生成中${i 1}/${this.allNum};const doc document.querySelector(# pdfDoms[i]);const canvas await html2canvas(doc, {scale: 2, // 提高清晰度控制内存useCORS: true,});const imgDataUrl canvas.toDataURL(image/jpeg, 0.95); // 压缩图像const imgBytes await fetch(imgDataUrl).then((res) res.arrayBuffer());const img await pdfDoc.embedJpg(imgBytes);// const { width, height } img.scaleToFit(595.28, 841.89);const A4_WIDTH 595.28; // A4 宽度const A4_HEIGHT 841.89; // A4 高度const scale Math.min(A4_WIDTH / img.width, A4_HEIGHT / img.height);const scaledWidth img.width * scale;const scaledHeight img.height * scale;const xOffset (A4_WIDTH - scaledWidth) / 2;const yOffset (A4_HEIGHT - scaledHeight) / 2;const page pdfDoc.addPage([595.28, 841.89]);page.drawImage(img, {x: xOffset,y: yOffset,width: scaledWidth,height: scaledHeight,});canvas.remove();await new Promise((resolve) setTimeout(resolve, 100)); // 防止卡死}const pdfBytes await pdfDoc.save();const blob new Blob([pdfBytes], {type: application/octet-stream,});FileSaver.saveAs(blob, 导出的PDF.pdf);uni.hideLoading();this.loadText 文件生成成功!;},
domtoimagepdf-lib
async downloadPDF() {this.loadText 文件生成中...;// 创建一个新的 PDF 文档const pdfDoc await PDFDocument.create();// 处理需转pdf的dom idconst pdfDoms await this.handlePDFPageDom();let pdfPage [];let base64Arr [];for (let i 0; i pdfDoms.length; i) {const element document.getElementById(pdfDoms[i]);const url await domtoimage.toPng(element, {quality: 0.95,skipFonts: true,});base64Arr.push({ base64: url });}await base64Arr.map((item, index) {pdfDoc.addPage([595.28, 841.89]);pdfPage.push(this.handleReportView(item.base64, index, pdfDoc));});await Promise.all(pdfPage).then(async (res) {// 将 PDF 文档保存为 Uint8Arrayconst pdfBytes await pdfDoc.save();// 生成下载链接并自动下载 PDFconst blob new Blob([pdfBytes], { type: application/pdf });const link document.createElement(a);link.href URL.createObjectURL(blob);link.download ${this.studentName}.pdf;link.click();URL.revokeObjectURL(link.href);uni.hideLoading();this.loadText 文件生成成功!;setTimeout(() {window.parent.postMessage({cmd: success,});}, 1000);}).catch((err) {// PDF null;console.log(生成失败, err);});},async handleReportView(imgBase64, index, pdfDoc) {const A4_WIDTH 595.28; // A4 宽度const A4_HEIGHT 841.89; // A4 高度// 获取所有页面const pages pdfDoc.getPages();// 修改第index页索引从0开始const pageNow pages[index];return await new Promise(async (resolve, reject) {const pageData imgBase64;// setTimeout(() {let img new Image();img.crossOrigin Anonymous;img.onload async () {const imgBytes await fetch(pageData).then((res) res.arrayBuffer());// 嵌入 PNG 图片const pngImage await pdfDoc.embedPng(imgBytes);const { width: imgWidth, height: imgHeight } img;// 计算缩放比例确保图片适应 A4 页面并保持宽高比const scale Math.min(A4_WIDTH / imgWidth, A4_HEIGHT / imgHeight);const scaledWidth imgWidth * scale;const scaledHeight imgHeight * scale;img.width scaledWidth;img.height scaledHeight;// 计算图片的偏移量使其居中显示在页面上const xOffset (A4_WIDTH - scaledWidth) / 2;const yOffset (A4_HEIGHT - scaledHeight) / 2;// 将内容设置到第几页await pageNow.drawImage(pngImage, {x: xOffset,y: yOffset,width: scaledWidth,height: scaledHeight,});resolve();};img.onerror () {alert(资源加载失败);resolve();};img.src pageData;// }, 500);}).catch((err) {return Promise.resolve();});},