HTML代碼
<div id="pdfDom" > </div>
<script>
import htmlToPdf from '@/components/utils/htmlToPdf' //頁面打印
export default {
methods: {
gethtmlToPdf(){
var title = 'tttt';//PDF的文件名
htmlToPdf.downloadPdf(title)
},
}
}
</script>
PDF打印插件
src/components/utils/htmlToPdf.js
//該部分代碼是從網上找的,然后根據我自己的需求,調試修改得來。
//本人系后端開發,前端接手不久,所以部分代碼都是百度得來,請見諒。
// 導出頁面為PDF格式 import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' export default{ //有分頁 getPdf(name){ window.pageYoffset = 0; document.documentElement.scrollTop = 0; document.body.scrollTop = 0; let shareContent = document.querySelector('#pdfDom'),//需要截圖的包裹的(原生的)DOM 對象 width = shareContent.clientWidth, //獲取dom 寬度 height = shareContent.clientHeight, //獲取dom 高度 // height = canvas.height, //獲取dom 高度 canvas = document.createElement("canvas"), //創建一個canvas節點 scale = 1.5; //定義任意放大倍數 支持小數 html2Canvas(shareContent, { allowTaint: true, // scale: scale, // 添加的scale 參數 // canvas: canvas, //自定義 canvas logging: false, //日志開關,便於查看html2canvas的內部執行流程 // width: width, //dom 原始寬度 // height: height, useCORS: true, // 【重要】開啟跨域配置 scale : 1.5 }).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 //設置圖片跨域訪問 // img.setAttribute('crossOrigin', 'anonymous'); let pageData = canvas.toDataURL('image/jpeg', 1.0) let PDF = new JsPDF('', 'pt', 'a4') 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(name + '.pdf') } ) }, //test -- 無分頁 downloadPdf(name) { window.pageYoffset = 0; document.documentElement.scrollTop = 0; document.body.scrollTop = 0; let shareContent = document.querySelector('#pdfDom'),//需要截圖的包裹的(原生的)DOM 對象 width = shareContent.clientWidth, //獲取dom 寬度 height = shareContent.clientHeight, //獲取dom 高度 // height = canvas.height, //獲取dom 高度 canvas = document.createElement("canvas"), //創建一個canvas節點 scale = 1.5; //定義任意放大倍數 支持小數 // console.log(tt) setTimeout(() => { html2Canvas(shareContent, { // allowTaint: false,這部分,最好還是不用,原因是,容易污染畫布。 scale: 2.5, // 提升畫面質量,但是會增加文件大小 useCORS: true, // 【重要】開啟跨域配置 backgroundColor: "#fff", // 一定要添加背景顏色,否則出來的圖片,背景全部都是透明的 // foreignObjectRendering: true, }).then(function (canvas) { /**jspdf將html轉為pdf一頁顯示不截斷,整體思路: * 1. 獲取DOM * 2. 將DOM轉換為canvas * 3. 獲取canvas的寬度、高度(稍微大一點) * 4. 將pdf的寬高設置為canvas的寬高 * 5. 將canvas轉為圖片 * 6. 實例化jspdf,將內容圖片放在pdf中(因為內容寬高和pdf寬高一樣,就只需要一頁,也防止內容截斷問題) */ // 得到canvas畫布的單位是px 像素單位 var contentWidth = canvas.width var contentHeight = canvas.height // 將canvas轉為base64圖片 var pageData = canvas.toDataURL('image/jpeg', 1.0) // 設置pdf的尺寸,pdf要使用pt單位 已知 1pt/1px = 0.75 pt = (px/scale)* 0.75 // 2為上面的scale 縮放了2倍 var pdfX = (contentWidth + 10) / 2 * 0.75 var pdfY = (contentHeight + 10) / 2 * 0.75 // 10為底部留白 // 設置內容圖片的尺寸,img是pt單位 var imgX = pdfX; var imgY = (contentHeight / 2 * 0.75); //內容圖片這里不需要留白的距離 // 初始化jspdf 第一個參數方向:默認''時為縱向,第二個參數設置pdf內容圖片使用的長度單位為pt,第三個參數為PDF的大小,單位是pt var PDF = new JsPDF('', 'pt', [pdfX, pdfY]) // 將內容圖片添加到pdf中,因為內容寬高和pdf寬高一樣,就只需要一頁,位置就是 0,0 PDF.addImage(pageData, 'jpeg', 0, 0, imgX, imgY) PDF.save(name+'.pdf') }) }, 200); }, }
以上代碼,雖然可以打印成PDF,但是,如果頁面中有引入外鏈的圖片,入OSS上的圖片,往往會出現跨域的問題。
具體原因見下鏈接 這里 這是一個我覺得寫得相對比較詳細的文章
后來做了各種嘗試,找到了一個解決辦法
修改HTML里的代碼
gethtmlToPdf
<div id="pdfDom" > </div> <script> import htmlToPdf from '@/components/utils/htmlToPdf' //頁面打印 export default { methods: {
gethtmlToPdf(){
var title = this.$route.query.billNumber
let shareContent = document.querySelector('#pdfDom'); //定義任意放大倍數 支持小數
let imgList = shareContent.querySelectorAll('img')
if (imgList){
var i;
for (i = 1; i < imgList.length; i++) {
imgList[i].src += '&timeSign='+Date.now().toString()
console.log(imgList[i].src)
window.URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest();
xhr.open("get", imgList[i].src, true);
xhr.send();
}
}
// console.log(1)
htmlToPdf.downloadPdf(title)
},
} } </script>
如此即可,按我的理解,應該是此部分代碼會重新打開一次圖片,然后會直接刷新緩存中的連接,使其信息得以保全,所以在此訪問不會出現跨域問題。
本人較懶,且前端專業知識不足,如果有大佬能夠更詳細的解釋,請留下鏈接,謝謝!