1. 程式人生 > 其它 >生成pdf檔案

生成pdf檔案

 專案需求生成pdf檔案。一開始寫的第一頁與第二頁沒截斷,pdf上看著還好,但是列印資料會丟失,找了好多方法結合後 第一頁與第二頁分割了,但是由於是內容生成的圖片 固定的高,一行內容之間還是會被截斷(如有解決,歡迎留言探討)

貼程式碼:

1、下載外掛:npm install html2Canvas JsPDF -S-D

<!-- html  -->
<!-- 生成PDF檔案資訊 -->
<div ref="targetDom" id="pdfDom"class="pdfDom" >
  // 要生成的內容
</div>
 <el-button class="back-btn" @click="btnPdfClick" v-loading="loadingPdf">   生成PDF檔案  </el-button>     methods: {      btnPdfClick() {          this.$nextTick(() => {          this.uploadPdf();       });   ]  }

2、js檔案

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'

export default {
  install(Vue, options) {
    Vue.prototype.isSplit = function (nodes, index, pageHeight) {
        // 計算當前這塊dom是否跨越了a4大小,以此分割
        if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1
] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) { return true; } return false; }, Vue.prototype.uploadPdf = function () { let ST = document.documentElement.scrollTop || document.body.scrollTop; let SL = document.documentElement.scrollLeft || document.body.scrollLeft; document.documentElement.scrollTop
= 0; document.documentElement.scrollLeft = 0; document.body.scrollTop = 0; document.body.scrollLeft = 0; //獲取滾動條的位置並賦值為0,因為是el-dialog彈框,並且內容較多出現了縱向的滾動條,截圖出來的效果只能擷取到檢視視窗顯示的部分,超出視窗部分則無法生成。所以先將滾動條置頂 const A4_WIDTH = 592.28; const A4_HEIGHT = 841.89; let imageWrapper = document.querySelector('#pdfDom') // 獲取DOM let pageHeight = imageWrapper.scrollWidth / A4_WIDTH * A4_HEIGHT; let lableListID = imageWrapper.querySelectorAll("p"); // 進行分割操作,當dom內容已超出a4的高度,則將該dom前插入一個空dom,把他擠下去,分割 for (let i = 0; i < lableListID.length; i++) { let multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight); if (this.isSplit(lableListID, i, multiple * pageHeight)) { let divParent = lableListID[i].parentNode; // 獲取該div的父節點 let newNode = document.createElement('div'); newNode.className = 'emptyDiv'; newNode.style.background = '#ffffff'; let _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight); //留白 newNode.style.height = _H + 30 + 'px'; newNode.style.width = '100%'; let next = lableListID[i].nextSibling; // 獲取div的下一個兄弟節點 // 判斷兄弟節點是否存在 if (next) { // 存在則將新節點插入到div的下一個兄弟節點之前,即div之後 divParent.insertBefore(newNode, next); } else { // 不存在則直接新增到最後,appendChild預設新增到divParent的最後 divParent.appendChild(newNode); } } } //接下來開始截圖 this.$nextTick(() => { // nexttick可以保證要截圖的部分全部執行完畢,具體用法自行百度... let title = this.exportPDFtitle; html2Canvas(imageWrapper, { allowTaint: true, width: imageWrapper.offsetWidth - 15, // 因為多出的需要剪裁掉, height: imageWrapper.offsetHeight, backgroundColor: "#FFF", //一定要設定北京顏色,否則有的瀏覽器就會變花~,比如Edge useCORS: true, scale: 3, // 圖片模糊 dpi: 350, //z }).then((canvas) => { let pdf = new JsPDF('p', 'mm', 'a4'); //A4紙,縱向 let ctx = canvas.getContext('2d'), a4w = 190, a4h = 270, //A4大小,210mm x 297mm,四邊各保留10mm的邊距,顯示區域190x277 imgHeight = a4h * canvas.width / a4w, //按A4顯示比例換算一頁影象的畫素高度 renderedHeight = 0; while (renderedHeight < canvas.height) { let 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', 0.2), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)); //新增影象到頁面,保留10mm邊距 renderedHeight += imgHeight; if (renderedHeight < canvas.height) pdf.addPage(); //如果後面還有內容,新增一個空頁 } pdf.save(title + ".pdf") }) }) } } }

3、main.js全域性引入

// 生成PDF
import htmlToPdf from '@/utils/htmlToPdf';
Vue.use(htmlToPdf);