vue实现HTML转PDF (已解决清晰、页边距、图片跨域导出等问题)
最近有需求做簡歷打印的功能,就又花時間研究了一下html轉圖片導出,里面牽扯到多頁pdf導出時的分頁和頁邊距問題,清晰度問題以及圖片跨域問題等。我們一個一個來解決。
一、先說HTML轉PDF的實現方法
1. 我們要先添加兩個模塊
第一個.將頁面html轉換成圖片 npm install --save html2canvas 第二個.將圖片生成pdf npm install jspdf --save2. 在utils文件夾下面創建一個htmlToPdf.js文件,寫入如下代碼:
// 頁面導出為pdf格式 import html2Canvas from 'html2canvas' import jsPDF from 'jspdf'const htmlToPdf = {getPdf(title,url) {html2Canvas(document.querySelector('#pdfDom'), {allowTaint: false,taintTest: false,logging: false,useCORS: true,dpi: window.devicePixelRatio*4, //將分辨率提高到特定的DPI 提高四倍scale:4 //按比例增加分辨率}).then(canvas=>{var pdf = new jsPDF('p', 'mm', 'a4'); //A4紙,縱向var ctx = canvas.getContext('2d'),a4w = 190, a4h = 277, //A4大小,210mm x 297mm,四邊各保留10mm的邊距,顯示區域190x277imgHeight = Math.floor(a4h * canvas.width / a4w), //按A4顯示比例換算一頁圖像的像素高度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(title + '.pdf')})} };export default htmlToPdf;3. 在我們需要的頁面使用我們定義的函數文件。
import html2canvas from "html2canvas";4. 在執行下載的方法中調用html2canvas中的getPdf方法即可。
html
<div id="pdfDom">// ... 需要打印的內容 </div> <div class="preview-content-operateBtn"><button class="previewBtn" @click="onClickDownLoad">下載PDF簡歷</button> </div>js
onClickDownLoad() {htmlToPdf.getPdf('下載名稱'); },至此,我們的HTML轉PDF的功能也就實現了。
但是在實現的過程中,我們會發現以下問題:
1. 因為實現的方法是先利用canvas轉成圖片,然后轉pdf,所以會存在導出模糊的情況。
2. 導出的pdf頁邊距的問題。
3. 當要打印的區域存在跨域圖片時,方法會報錯。
問題已經找出來,接下來當然就是一個一個解決問題嘍,哈哈。
問題1.?轉pdf,所以會存在導出模糊的情況
解決的原理就是通過放大canvas轉圖片時的大小
dpi: window.devicePixelRatio*4, //將分辨率提高到特定的DPI 提高四倍 scale:4 //按比例增加分辨率問題2.?導出的pdf頁邊距的問題
在圖片轉pdf的時候,提前把pdf的頁邊距留出來,再去計算圖片的放置尺寸。
var pdf = new jsPDF('p', 'mm', 'a4'); //A4紙,縱向 var ctx = canvas.getContext('2d'),a4w = 190, a4h = 277, //A4大小,210mm x 297mm,四邊各保留10mm的邊距,顯示區域190x277imgHeight = Math.floor(a4h * canvas.width / a4w), //按A4顯示比例換算一頁圖像的像素高度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;}問題3. 圖片跨域
在解決圖片跨域的過程中,我試過了網上的方法,說是還需要在跨域的服務器上配置一些參數,比較麻煩,還是前端自己解決吧。
然后嘗試把圖片轉base64(可以搜索圖片轉base64的方法),之后,圖片跨域問題完美解決,很是開心。還是要記得先為跨域的圖片做下代理(圖片地址:http://118.190.75.53/portal_pic/item/3de47b6bf40747d495728cf6441e4a62.jpg)
proxy: {'/portal_pic': {target: "http://118.190.75.53/"}, }, this.getBase64Image(this.baseInfo.basic.interviewHead);// 第一個參數是圖片的URL地址,第二個是轉換成base64地址后要賦值給的img標簽 getBase64Image(url = "") {if (!url) return;let link = url;link = link.split("118.190.75.53");if (link.length > 1) link = link[1];var that = this;var image = new Image();console.log(url, "url");image.src = link + "?v=" + Math.random(); // 處理緩存image.crossOrigin = "*"; // 支持跨域圖片image.onload = function() {var base64 = that.drawBase64Image(image);that.baseInfo.basic.interviewHead = base64;console.log(that.baseInfo, that.baseInfo.basic);}; }, drawBase64Image(img) {var canvas = document.createElement("canvas");canvas.width = img.width;canvas.height = img.height;var ctx = canvas.getContext("2d");ctx.drawImage(img, 0, 0, img.width, img.height);var dataURL = canvas.toDataURL("image/png");return dataURL; },好了,遇到的問題已經解決,功能實現,可以愉快的下載pdf文件了,哈哈!
(在此順便記錄一下實現轉pdf的另一種簡單的方式,window.print(),這種方法是通過調用網頁上面的打印方法,缺點就是有些地方可能會打印不準確。)
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的vue实现HTML转PDF (已解决清晰、页边距、图片跨域导出等问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: json.stringify()与jso
- 下一篇: 小米POCO F5 5G通过FCC认证