vue生成pdf下载。vue把当前页面生成pdf下载。vue根据页面dom id生成pdf下载。vue pdf导出 电脑版发表于:2020/7/17 19:20 tn2>思路: 通过 html2canvas 将 HTML 页面转换成图片,然后再通过 jspdf 将图片的 base64 生成为 pdf 文件。 [TOC] ### 下载相关依赖 ``` cnpm install html2Canvas; cnpm install jspdf --save ``` 或者 ``` // 将页面 html 转换成图片的库 npm install html2canvas --save // 将图片生成 pdf的库 npm install jspdf --save ``` ### 封装生成pdf的方法并使用 #### 封装成全局方法 创建一个htmlToPdf.js的js文件, 然后在main.js中全局引用一下,编写如下代码: ``` // htmlToPdf.js // 导出页面为PDF格式 import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' export default { install(Vue, options) { Vue.prototype.getPdf = function () { var title = this.htmlTitle //DPF标题 html2Canvas(document.querySelector('#pdfDom'), { allowTaint: true, taintTest: false, useCORS: true, y:72, // 对Y轴进行裁切 // width:1200, // height:5000, dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍 scale: 4 //按比例增加分辨率 }).then(function (canvas) { let contentWidth = canvas.width let contentHeight = canvas.height let pageHeight = contentWidth / 592.28 * 841.89 let leftHeight = contentHeight let position = 0 let imgWidth = 595.28 let imgHeight = 592.28 / contentWidth * contentHeight let pageData = canvas.toDataURL('image/jpeg', 1.0) let PDF = new JsPDF('', 'pt', 'a4') 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(title + '.pdf') }) } } } ``` main.js中引用: ``` // main.js import htmlToPdf from '@/util/htmlToPdf' Vue.use(htmlToPdf) ``` 在vue页面中给需要打印的区域一个div标签,然后给div一个id,id名和htmlToPdf.js中选择的名字一致,代码如下: ``` <div id="pdfDom"> ... 下载成pdf的内容 </div> ``` 在data节点中声明一个htmlTitle变量,指定为pdf文件的文件名。或者通过其他方式传递也行 ``` data() { return { htmlTitle: '下载安装SQL Server 2017' } } ``` 在vue页面中添加一个button按钮,事件名和htmlToPdf.js中的方法名保持一致。 ``` <el-button @click="getPdf()">PDF</el-button> ``` #### 在某个页面定义一个方法直接使用 在需要的页面里边引用需要的依赖 ``` // 导出页面为PDF格式 import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' ``` 直接在页面里边的methods中定义一个下载pdf的方法即可 ``` getPdf (idInp,pdfTitleInp) { // 当下载pdf时,若不在页面顶部会造成PDF样式不对,所以先回到页面顶部再下载 let top = document.getElementById(idInp); if (top != null) { top.scrollIntoView(); top = null; } //let title = this.exportPDFtitle; //pdf名称 let title = pdfTitleInp html2Canvas(document.querySelector('#'+idInp), { allowTaint: true }).then(function (canvas) { // 获取canvas画布的宽高 let contentWidth = canvas.width; let contentHeight = canvas.height; // 一页pdf显示html页面生成的canvas高度; let pageHeight = contentWidth / 841.89 * 592.28; // 未生成pdf的html页面高度 let leftHeight = contentHeight; // 页面偏移 let position = 0; // html页面生成的canvas在pdf中图片的宽高(本例为:横向a4纸[841.89,592.28],纵向需调换尺寸) let imgWidth = 841.89; let imgHeight = 841.89 / contentWidth * contentHeight; let pageData = canvas.toDataURL('image/jpeg', 1.0); let PDF = new JsPDF('l', 'pt', 'a4'); // 两个高度需要区分: 一个是html页面的实际高度,和生成pdf的页面高度 // 当内容未超过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 -= 592.28; // 避免添加空白页 if (leftHeight > 0) { PDF.addPage(); } } } PDF.save(title + '.pdf') }) } } ``` 调用。在需要调用的地方触发即可,两个参数一个是需要下载pdf页面dom节点的id,这两个是pdf的名称 ``` <div class="downLoadOfflinePackage" @click="getPdf('pdfDom',labOpton.title)" style="color:#FF3923">下载离线包</div> ``` 效果如下: ![](https://img.tnblog.net/arcimg/aojiancc2/58728383859a48b7b8158ee682d7c047.png) ### 错误解决:VUE-ElementUI DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 这种情况下一般是图片不能跨域引起的。 比如引入了其他网站的图片,或者自己网站的图片也有可能遇到这种情况 只要是不允许跨域的话。 **如果是引入了其他网站的图片** 换成自己本地的图片或者引入自己的图片在尝试 **如果引用的都是自己网站的图片,那么设置一下让图片跨域即可** 你可能在vue前端需要这样的设置: ``` img.setAttribute("crossOrigin",'Anonymous') ``` 你也可能可以尝试以下在net core后端设置静态文件允许跨域访问(自己根据自己开发的后端去针对性设置) ``` //app.UseStaticFiles(); app.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = (c) => { c.Context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); } }); ```