前端实现下载pdf的两种方法

1、使用html2canvas和jspdf插件实现
该方式是通过html2canvas将HTML页面转换成图片,然后再通过jspdf将图片的base64生成为pdf文件。
实现步骤如下:

(1)下载插件模块:

npm install html2canvas jspdf --save             
npm install jspdf --save

(2)定义功能实现方法
在项目工具方法存放文件夹utils中创建htmlToPdf.js文件,
代码如下:

export default{install (Vue, options) {Vue.prototype.getPdf = function () {//      console.log('begin download...')setTimeout(( =>{//console.log('downloading...')var title = this.htmlTitlehtml2canvas($("#pdfDom")[0],{**配置参数**width: 980,height: 980 * 1.4142 * this.page,background: "#fff",scale: 2.1,tainttest: true,logging: false,letterRendering: true,llowTaint: true}).then(function (canvas) {var contentWidth = canvas.widthvar contentHeight = canvas.height// A4纸宽高var A4Width = 595.28var A4Height = 841.89// 一页pdf显示html页面生成的canvas高度var pageHeight = contentWidth / A4Width * A4Height// 未生成pdf的html页面高度var leftHeight = contentHeight// pdf页面偏移var position = 0// pdf页面内边距var pdfPadding = 0// a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高var imgWidth = A4Widthvar imgHeight = A4Width / contentWidth * contentHeightvar pageData = canvas.toDataURL('image/jpeg', 1.0)var pdf = new JsPdf('', 'pt', 'a4')// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)// 当内容未超过pdf一页显示的范围,无需分页if (leftHeight < pageHeight) {pdf.addImage(pageData, 'JPEG', pdfPadding, 0, imgWidth, imgHeight)} else {while (leftHeight > 0) {pdf.addImage(pageData, 'JPEG', pdfPadding, position, imgWidth, imgHeight)leftHeight -= pageHeightposition -= A4HeightleftHeight > 0 && pdf.addPage()}}PDF.save(title + '.pdf')}}},2000)}}
}

(3)全局引入实现方法
在项目主文件main.js中引入定义好的实现方法,并注册。

import htmlToPdf from '@/components/utils/htmlToPdf'
// 使用Vue.use()方法就会调用工具方法中的install方法
Vue.use(htmlToPdf)

(4)在相关要导出的页面中,点击时调用绑定在Vue原型上的getPdf方法,传入id即可

//html<div id="pdfDom">//要下载的HTML页面,页面是由后台返回<div v-html="pageData"></div>
</div>
<el-button type="primary" size="small" @click="getPdf('#pdfDom')">点击下载</el-button>

原理差不多,只不过下边的方法更好些,下载的pdf页面多的情况也可以下载出来,用上边的方法,内容多的情况,下载会出现空白页的情况,下边的方法我认为是好于上边的。下边的方法我是通过iframe来实现的
2、使用dom-to-image和jspdf插件实现
实现步骤如下:

(1)下载插件模块:

npm install dom-to-image --save             
npm install jspdf --save

(2、3、4) 同上
为避免下载的不全或者后台数据还没加载完全,就下载pdf ,所以最好在mounted里 通过eventBus,执行完获取数据的方法之后加一个延时器,确保后台返回的数据都已经渲染完,再执行下载的方法,

 async mounted() {await this.getData();this.$nextTick(() => {setTimeout(() => {this.$Eventbus.$emit("isCanDownload", { isRendered: true });}, 1000);});},

在预览页的mounted里接收一下,判断条件加好,条件成立,再执行下载的方法

 this.$Eventbus.$on("isCanDownload", (val) => {if (val.isRendered && this.isDownload) {this.isDownload = false;this.download();}});window.addEventListener("message",(event) => {if (event.data === "下载") {this.isDownload = true;}},false);

在主页面可以这样来写,代码如下

<div class="custom-pdf" v-if="href"><iframe:src="href"frameborder="0"id="custom-pdf"></iframe></div>

然后在下载的方法同上getpdf里边调用方法

this.$nextTick(() => {document.getElementById("custom-pdf").onload = () => {document.getElementById("custom-pdf").contentWindow.postMessage("下载",location.origin + "/" + router.href);};window.addEventListener("message",(event) => {if (event.data === "完成") {this.isDownloading = false;}},false);});


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部