- 下载依赖
yarn add html2canvas // 将页面html转换成图片
yarn add jspdf // 将图片生成pdf - 定义全局函数,创建htmlToPdf.js文件
-
import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' export default { install(Vue, options) { Vue.prototype.getPdf = function (pdfFileName, isDownload, hide) { return new Promise((resolve, reject) => { // this.$message.loading('正在下载', 2.5) let ele = document.getElementById('pdfDom') pdfFileName = pdfFileName || 'pdf' window.pageYoffset = 0 // 滚动置顶 document.documentElement.scrollTop = 0 document.body.scrollTop = 0 html2Canvas(ele, { allowTaint: true, windowWidth: document.body.scrollWidth, windowHeight: document.body.scrollHeight }).then(canvas => { // const _this = this // 未生成pdf的html页面高度 var leftHeight = canvas.height var a4Width = 555.28 // 原A4宽 592 因为要设置边距 20 ,这里要减掉 40 var a4Height = 801.89 // 原A4高 841 因为要设置边距 20 ,这里要减掉 40 // 一页pdf显示html页面生成的canvas高度; var a4HeightRef = Math.floor(canvas.width / a4Width * a4Height) // pdf页面偏移 var position = 0 var pageData = canvas.toDataURL('image/jpeg', 1.0) var pdf = new JsPDF('x', 'pt', 'a4') // let printIndex = 1 const canvas1 = document.createElement('canvas') let height pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen') function createImpl(canvas) { if (leftHeight > 0) { // printIndex++ var checkCount = 0 if (leftHeight > a4HeightRef) { var i = position + a4HeightRef for (i = position + a4HeightRef; i >= position; i--) { var isWrite = true for (var j = 0; j < canvas.width; j++) { var c = canvas.getContext('2d').getImageData(j, i, 1, 1).data if (c[0] !== 0xff || c[1] !== 0xff || c[2] !== 0xff) { isWrite = false break } } if (isWrite) { checkCount++ if (checkCount >= 10) { break } } else { checkCount = 0 } } height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef) if (height <= 0) { height = a4HeightRef } } else { height = leftHeight } canvas1.width = canvas.width canvas1.height = height // console.log(index, 'height:', height, 'pos', position); var ctx = canvas1.getContext('2d') ctx.drawImage(canvas, 0, position, canvas.width, height, 0, 0, canvas.width, height) // 边距这里设置0,不然又黑边 // var pageHeight = Math.round(a4Width / canvas.width * height) // pdf.setPageSize(null, pageHeight) if (position !== 0) { pdf.addPage() } // 设置 20px 边距 pdf.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 20, 20, a4Width, a4Width / canvas1.width * height) leftHeight -= height position += height if (leftHeight > 0) { // 添加全屏水印 /* const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAArCAYAAADIWo5HAAACLUlEQVR42u2Zy2sCMRDGV9tbtVJKrQ/0JBWLvbgsaOttQQqreO5R6GHP/v+HZiEDQ9i8k33YDHyXbcxufpN8maRRFCJEiBAhQoTgRIfoh+hKNBe0G9I2GVG3om9bEl2I9rcIoE/77Cq8Myd6sn2ZSBgAr80YARhI+gOwCdGW6EB/d6R9XDUGFrsAf2Fe7Fswk1JBmzMd1DNKgI2EywQyUKYjkxFeOwwxkwgAvBJNqEa0DzaTHcn3qWrXdA/ocQD8m11ABUDfQF0fpujjI2QAeoZetdYdfOzB9HgGNEF6owM8Ec3Q8wEDgP07T6ktgNyB8YgAqGZ0b+gRsS2AtQP/iAUAHlAdsEW7TY6eFVrVNQN8A2AjlZho5R5wYjJhoqMiADy4DFWLPJMcKBhv3AYThFi4yJyrAAAfDrY/1SVQVhLDOWDowIwzSQ1TqwfA1P5CU3yJlsPY8fmjcTMgptmeIwB3aFbsLCvM2BRAFR4AZXYxuEdmn38hmjoosY0B5IonxLNhIYTNby0odMoAJJL1/k10bwpgQztZKaxb2YXFRnAUhexDHzoAUsGxu3j+awNA5+RmcxW1UCx1eQB4SyI1AaBrbiMEYGrwexgYBlgrgGtU/ZUY3AlGhgByTvV5MQGgW1SomqBOUWLiATy1wgNsABQz51PzWHxTALzWAW0F0EM+MKPmnLj6x0lbAPDuC5zfNPsCcChZ25DZd4VBJCW7wrRp1+whQoQIESJEg+IPRa38G55TPkQAAAAASUVORK5CYII=' for (let i=0;i<6;i++) { for (let j=0;j<5;j++) { const left = (j * 120) + 20 pdf.addImage(base64,'JPEG', left, i*150, 20, 30); // 关掉水印 } } */ setTimeout(createImpl, 0, canvas) } else { pdf.save(pdfFileName + '.pdf') setTimeout(hide, 0) if (isDownload) { var pdfData = pdf.output('datauristring')//获取base64Pdf resolve(pdfData) } // this.$message.success('下载完成', 2.5) } } } // 当内容未超过pdf一页显示的范围,无需分页 if (leftHeight < a4HeightRef) { pdf.addImage(pageData, 'JPEG', 20, 20, a4Width, a4Width / canvas.width * leftHeight) pdf.save(pdfFileName + '.pdf') if (isDownload) { var pdfData = pdf.output('datauristring')//获取base64Pdf resolve(pdfData) } } else { try { pdf.deletePage(0) setTimeout(createImpl, 0, canvas) } catch (err) { console.log(err) } } }) }) } } }
- 在main.js中使用
import htmlToPdf from '@/components/htmlToPdf/htmlToPdf' Vue.use(htmlToPdf)
-
<template> <div class="row" id="pdfDom" style="padding-top: 55px;background-color:#fff;"> //pdf想要展示的内容 </div>
-
<div class="flex itemcenten jucem"> <el-button @click="htmlToPdf" type="primary" >下载报告</el-button > </div> </template> <script> export default { data () { return {} }, method: { //上传pdf接口 UploadPdf(res) { //res拿到base64的pdf let pdfBase64Str = res; let title = "上传给后端的个人报告"; var myfile = this.dataURLtoFile(pdfBase64Str, title + ".pdf"); //调用一下下面的转文件流函数 var formdata = new FormData(); formdata.append("file", myfile); // 文件对象 console.log(formdata); uploadAsync(formdata, this.isLookItem.record.id) .then((res) => { console.log("上传pdf接口", res); }) .catch((err) => { console.log("上传pdf接口", err); }); }, dataURLtoFile(dataurl, filename) { var arr = dataurl.split(","), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, { type: mime }); }, toGetPdf(val, download) { this.$nextTick(() => { setTimeout(() => { window.scrollTo(0, 0); let title = "个人报告"; this.getPdf(title, download).then((res) => { if (val) { this.UploadPdf(res); } else { console.log("不上传"); } }); }, 1000); }); }, htmlToPdf() { if ( this.isLookItem.record.download_url == null || this.isLookItem.record.download_url == "" ) { this.toGetPdf(true, true); } else { this.toGetPdf(false, false); } const loading = this.$loading({ lock: true, text: "下载中,请稍后", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }); setTimeout(() => { loading.close(); }, 7000); }, } } </script>
vue页面导出pdf文档并上传pdf格式给后台
于 2022-05-17 10:40:25 首次发布
关键词由CSDN通过智能技术生成