vue使用html2canvas和jspdf將html轉(zhuǎn)成pdf
A4尺寸
A4紙的尺寸是210mm×297mm。
分辨率是72像素/英寸時(shí),A4紙的尺寸的圖像的像素是595×842(推薦用這個(gè)大小比例)。
分辨率是150像素/英寸時(shí),A4紙的尺寸的圖像的像素是1240×1754。
分辨率是300像素/英寸時(shí),A4紙的尺寸的圖像的像素是2479×3508。
選擇不同的分辨率圖像像素大小也會(huì)隨之變化
安裝插件html2canvas和jspdf
npm install html2canvas--save npm install jspdf --save
html2canvas可以通過(guò)獲取HTML的某個(gè)元素,然后生成Canvas,能讓用戶(hù)保存為圖片。
jsPDF 是一個(gè)基于 HTML5 的客戶(hù)端解決方案,用于生成各種用途的 PDF 文檔。
在項(xiàng)目中引入
在utils 中 新建htmltopdf.js
htmlToPdf.js
// 導(dǎo)出頁(yè)面為PDF格式 import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' export default{ install (Vue, options) { Vue.prototype.getPdf = function () { var pdfTitle = this.pdfTitle //pdf的名稱(chēng) var pdfDom = document.querySelector('#pdfDom') html2Canvas(pdfDom, { allowTaint: true }).then(function (canvas) { console.log(canvas) const marginBottom = 34 // 項(xiàng)目頁(yè)面顯示微處理 以下用到的地方 可以忽略 let canvasWidth = canvas.width //頁(yè)面生成canvas寬度 let canvasHeight = canvas.height + marginBottom //頁(yè)面生成canvas高度 let pageHeight = canvasWidth / 592.28 * 841.89 + marginBottom //分頁(yè) 每頁(yè)的高度 let allPageHeight = canvasHeight // 所有頁(yè)面的高度 let position = 0 //偏移量 let imgWidth = 595.28 //生成canvas 圖片的寬度 let imgHeight = 592.28 / canvasWidth * canvasHeight //生成canvas 圖片的高度 let pageData = canvas.toDataURL('image/jpeg', 3.0) // console.log(canvasWidth) // console.log(canvasHeight) // console.log(pageHeight) // console.log(allPageHeight) // console.log(position) // console.log(imgWidth) // console.log(imgHeight) // console.log(pageData) let PDF = new JsPDF('', 'pt', 'a4') if (allPageHeight < pageHeight) { PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) } else { // 循環(huán)生成分頁(yè) while (allPageHeight > 0) { PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight) allPageHeight = allPageHeight - pageHeight - marginBottom position = position - 841.89 - marginBottom if (allPageHeight > 0) { PDF.addPage() //添加新的一頁(yè) } } } PDF.save(pdfTitle + '.pdf') //保存pdf }) } } }
在main.ts 中 全局引入
main.ts
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import 'babel-polyfill' import Vue from 'vue' import App from './App.vue' import router from './router/index.ts' import store from './store/index.js' import * as ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import htmlToPdf from '@/utils/htmlToPdf.js' // 使用Vue.use()方法就會(huì)調(diào)用工具方法中的install方法 Vue.use(htmlToPdf) // import 'swiper/dist/css/swiper.css' // import * as VueAwesomeSwiper from 'vue-awesome-swiper' // Vue.use(VueAwesomeSwiper) Vue.config.productionTip = false Vue.use(ElementUI) /* eslint-disable no-new */ new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
vue 頁(yè)面
<template> <div class="transcript-container clearfix transcript-detail" @mouseenter.stop="pdfFlag = false"> <div class="creat-pdf clearfix" @click.stop="pdfFlag = true;getPdf('#pdfDom')">下載pdf</div> <div id="pdfDom" class="clearfix" style="width: 210mm;margin: auto;"> </div> </div> </template> <script lang="ts"> import { Vue, Component } from 'vue-property-decorator' import { Getter, Action } from 'vuex-class' @Component export default class cousrseActivity extends Vue { @Getter commonData @Action transcriptDetail $refs: { onePage: HTMLElement, twoPage: HTMLElement } pdfTitle: string = '' } </script> //對(duì)打印 做的 兼容 <style media="print" type="text/css"> @page { size: auto; margin: 0mm; } /* 在chrome下可以使用background屬性 */ body { -webkit-print-color-adjust: exact; } @media print { .transcript-container.transcript-detail .transcript-wrap { margin-bottom: 0; } } </style>
遇到的問(wèn)題
多行省略號(hào)
多行省略號(hào) 在html2canvas 時(shí) 由于不能解析 display: -webkit-box; 會(huì)導(dǎo)致生成的圖片 錯(cuò)誤
.ellipsis{ overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; /* 可以顯示的行數(shù),超出部分用...表示*/ -webkit-box-orient: vertical; }
目前 我這邊正常顯示時(shí) 使用多行省略號(hào) 在打印時(shí) 將 display: -webkit-box;改成display:blcok 就能正常顯示了
圖片模糊 生成的pdf 不清楚
解決辦法: 將canvas的屬性width和height屬性放大為2倍,也就是,先將canvas高分辨率輸出,再來(lái)壓縮導(dǎo)出打印
// 導(dǎo)出頁(yè)面為PDF格式 import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' export default{ install (Vue, options) { Vue.prototype.getPdf = function () { var pdfTitle = this.pdfTitle var pdfDom = document.querySelector('#pdfDom') var c = document.createElement('canvas') html2Canvas(pdfDom, { useCORS: true, scale: 2, canvas: c, logging: true, width: pdfDom.width, height: pdfDom.height // allowTaint: true }).then(function (canvas) { console.log(canvas) const marginBottom = 34 let canvasWidth = canvas.width let canvasHeight = canvas.height + marginBottom * 2 console.log(canvasWidth) console.log(canvasHeight) let pageHeight = canvasWidth / 592.28 * 841.89 + marginBottom * 2 let allPageHeight = canvasHeight let position = 0 let imgWidth = 595.28 let imgHeight = 592.28 / canvasWidth * canvasHeight let pageData = canvas.toDataURL('image/jpeg', 3.0) // console.log(canvasWidth) // console.log(canvasHeight) // console.log(pageHeight) // console.log(allPageHeight) // console.log(position) // console.log(imgWidth) // console.log(imgHeight) // console.log(pageData) let PDF = new JsPDF('', 'pt', 'a4') if (allPageHeight < pageHeight) { PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) } else { while (allPageHeight > 0) { PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight) allPageHeight = allPageHeight - pageHeight - marginBottom position = position - 841.89 - marginBottom if (allPageHeight > 0) { PDF.addPage() } } } PDF.save(pdfTitle + '.pdf') }) } } }
處理過(guò)的圖片 能清晰一點(diǎn) 但是生成的pdf 也大了一倍
圖片跨域 Tained canvases may not be exported
在test 服務(wù)器上 一點(diǎn)問(wèn)題都沒(méi)有 可以正常下載 一大包到線(xiàn)上 就開(kāi)始報(bào)跨域的錯(cuò)誤
百度了一下 基本都是一樣的 復(fù)制來(lái) 復(fù)制去 給的辦法 還是沒(méi)發(fā)處理跨域的問(wèn)題
看了一下html2canvas api 發(fā)現(xiàn)了 一個(gè)屬性 proxy 代理完的圖片 但是還是報(bào)跨域的問(wèn)題 生成的pdf 還是沒(méi)有圖片
最后發(fā)現(xiàn) 頁(yè)面里邊的圖片可以正產(chǎn)顯示 只有外域的圖片不能顯示 本域的圖片用base64顯示的 外域的圖片是不是也能用base64顯示
base64 Data URL scheme 支持的類(lèi)型:
- data:,文本數(shù)據(jù)
- data:text/plain,文本數(shù)據(jù)
- data:text/html,HTML代碼
- data:text/html;base64,base64編碼的HTML代碼
- data:text/css,CSS代碼
- data:text/css;base64,base64編碼的CSS代碼
- data:text/JavaScript,Javascript代碼
- data:text/javascript;base64,base64編碼的Javascript代碼
- data:image/gif;base64,base64編碼的gif圖片數(shù)據(jù)
- data:image/png;base64,base64編碼的png圖片數(shù)據(jù)
- data:image/jpeg;base64,base64編碼的jpeg圖片數(shù)據(jù)
將外域 的圖片弄成base64 后 生成的pdf里邊的圖片 可以正常顯示了 也不報(bào)跨域的問(wèn)題了
總結(jié)
到此這篇關(guān)于vue使用html2canvas和jspdf將html轉(zhuǎn)成pdf的文章就介紹到這了,更多相關(guān)html2canvas jspdf將html轉(zhuǎn)pdf內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決vue js IOS H5focus無(wú)法自動(dòng)彈出鍵盤(pán)的問(wèn)題
今天小編就為大家分享一篇解決vue js IOS H5focus無(wú)法自動(dòng)彈出鍵盤(pán)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08詳解基于 axios 的 Vue 項(xiàng)目 http 請(qǐng)求優(yōu)化
這篇文章主要介紹了詳解基于 axios 的 Vue 項(xiàng)目 http 請(qǐng)求優(yōu)化,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09vue組件實(shí)現(xiàn)可搜索下拉框擴(kuò)展
這篇文章主要為大家詳細(xì)介紹了vue組件實(shí)現(xiàn)可搜索下拉框的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Vue中的數(shù)據(jù)監(jiān)聽(tīng)和數(shù)據(jù)交互案例解析
這篇文章主要介紹了Vue中的數(shù)據(jù)監(jiān)聽(tīng)和數(shù)據(jù)交互案例解析,在文章開(kāi)頭部分先給大家介紹了vue中的數(shù)據(jù)監(jiān)聽(tīng)事件$watch,具體代碼講解,大家可以參考下本文2017-07-07vue中eslint導(dǎo)致的報(bào)錯(cuò)問(wèn)題及解決
這篇文章主要介紹了vue中eslint導(dǎo)致的報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10vue3使用vue-cli引入windicss報(bào)錯(cuò)Can‘t resolve windi.css問(wèn)題
這篇文章主要介紹了vue3使用vue-cli引入windicss報(bào)錯(cuò)Can‘t resolve windi.css問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03