使用html2canvas插件 将vue页面转pdf文件 不分页 并上传后台

391 阅读3分钟
1、需要下载这两个插件
npm i html2canvas --save
npm i jspdf --save

2、使用  //我在div写了很多echarts图表 怕生成的pdf图表截断 所以没有做分页处理
import { getPdf } from "@/widget/pdf.js"; 

 <div class="box_content" id="pdf">
   //内容写在这里面
 </div>
 
 handleExport(name) {
  printOut('pdf',name)
 }

3、创建一个pdf.js文件
import html2Canvas from "html2canvas";//引入
import JsPDF from "jspdf";//引入
import { Loading } from "element-ui"; //导出耗时,用来提示的loading
import axios from "axios";
import { getToken } from "@/server/auth";//需要在下载文件后将文件上传到后台 根据实际情况引入

export const getPdf = (DomName, name) => { //element是元素 newObj是参数
  // 只导出一张pdf,不适合要求是a4,a5..等,滚动有影响,需要设置滚动置顶
    // 能解决图片导出问题
      DomName = document.getElementById(DomName)
      console.log("正在帮您导出......");
        window.pageYoffset = 0; // 滚动置顶
      document.documentElement.scrollTop = 0;
      document.body.scrollTop = 0;
      //title,随意设置,也可以提出来做参数,传入进来,自己发挥
      var title = name; // 导出名字
      var that = this;
      var shareContent = DomName; //需要截图的包裹的(原生的)DOM 对象
      //打印看有没有获取到dom
      console.log(shareContent,'shareContent');
      var width = shareContent.offsetWidth; //获取dom 宽度
      var height = shareContent.offsetHeight; //获取dom 高度
      var canvas = document.createElement("canvas"); //创建一个canvas节点
      var scale = 2; //定义任意放大倍数 支持小数
      canvas.width = width * scale; //定义canvas 宽度 * 缩放,在此我是把canvas放大了2倍
      canvas.height = height * scale; //定义canvas高度 *缩放
      canvas.getContext("2d").scale(scale, scale); //获取context,设置scale
      html2Canvas(DomName, {
        //允许跨域图片的加载
        useCORS: true,
         dpi: window.devicePixelRatio , //将分辨率提高到特定的DPI 提高四倍
        // scale: 2, //按比例增加分辨率
      }).then(function(canvas) {
        var context = canvas.getContext("2d");
        // 【重要】关闭抗锯齿
        context.mozImageSmoothingEnabled = false;
        context.webkitImageSmoothingEnabled = false;
        context.msImageSmoothingEnabled = false;
        context.imageSmoothingEnabled = false;
        var imgData = canvas.toDataURL("image/", 1.0); //转化成base64格式,可上网了解此格式
        var img = new Image();
        img.src = imgData;
        img.onload = function() {
          img.width = img.width / 2; //因为在上面放大了2倍,生成image之后要/2
          img.height = img.height / 2;
          img.style.transform = "scale(0.5)";
          if (this.width > this.height) {
            //此可以根据打印的大小进行自动调节
            var doc = new JsPDF("l", "mm", [
              this.width * 0.555,
              this.height * 0.555
            ]);
          } else {
            var doc = new JsPDF("p", "mm", [
              this.width * 0.555,
              this.height * 0.555
            ]);
          }
          doc.addImage(
            imgData,
            "jpeg",
            10,
            0,
            this.width * 0.505,
            this.height * 0.545
          );
          doc.save(title + ".pdf");
          console.log("倒数3秒导出啦");
        };
      });
      
      //将文件转base64然后上传到后台 如果不需要就可以不用下面这些
      var pdfDataBase64 = pdf.output("datauristring"); //获取base64Pdf
      let file = dataURLtoFile(pdfDataBase64, name);
      saveFile(file,name)
    };
  });
};
//将文件转base64方法 看需求
function dataURLtoFile(dataurl, filename) {
  let arr = dataurl.split(",");
  let mime = arr[0].match(/:(.*?);/)[1];
  let suffix = mime.split("/")[1];
  let bstr = atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], `${filename}.${suffix}`, {
    type: mime
  });
}
//通过调用这个方法上传到后台 看需求
function saveFile(file,newObj){
  let formdata = new FormData();
  for(var key in newObj){
    formdata.append(key, newObj[key]);
  }
  formdata.append("file", file);
   let actionUrl ='/api/add'
    let headers = {
      Authorization: "Bearer " + getToken()
    };
     axios
    .post(actionUrl, formdata, {
      headers: headers //设置header信息
    })
    .then(res => {})
    .catch(error => {});
}
  • 2023-5-10更新 直接下载方法
export const getPdf2 = (element, name, _this) => {
  var width = element.offsetWidth / 1.5;
  var height = element.offsetHeight / 1.5;
  const opts = {
    scrollY: 0,
    scrollX: 0,
    dpi: 900, //解决生产图片模糊
    scale: 2, //清晰度--放大倍数
    useCORS: true // 【重要】开启跨域配置
  };
  html2Canvas(element, opts).then(canvas => {
    var context = canvas.getContext("2d");
    context.mozImageSmoothingEnabled = false;
    context.webkitImageSmoothingEnabled = false;
    context.msImageSmoothingEnabled = false;
    context.imageSmoothingEnabled = false;
    var pageData = canvas.toDataURL("image/jpeg", 1.0);
    var img = new Image();
    img.src = pageData;
    img.onload = () => {
      img.width = img.width / 2;
      img.height = img.height / 2;
      img.style.transform = "scale(1)";
      if (width > height) {
        var pdf = new JsPDF("l", "mm", [width * 0.505, height * 0.505]);
      } else {
        var pdf = new JsPDF("p", "mm", [width * 0.505, height * 0.505]);
      }
      pdf.addImage(pageData, "jpeg", 0, 0, width * 0.505, height * 0.505); //0.545
      const fileName =  `${name}.pdf`
      pdf.save(fileName)
      _this.$loading.hide()
    };
  });
};
  • 使用
import { getPdf2 } from '@/assets/js/pdf' //工具方法,导出操作
 <div class="box_content" ref="pdf"></div>
  handleExport() {
      this.$loading.show({ tip: '正在生成报告请稍候...' })
      setTimeout(() => {
        getPdf2(this.$refs.pdf,'报告名称', this)
        this.comeback()
      }, 1000)
    },