vue+jspdf+html2canvas导出PDF文件,并将字体放大

    今天开始实现日结单这个功能,日结单是允许打印的,所以我们需要将日结单以PDF的形式导出,我做的是Vue单页应用,于是查找了一番Vue如何导出PDF,看了几篇博客,实现了PDF的导出。主要实现思路是通过html2canvas和jspdf这两个模块,先将页面转换成图片,再将图片放入PDF文件中。
    一、首先添加两个模块:
    
cnpm install html2canvas --save

cnpm install jspdf --save

    二、定义全局函数..创建一个htmlToPdf.js文件在指定位置,比如你可以放在(‘@/components/utils/htmlToPdf‘),该文件内容如下

// 导出页面为PDF格式
import html2canvas from "html2canvas"
import JSPDF from "jspdf"
export default {
  install(Vue, options) {
    Vue.prototype.ExportSavePdf = function(htmlTitle, currentTime) {
      var element = document.getElementById("pdfCentent")
      html2canvas(element, {
        logging: false
      }).then(function(canvas) {
        var pdf = new JSPDF("p", "mm", "a4") // A4纸,纵向
        var ctx = canvas.getContext("2d")
        var a4w = 170;
        var a4h = 257 // A4大小,210mm x 297mm,四边各保留20mm的边距,显示区域170x257
        var imgHeight = Math.floor(a4h * canvas.width / a4w) // 按A4显示比例换算一页图像的像素高度
        var renderedHeight = 0


        while (renderedHeight < canvas.height) {
          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)
          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()
          } // 如果后面还有内容,添加一个空页
          // delete page;
        }
        pdf.save(htmlTitle + currentTime)
      })
    }
  }
}

    三、在main.js文件中引用我们定义的全局函数

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

    四、在组件中使用即可

<template>
  <div>
    <div id="pdfContent">
      <p>需要生成pdf的内容</p>
    </div>


    <el-button type="danger" @click="getPdf(htmlTitle,currentTime)">导出PDF</el-button>
  </div>
</template>


<script>
  export default {
    data() {
      return {
        htmlTitle:‘PDF名称‘,
        currentTime:‘‘
      }
    },
    methods: {


    }
  }
</script>


<style>
</style>

    实际效果如下图所示:

技术分享图片

 
    这样子其实已经差不多了,但是可能是我的笔记本分辨率太高了,我觉得字体有些小,我想到的有两种解决方案:
    ①  设置组件中元素的style,将font-size调大
    ②  将图片的内容进行放大,但不改变图片的高和宽
    毫无疑问肯定选第二种,因为我们是先在网页上进行日结单的预览,然后再点击打印按钮进行打印,如果在页面上把字体调大,预览的时候体验会非常差。
 
    看了一篇博客,对我的帮助很大, https://www.cnblogs.com/jsonYoung/p/9806903.html,虽然这个老哥的htmlToPdf.js文件内容是有问题的,但是他的思路很正确,将canvas的属性width和height属性放大为2倍,最后将canvas的css样式width和height设置为原来1倍的大小即可。
    我修改了一下这位老哥的htmlToPdf.js文件,代码如下:
// 导出页面为PDF格式
import html2Canvas from ‘html2canvas‘
import JsPDF from ‘jspdf‘
export default {
  install(Vue, options) {
    Vue.prototype.getPdf = function(title) {
      var element = document.getElementById("pdfContent")
      var title = title; //PDF文件标题
      var c = document.createElement("canvas");//创建照片
      var opts = {
        scale: 2,
        canvas: c,
        logging: true,
        width: element.clientWidth,
        height: element.clientHeight
      };
      //照片高度和宽度是页面元素的两倍
      c.width = element.clientWidth * 2
      c.height = element.clientHeight * 2
      c.getContext("2d").scale(2, 2);
      html2Canvas(element, opts)
      .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) {
          //第一个20是img和pdf页面的左边距,第二个20是img与pdf页面的上边距
          PDF.addImage(pageData, ‘JPEG‘, 20, 20, imgWidth, imgHeight)
        } else {
          while (leftHeight > 0) {
            PDF.addImage(pageData, ‘JPEG‘, 20, position, imgWidth, imgHeight)
            leftHeight -= pageHeight
            position -= 841.89
            if (leftHeight > 0) {
              PDF.addPage()
            }
          }
        }
        PDF.save(title + ‘.pdf‘)
      })
    }
  }
}

  组件代码如下:

<template>
  <div>
    <div id="pdfContent">
      <p>需要生成pdf的内容</p>
    </div>


    <el-button type="danger" @click="getPdf(title)">导出PDF</el-button>
  </div>
</template>


<script>
  export default {
    data() {
      return {
        title:‘PDF名称‘,
      }
    },
    methods: {


    }
  }
</script>


<style>
</style>

  最终效果如图所示,左边的字体是经过放大的,我个人觉得是满足我的需求了,字体不大不小,之前那个字体就太小了。看着不舒服。

技术分享图片

 

文章来自:https://www.cnblogs.com/N1ckeyQu/p/11382195.html
© 2021 jiaocheng.bubufx.com  联系我们
ICP备案:鲁ICP备09046678号-3