加载中...

vue页面导出pdf文档并上传pdf格式给后台

  1. 下载依赖
    yarn add html2canvas // 将页面html转换成图片
    yarn add jspdf // 将图片生成pdf
  2. 定义全局函数,创建htmlToPdf.js文件
    1. import html2Canvas from ''html2canvas''
    2. import JsPDF from ''jspdf''
    3. export default {
    4.     install(Vue, options) {
    5.         Vue.prototype.getPdf = function (pdfFileName, isDownload, hide) {
    6.             return new Promise((resolve, reject) => {
    7.                 // this.$message.loading(''正在下载'', 2.5)
    8.                 let ele = document.getElementById(''pdfDom'')
    9.                 pdfFileName = pdfFileName || ''pdf''
    10.                 window.pageYoffset = 0 // 滚动置顶
    11.                 document.documentElement.scrollTop = 0
    12.                 document.body.scrollTop = 0
    13.                 html2Canvas(ele, {
    14.                     allowTaint: true,
    15.                     windowWidth: document.body.scrollWidth,
    16.                     windowHeight: document.body.scrollHeight
    17.                 }).then(canvas => {
    18.                     // const _this = this
    19.                     // 未生成pdf的html页面高度
    20.                     var leftHeight = canvas.height
    21.                     var a4Width = 555.28 // 原A4592 因为要设置边距 20 ,这里要减掉 40
    22.                     var a4Height = 801.89 // 原A4高   841 因为要设置边距 20 ,这里要减掉 40
    23.                     // 一页pdf显示html页面生成的canvas高度;
    24.                     var a4HeightRef = Math.floor(canvas.width / a4Width * a4Height)
    25.                     // pdf页面偏移
    26.                     var position = 0
    27.                     var pageData = canvas.toDataURL(''image/jpeg'', 1.0)
    28.                     var pdf = new JsPDF(''x'', ''pt'', ''a4'')
    29.                     // let printIndex = 1
    30.                     const canvas1 = document.createElement(''canvas'')
    31.                     let height
    32.                     pdf.setDisplayMode(''fullwidth'', ''continuous'', ''FullScreen'')
    33.                     function createImpl(canvas) {
    34.                         if (leftHeight > 0) {
    35.                             // printIndex++
    36.                             var checkCount = 0
    37.                             if (leftHeight > a4HeightRef) {
    38.                                 var i = position + a4HeightRef
    39.                                 for (i = position + a4HeightRef; i >= position; i--) {
    40.                                     var isWrite = true
    41.                                     for (var j = 0; j < canvas.width; j++) {
    42.                                         var c = canvas.getContext(''2d'').getImageData(j, i, 1, 1).data
    43.                                         if (c[0] !== 0xff || c[1] !== 0xff || c[2] !== 0xff) {
    44.                                             isWrite = false
    45.                                             break
    46.                                         }
    47.                                     }
    48.                                     if (isWrite) {
    49.                                         checkCount++
    50.                                         if (checkCount >= 10) {
    51.                                             break
    52.                                         }
    53.                                     } else {
    54.                                         checkCount = 0
    55.                                     }
    56.                                 }
    57.                                 height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef)
    58.                                 if (height <= 0) {
    59.                                     height = a4HeightRef
    60.                                 }
    61.                             } else {
    62.                                 height = leftHeight
    63.                             }
    64.                             canvas1.width = canvas.width
    65.                             canvas1.height = height
    66.                             // console.log(index, ''height:'', height, ''pos'', position);
    67.                             var ctx = canvas1.getContext(''2d'')
    68.                             ctx.drawImage(canvas, 0, position, canvas.width, height, 0, 0, canvas.width, height) // 边距这里设置0,不然又黑边
    69.                             // var pageHeight = Math.round(a4Width / canvas.width * height)
    70.                             // pdf.setPageSize(null, pageHeight)
    71.                             if (position !== 0) {
    72.                                 pdf.addPage()
    73.                             }
    74.                             // 设置 20px 边距
    75.                             pdf.addImage(canvas1.toDataURL(''image/jpeg'', 1.0), ''JPEG'', 20, 20, a4Width, a4Width / canvas1.width * height)
    76.                             leftHeight -= height
    77.                             position += height
    78.                             if (leftHeight > 0) {
    79.                                 // 添加全屏水印
    80.                                 /* 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=''
    81.                                 for (let i=0;i<6;i++) {
    82.                                   for (let j=0;j<5;j++) {
    83.                                     const  left = (j * 120) + 20
    84.                                     pdf.addImage(base64,''JPEG'', left, i*150, 20, 30); // 关掉水印
    85.                                   }
    86.                                 } */
    87.                                 setTimeout(createImpl, 0, canvas)
    88.                             } else {
    89.                                 pdf.save(pdfFileName + ''.pdf'')
    90.                                 setTimeout(hide, 0)
    91.                                 if (isDownload) {
    92.                                     var pdfData = pdf.output(''datauristring'')//获取base64Pdf
    93.                                     resolve(pdfData)
    94.                                 }
    95.                                 // this.$message.success(''下载完成'', 2.5)
    96.                             }
    97.                         }
    98.                     }
    99.                     // 当内容未超过pdf一页显示的范围,无需分页
    100.                     if (leftHeight < a4HeightRef) {
    101.                         pdf.addImage(pageData, ''JPEG'', 20, 20, a4Width, a4Width / canvas.width * leftHeight)
    102.                         pdf.save(pdfFileName + ''.pdf'')
    103.                         if (isDownload) {
    104.                             var pdfData = pdf.output(''datauristring'')//获取base64Pdf
    105.                             resolve(pdfData)
    106.                         }
    107.                     } else {
    108.                         try {
    109.                             pdf.deletePage(0)
    110.                             setTimeout(createImpl, 0, canvas)
    111.                         } catch (err) {
    112.                             console.log(err)
    113.                         }
    114.                     }
    115.                 })
    116.             })
    117.         }
    118.     }
    119. }

  3. 在main.js中使用
     
    1. import htmlToPdf from ''@/components/htmlToPdf/htmlToPdf''
    2. Vue.use(htmlToPdf)

    1. <template>
    2.   <div class="row" id="pdfDom" style="padding-top: 55px;background-color:#fff;">
    3.     //pdf想要展示的内容
    4.   </div>

    1. <div class="flex itemcenten jucem">
    2.       <el-button
    3.         @click="htmlToPdf"
    4.         type="primary"
    5.         >下载报告</el-button
    6.       >
    7.     </div>
    8. </template>
    9. <script>
    10. export default {
    11.   data () {
    12.     return {}
    13.   },
    14.   method: {
    15.    
    16. //上传pdf接口
    17.     UploadPdf(res) {
    18.       //res拿到base64的pdf
    19.       let pdfBase64Str = res;
    20.       let title = "上传给后端的个人报告";
    21.       var myfile = this.dataURLtoFile(pdfBase64Str, title + ".pdf"); //调用一下下面的转文件流函数
    22.       var formdata = new FormData();
    23.       formdata.append("file", myfile); // 文件对象
    24.       console.log(formdata);
    25.       uploadAsync(formdata, this.isLookItem.record.id)
    26.         .then((res) => {
    27.           console.log("上传pdf接口", res);
    28.         })
    29.         .catch((err) => {
    30.           console.log("上传pdf接口", err);
    31.         });
    32.     },
    33.     dataURLtoFile(dataurl, filename) {
    34.       var arr = dataurl.split(","),
    35.         mime = arr[0].match(/:(.*?);/)[1],
    36.         bstr = atob(arr[1]),
    37.         n = bstr.length,
    38.         u8arr = new Uint8Array(n);
    39.       while (n--) {
    40.         u8arr[n] = bstr.charCodeAt(n);
    41.       }
    42.       return new File([u8arr], filename, { type: mime });
    43.     },
    44.     toGetPdf(val, download) {
    45.       this.$nextTick(() => {
    46.         setTimeout(() => {
    47.           window.scrollTo(0, 0);
    48.           let title = "个人报告";
    49.           this.getPdf(title, download).then((res) => {
    50.             if (val) {
    51.               this.UploadPdf(res);
    52.             } else {
    53.               console.log("不上传");
    54.             }
    55.           });
    56.         }, 1000);
    57.       });
    58.     },
    59.     htmlToPdf() {
    60.       if (
    61.         this.isLookItem.record.download_url == null ||
    62.         this.isLookItem.record.download_url == ""
    63.       ) {
    64.         this.toGetPdf(true, true);
    65.       } else {
    66.         this.toGetPdf(false, false);
    67.       }
    68.       const loading = this.$loading({
    69.         lock: true,
    70.         text: "下载中,请稍后",
    71.         spinner: "el-icon-loading",
    72.         background: "rgba(0, 0, 0, 0.7)",
    73.       });
    74.       setTimeout(() => {
    75.         loading.close();
    76.       }, 7000);
    77.     },
    78.   }
    79. }
    80. </script>