Front end page export PDF

Posted by nolos on Tue, 17 Dec 2019 18:02:46 +0100

This is an encapsulated vue component, which simply sets the export header, content, and bottom The content can be paged. It can export all pages of the list

The implementation is based on html2canvas to convert the page to image, and then use jspdf to add the generated image directly to pdf

html2canvas configuration reference address

JSPDFS Github address

js operation blob size limit, online map

Use

<export-pdf-view
                        ref="pdf"
                        :begin="begin"
                        :flush-content="loadList"
                        :end="end"
                        save-name="Equipment use record.pdf"
                        class="recharge">
</export-pdf-view>

Note: the callback function needs to return to Promise. If the callback function has modified data internally, note that the res. callback function after calling dom after refreshing Promise is called before generating.

  1. Ref uses ref to call the method $refs. Record. Exportpdf() inside the component to export pdf
  2. Called when the callback function begin exports
  3. When the callback function flush content starts to export content, this method will be called repeatedly until the end of res(false) of Promise, / / the list data can be loaded repeatedly here
  4. Called when the callback function end generates the bottom of pdf

ExportPdfView.vue

<template>
    <div class="pdf-view">
        <div ref="header" class="header">
            <slot name="header"></slot>
        </div>
        <div ref="content" class="content">
            <slot name="content"></slot>
        </div>
        <div ref="footer" class="footer">
            <slot name="footer"></slot>
        </div>
    </div>
</template>

<script>
    import FileSaver from 'file-saver';//May need
    import html2canvas from 'html2canvas';
    import PDF from 'jspdf';

    let pdfWidth = 592.28;
    let pdfHeight = 841.89;

    export default {
        name: "ExportPdfView",
        props: ['begin', 'flushContent', 'end', 'saveName'],
        data() {
            return {

            }
        },
        methods: {
            exportPDF(){

                let pdf = new PDF('', 'pt', 'a4');
                let h2cOpt = {backgroundColor: '#fff', scale: 4};
                let nowHeight = 0;

                let appendToPDF = (canvas, dom) => {
                    let domHeight = pdfWidth / dom.offsetWidth * dom.offsetHeight;
                    if(domHeight <= 0){
                        return;
                    }
                    //console.log('pdfHeight:' + pdfHeight, 'domHeight:' + domHeight, 'nowHeight:' + nowHeight);
                    if(nowHeight + domHeight > pdfHeight){
                        pdf.addPage();
                        nowHeight = 0;
                    }

                    let data = canvas.toDataURL('image/jpeg', 1);
                    pdf.addImage(data, 'JPEG', 0, nowHeight, pdfWidth, domHeight);
                    nowHeight += domHeight;
                }

                let buildPDF = async () => {
                    console.log('Start exporting pdf...');
                    if(this.begin){
                        await this.begin();
                    }
                    appendToPDF(await html2canvas(this.$refs.header, h2cOpt), this.$refs.header);
                    let res = false;
                    do{
                        res = await this.flushContent();
                        console.log('Refresh pdf content...', res);
                        appendToPDF(await html2canvas(this.$refs.content, h2cOpt), this.$refs.content);
                    } while (res);
                    if(this.end){
                        await this.end();
                    }
                    appendToPDF(await html2canvas(this.$refs.footer, h2cOpt), this.$refs.footer);
                    console.log('End pdf export, Save to file...');
                    pdf.save(this.saveName || 'export.pdf');
                }
                this.$nextTick( _ => {
                    buildPDF();
                });
            }
        }
    }
</script>

<style scoped lang="less">
.pdf-view{
    //width: 592.28px;
    display: table;
    margin: 0 auto;
    font-size: 12px;

    .header{

    }
    .content{

    }
    .footer{

    }
}
</style>

Topics: Front-end Vue github less