vue如何获取生成的pdf文件?

155 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

使用vue插件生成的pdf,如何获取pdf文件,而不是直接下载

起因:事情是这样的:之前呢都是点击直接下载pdf或者点击去生成pdf(对我这种小菜鸡来说,直接用插件啦);but,这次后端居然让我把文件传过去,一下懵逼的我,满世界求帮助;下面是我的求助历程;

首先呢我用的是vue框架,生成pdf的话就很简单了:先下载这两个依赖

npm install --save html2canvas  //将页面html转换成图片
npm install jspdf --save //将图片生成pdf

然后定义全局函数,创建一个htmlToPdf.js文件,放在('src/components/utils/htmlToPdf.js')

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import jsPDF from 'jspdf'
export default{
  install (Vue, options) {
    Vue.prototype.getPdf = function () {
      var ST = document.documentElement.scrollTop;
      var SL = document.documentElement.scrollLeft;
      document.documentElement.scrollLeft = 0;
      document.documentElement.scrollTop = 0;
      var title = this.htmlTitle
      // console.log(document.querySelector("#pdfDom").parentElement);
      html2Canvas(document.querySelector('#pdfDom'), {
        allowTaint: true,
      }).then(function (canvas) {
        document.documentElement.scrollTop = ST;
        document.documentElement.scrollLeft = SL;
        var pdf = new jsPDF('p', 'mm', 'a4');    //A4纸,纵向
        var ctx = canvas.getContext('2d')
        // console.log('')
        var a4w = 190, a4h = 277    //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
        var imgHeight = Math.floor(a4h * canvas.width / a4w)   //按A4显示比例换算一页图像的像素高度
        var renderedHeight = 0;
          while(renderedHeight < canvas.height) {
            var ctx = canvas.getContext("2d");
            ctx.font = "100px 微软雅黑";
            ctx.fillStyle = "rgba(81, 90, 110, 0.3)";
            // ctx.fillText('这是你的水印', 430, 600);
            // ctx.fillText('这是你的水印', 430, 1400);
            var page = document.createElement("canvas");
            page.width = canvas.width;
            page.height = Math.min(imgHeight, canvas.height - renderedHeight);//可能内容不足一页
            //用getImageData剪裁指定区域,并画到前面创建的canvas对象中
            page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);
            // console.log(page.toDataURL('image/jpeg', 1.0))
            pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width));    //添加图像到页面,保留10mm边距
            renderedHeight += imgHeight;
            if(renderedHeight < canvas.height) {
              pdf.addPage();//如果后面还有内容,添加一个空页
            }
          }
          // 直接下载保存
          pdf.save(title + '.pdf');
          // console.log(pdf)
        }
      )
    }
  }
}

再然后在main.js中使用我们定义的函数文件。

import htmlToPdf from '@/components/utils/htmlToPdf'
Vue.use(htmlToPdf)

最后呢,只要在要生成pdf的页面,直接使用定义好的方法,直接  this.getPdf() 来使用就好了 注意:要打印的id需要和js的要获取的id一致;tiltle要在data定义,否则为空

1.png 2.png 3.png 4.png

到这呢,你就会发现;点击的时候直接下载保存了这个pdf了,和我想要的不一样,我要获取的是这个pdf的文件; 然后我就在js里打印了pdf,发现了其中的有很多方法

// 注释掉直接下载保存
// pdf.save(title + '.pdf');
// 使用pdf的output方法,得到二进制
var output = pdf.output();
// 再将二进制转为u8array
var u8array = pdf.binaryStringToUint8Array(output);
// 最后将u8array再转为Blob,这就是我要的文件啦,传给后端就好啦
var file = new Blob([u8array],{type:'application/pdf'})