First, technology selection

1. Images generated after HTML is converted to Canvas and exported to PDF (selected in this paper)

  • HTML to Canvas plug-in: HTML2Canvas is a plug-in that converts HTML code to Canvas.
  • Canvas generates PDF: jsPDF is an open source library that uses the Javascript language to generate PDF

2. Export HTML code to PDF

Wkhtmltopdf is a plug-in that converts HTML code into PDF. It is mostly used in table scenarios

Ii. Technical implementation (based on HTML2Canvas and jsPDF)

1. Install the plug-in

npm i html2canvas -S
npm i jspdf -S
Copy the code

2. Registration and implementation of encapsulation

The following encapsulated code can be used directly in the project file, with the following points to note:

  1. Because the size of the exported PDF image needs to be fixed, you need to add a. Pdf-screen style class to the DOM of the exported element to find the exported element, and then change the exported element style.
  2. The size of the exported page is fixed at A4.
/ * * *@file Export PDF files */
import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';

/* eslint-disable */

const PDF = {};

// a4
let a4Width = 595.28; 
let a4Height = 841.89;

let defaultOptions = {
    name: new Date().getTime(),
    scale: window.devicePixelRatio * 2.padding: 0.width: 595.28 * 2.allowTaint: true.onclone: function (dom) {
        let screen = dom.querySelector('.pdf-screen');
        screen.style.width = 595.28 * 2 + 'px';
        screen.style.padding = '10px';
    }
}

PDF.install = function (Vue, rootOptions = {}) {
    Vue.prototype.$pdf = function (dom, options = rootOptions) {
        
        options = Object.assign(defaultOptions, options);
        
        html2canvas(dom, options).then(canvas= > {
            let position = 0;

            // Width and height of generated canvas elements (need to shrink back to original scale)
            let canvasWidth = canvas.width / options.scale;
            let canvasHeight = canvas.height / options.scale;

            // Page width and height after scaling
            let pageWidth = a4Width;
            let pageHeight = (a4Width / canvasWidth) * canvasHeight;
            
            // Return image dataURL with parameters: image format and clarity (0-1)
            let jpeg = canvas.toDataURL('image/jpeg'.1.0);

            // Default vertical direction, ponits size, format A4 [595.28,841.89]
            let doc = new JsPDF(' '.'pt'.'a4');
            
            // There are two heights to distinguish, one is the actual height of the HTML page, and the page height of the generated PDF (841.89)
            // When the content does not exceed the size of a PDF page, no pagination is required
            if (canvasHeight < pageHeight) {
                doc.addImage(jpeg, 'JPEG'.0.0, pageWidth, pageHeight); // Print from the top of the image
            } else {
                while (canvasHeight > 0) {
                    doc.addImage(jpeg, 'JPEG'.0, position, pageWidth, pageHeight);
                    canvasHeight -= pageHeight;
                    position -= a4Height;

                    // Avoid adding blank pages
                    if (canvasHeight > 0) {
                        doc.addPage();
                    }
                }
            }
            doc.save(options.name + '.pdf');
        });
    };
};

export default PDF;

Copy the code

3. Usage

// Import the plug-in in main.js
import pdf from "./plugins/pdf";

// Register the plug-in
Vue.use(PDF);

// called in the function that needs to export the PDF
// DOM is the outermost element to export
this.$pdf(dom, options);

// Use case (see HTML2CANVAS configuration)
this.$pdf(this.$refs.screen, {
    name: 'filename'.// Export the file name
    scale: 2.// Export file sharpness, the larger the value, the larger the file size (default value: device DPR *2)
    ignoreElements: (element) = > {  // Ignore render elements (by querying dom elements, not just class names)
        if (element.className.indexOf('className')! = = -1) {
            return true; }}});Copy the code

Problems encountered and solutions

1. PDF content truncation problem (to be solved)

Problem Description: Since the implementation principle is to convert HTML to Canvas and export PDF files in the form of pictures, the content of the long graph generated by Canvas will be truncated in the process of paging saving.

2. PDF export file resolution problem (solved)

Problem description: The image resolution generated by Canvas is too low.

Solution: Dom elements can be scaled to generate images and exported to PDF files;

4. Points to be optimized

1. Export with watermark effect

5. Reference materials

  • Wkhtmltopdf Official document
  • Htmp2canvas official document
  • JsPDF official documentation