iT邦幫忙

0

html2pdf.js如何輸出百頁pdf,看這篇就對了

  • 分享至 

  • xImage
  •  

相信大家在做專案的時候,一定都做過報表吧

而我在做報表時,普遍都是使用水晶報表來完成(主要語言為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檔案後就發現神奇的事發生了,一切正常!!

https://ithelp.ithome.com.tw/upload/images/20201003/201312027S4RQBB2jp.png

到了200頁也完全沒有問題

https://ithelp.ithome.com.tw/upload/images/20201003/20131202zAdoQ8gIJ1.png

解決了原先輸出百頁pdf就會造成空白的問題,真是太猛了!!


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言