相信大家在做專案的時候,一定都做過報表吧
而我在做報表時,普遍都是使用水晶報表來完成(主要語言為C#)
但水晶報表實在是很不好設計,每次都搞得很蛋疼...
於是我開始學會利用網頁畫好報表再輸出成pdf
而我主要使用的lib就是html2pdf.js
由html2pdf.js來將我的html輸出成pdf檔案
可是我最近發現,只要pdf的頁數一多(輸出超過100頁)pdf就會變成空白
後來我在官方的Issues找到了答案
作者是這樣說的:
it's a problem directly in how canvases work. Canvases have a maximum height/width, and once you exceed that the canvas becomes unusable! That's what's happening here.
似乎是指Canvases的高度寬度有個限制,如果超過就會出錯
然後我又在後面的留言發現了作者的解法,如以下
// Assuming "pages" is an array of HTML elements or strings that are separate pages:
var worker = html2pdf().from(pages[0]).toPdf();
pages.slice(1).forEach(function (page) {
worker = worker.get('pdf').then(function (pdf) {
pdf.addPage();
}).from(page).toContainer().toCanvas().toPdf();
});
worker = worker.save();
於是我做了一個Demo來試試作者的寫法
首先我們引用了Vue.js跟html2pdf.js的包
使用Vue是因為等等我們方便渲染
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://raw.githack.com/eKoopmans/html2pdf/master/dist/html2pdf.bundle.js"></script>
好的,接下來編寫我們的HTML代碼
<div id="app">
<button v-on:click="Print()">Print</button>
<template v-for="item of list">
<div :id="'word' + item">
<img src="https://i.imgur.com/ycJpjmg.png" width="800" height="400">
</div>
</template>
</div>
我們的頁面十分簡單,基本就是一個列印的按鈕,負責列印的功能,然後template就是我們要渲染的報表資料,這邊我選了一張dotnet5的圖片作範例
然後開始編寫我們的js
new Vue({
el: '#app',
data: {
list: [],
domList: []
},
mounted: function () {
// 渲染200頁
for (let i = 0; i < 200; i++) {
this.list.push(i);
}
},
methods: {
Print: function () {
// pdf匯出設定
const opt = {
margin: 1,
filename: 'demo.pdf',
image: { type: "jpg", quality: 0.9 },
html2canvas: { dpi: 96, letterRendering: true, useCORS: true },
jsPDF: { unit: 'pt', format: 'letter', orientation: 'portrait' }
};
// 抓取各個圖片的DOM元素,並把它裝入doc這個陣列裡
for (let item in this.list) {
const element1 = document.getElementById('word' + item);
this.domList.push(element1);
}
// 開始進行列印
let doc = html2pdf().from(this.domList[0]).set(opt).toPdf();
for (let j = 1; j < this.domList.length; j++) {
doc = doc.get('pdf').then(
pdf => pdf.addPage()
).from(this.domList[j]).toContainer().toCanvas().toPdf()
}
// 列印完成輸出done
doc.save().then(() => console.dir('done'));
},
}
});
當我們按下Print,就會輸出並下載pdf檔案
打開pdf檔案後就發現神奇的事發生了,一切正常!!
到了200頁也完全沒有問題
解決了原先輸出百頁pdf就會造成空白的問題,真是太猛了!!