前端使用vue实现导出pdf

vue实现导出pdf

使用html2canvas和jspdf插件实现

这个方式是通过html2canvasl来把html页面转换成图片,然后再通过jspdf将图片转换为pdf文件

这个方法有个非常不好的缺点
  1. 生成的pdf质量不高,画面有些模糊,失真严重
  2. 如果在分页的地方有图片的话,可能会把图片也给你一分为二了

大概就会是下面这样子,每次分页都会无情的给你隔开,管你是啥玩意
在这里插入图片描述

1. 安装插件

先安装第一个 html2canvas 插件,这个作用是实现将 html 页面转换成 图片

在你的控制住台输入下面指令

npm install --save html2canvas

然后再安装第二个插件, 这个插件的作用是将图片转为 pdf

在你的控制住台输入下面指令

npm install jspdf --save

2. 创建 htmlToPdf.js 文件

安装好了上面的两个插件后,在你的项目里创建一个js文件,项目里应该会有个专门放js文件的文件夹,其实你自己找地方放也可以,只要你能找到就行,把 js 文件的名字和我写的一样就行
然后记住你这个文件的路径 列:(‘src/scripts/common/utils/htmlToPdf’)’

3. 在你创建的 htmlToPdf.js 文件里面写入以下代码

直接全部赋值粘贴过去就好了

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
  install (Vue, options) {
    Vue.prototype.getPdf = function (idStr, title) {
      html2Canvas(document.querySelector('#' + idStr), {
        // allowTaint: true,
        useCORS: true,
        // scale: 2, // 提升画面质量,但是会增加文件大小
      }).then((canvas) => {
        const contentWidth = canvas.width
        const contentHeight = canvas.height
        // 一页pdf显示html页面生成的canvas高度;
        const pageHeight = contentWidth / 592.28 * 841.89
        // 生成pdf的html页面高度
        let leftHeight = contentHeight
        // 页面偏移
        let position = 0
        // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
        const imgWidth = 595.28
        const imgHeight = 592.28 / contentWidth * contentHeight
        // canvas.crossOrigin="anonymous";
        const pageData = canvas.toDataURL('image/jpeg', 1.0)

        const PDF = new JsPDF('', 'pt', 'a4')
        // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
        // 当内容未超过pdf一页显示的范围,无需分页
        if (leftHeight < pageHeight) {
          PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        } else {
          while (leftHeight > 0) {
            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
            leftHeight -= pageHeight
            position -= 841.89
            if (leftHeight > 0) {
              // 避免添加空白页
              PDF.addPage()
            }
          }
        }       
        PDF.save(title + '.pdf')
      })
    }
  },
}
4. 上面不是说到了分页的话会把图片给咔嚓开嘛,然后下面的代码是不分页的,直接复制到 js 文件里就好
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
  install (Vue, options) {
    Vue.prototype.getPdf = function (idStr, title) {
      html2Canvas(document.querySelector('#' + idStr), {
        // allowTaint: true,
        useCORS: true,
        // scale: 2, // 提升画面质量,但是会增加文件大小
      }).then((canvas) => {
        const contentWidth = canvas.width
        const contentHeight = canvas.height
         
         /* 导出不分页处理 */
        const pageData = canvas.toDataURL('image/jpeg', 1.0)

        const pdfWidth = (contentWidth + 10) / 2 * 0.75
        const pdfHeight = (contentHeight + 200) / 2 * 0.75 // 500为底部留白

        const imgWidth = pdfWidth
        const imgHeight = (contentHeight / 2 * 0.75) // 内容图片这里不需要留白的距离

        const PDF = new JsPDF('', 'pt', [ pdfWidth, pdfHeight, ])
        PDF.addImage(pageData, 'jpeg', 0, 0, imgWidth, imgHeight)
        PDF.save(title + '.pdf')
      })
    }
  },
}

5. 在项目文件中的 main.js 里面引入,并注册

把这两行代码复制到min.js里

import htmlToPdf from '@/scripts/common/utils/htmlToPdf'
Vue.use(htmlToPdf)
// 使用Vue.use()方法就会调用工具方法中的install方法
6. 在你要导出的页面中,给你要导出的那个部分 加一个id名字
<div id="pdfDom">
	//给自己需要导出的ui部分.定义id为"pdfDom".此部分将就是pdf显示的部分
</div>
<el-button @click="export">导出PDF</el-button>

在这里插入图片描述

7. 然后 在methods 里面声明点击事件,在return里给他一个导出的名字,这就ok啦
export default {
	data () {
		return {
			fileName: '页面导出PDF文件名'
		}
	}
	methods:{
		export () {
			this.getPdf('pdfDom', this.fileName)
		}
	} 
 }

如果要导出的页面里面的数据有滚动条的话,这种方法是不可行的,需要另选方法,请看以下案例
在这里插入图片描述

这种滚动条里有大量数据,需要滚才能看见,然后导出的pdf是以下格式的,不会显示滚动条
在这里插入图片描述

这个拿到的数据都是当前页面的截图,不会把滚动条里的数据也显示出来,就是当点击导出按钮的时候,让滚动条失效,把所有的数据都显示出来,然后当导出完成后,再让滚动条生效。大家还有更好的方法嘛,欢迎在下方留言

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值