相信大家在做专案的时候,一定都做过报表吧
而我在做报表时,普遍都是使用水晶报表来完成(主要语言为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就会造成空白的问题,真是太猛了!!