SoFunction
Updated on 2025-04-09

Example of code that generates PDF (jsPDF) in pure front-end and downloads saved or uploads to OSS

Preface

I encountered a need in my work, which is to generate PDFs on the front-end page and save them locally, because the front-end website may display various tables, chart information content and have brighter color styles. If the PDF produced by the back-end is allowed to be different from the display of the front-end page, the task will fall on the front-end.

Technology involves

  • jsPDF
  • html2canvas 

  • ali-oss

Code implementation

1. Obtain the DOM node

First, you need to obtain the DOM node that needs to be printed. At this time, the DOM node obtained has a style, which is equivalent to the content in the page.

 const eleHtml = ('.zxksBody');

2. Get the properties of the print container

First make a compatible judgment to determine whether the DOM node information has been obtained. If the DOM node is obtained, the content of the DOM node will be obtained and the height and width are assigned.

 if (eleHtml) {
    let eleW = ; // Get the width of the container    let eleH = ; // Get the height of the container }

3. Generate PDF

This step is to use the obtained DOM node throughjsPDF and html2canvasGenerate to PDF

html2canvas(eleHtml, {
        dpi: 300,
        width: eleW,
        height: eleH,
        scale: 2, // Improve rendering quality        useCORS: true  //Allow canvas to request external link pictures across domains, allowing cross-domain requests.      }).then(async (canvas) => {
            const pdf = new jsPDF('', 'pt', 'a4');
            const imgData = ('image/png', 1.0);
            //The size of a4 paper [595.28,841.89], the width and height of the image generated by the html page in the pdf            const imgWidth = 555.28;
            //One page of pdf displays the canvas height generated by the html page;            const imgHeight = 555.28 /  * ;
            // Calculate paging            const pageHeight = 841.89;
            //The html page height of the pdf is not generated            let leftHeight = imgHeight;
            //Page Offset            let position = 0;

            if (leftHeight < pageHeight) {
              //Set in (pageData, 'JPEG', left, upper, width, height) to display in pdf              (imgData, 'PNG', 20, 20, imgWidth, imgHeight);
            } else { // Pagination               while (leftHeight > 0) {
                  (imgData, 'PNG', 20, position, imgWidth, imgHeight);
                  leftHeight -= pageHeight;
                  position -= 841.89;
                  if (leftHeight > 0) {
                      ();
                  }
               }
         });

4. Save local or upload OSS

Save local

Saving the local area is simple. You can save it locally by calling the method provided by the PDF library directly.

(`${}-${}.pdf`)

Upload OSS

The uploaded OSS is a bit more complicated. First, you need to configure the content of the OSS, then convert the PDF into a Blob object, and finally call the OSS interface to achieve uploading.

// Configure OSSconst client = new OSS({
  region: "******",
  bucket: 'bucketName',
  endpoint: 'endpoint',
  stsToken: 'securityToken',
  accessKeyId: 'accessKeyId',
  accessKeySecret: 'accessKeySecret',
});


// Convert PDF files to Blob objectsconst pdfBlob = ('blob');

// Call OSS to implement uploadconst fileRes = await (`${}-${}.pdf`, pdfBlob);
(fileRes, 'Receive the returned OSS information');

5. Things to note

  • usehtml2canvas and jsPDFYou may encounter text misalignment or style errors. At this time, you need to adjust it. You can adjust it through the onclone callback method in html2canvas.
html2canvas(eleHtml, {
  onclone: (documentClone) => {
    // Modify on the cloned document    const partRight2 = ('.partRight2');
    const titleBars = ('.titleBar');

    if (partRight2) {
       = 'none'; // Hide content    }
    if (titleBars) {
      //Modify style properties      (titleBar => {
         = '-8px';
         = '20px';
      });
    }
  },
  dpi: 300,
  width: eleW,
  height: eleH,
  scale: 2, // Improve rendering quality  useCORS: true  //Allow canvas to request external link pictures across domains, allowing cross-domain requests.}).then(async (canvas) => {
        .......
    });
  • When obtaining DOM, the content with scroll bar cannot correctly obtain its height and width, and the content may be masked and cannot be printed correctly. At this time, you need to change the DOM style in the page before printing to print correctly.
// Get all contentconst eleHtml = ('.zxksBody');

// Change the style before generating canvas to get the normal height or width of the box to prevent the style from being covered.const changeHeight = ('.zxksContent');

if (changeHeight) {
   = '100%'; // Change the height}

html2canvas(eleHtml, {
    dpi: 300,
    width: eleW,
    height: eleH,
    scale: 2, // Improve rendering quality    useCORS: true  //Allow canvas inside canvas }).then(async (canvas) => {

        .....

        // After printing, change the style back        if (changeHeight) {
            = 'calc(100vh - 182px)';
        }
    }
  • For div boxes with scroll bars, when clicking to print, it is best to change the page content to prevent the box height from being unable to be correctly obtained, resulting in the text being hidden. After printing is completed, change it back

// For vue

You can use v-if to replace it, save the displayed content in the div, and remove the overflow scrolling function.

// For react

The content displayed can be judged using the ternary operator.

6. Complete code

const printPdf = async () => {
       const client = new OSS({
              const client = new OSS({
              region: "******",
              bucket: 'bucketName',
              endpoint: 'endpoint',
              stsToken: 'securityToken',
              accessKeyId: 'accessKeyId',
              accessKeySecret: 'accessKeySecret',
        }); 
       try {
          // Get all content          const eleHtml = ('.zxksBody');
          // With the function of removing hidden          const changeHeight = ('.zxksContent');

          if (changeHeight) {
             = '100%'; // Change the height          }

          if (eleHtml) {
            let eleW = ; // Get the width of the container            let eleH = ; // Get the height of the container
            // Make sure to get the full loading DOM            setTimeout(() => { 
              html2canvas(eleHtml, {
                onclone: (documentClone) => {
                  // Modify on the cloned document                  const partRight2 = ('.partRight2');
                  const titleBars = ('.titleBar');

                  if (partRight2) {
                     = 'none'; // Hide content                  }
                  if (titleBars) {
                    (titleBar => {
                       = '-8px';
                       = '20px';
                    });
                  }
                },
                dpi: 300,
                width: eleW,
                height: eleH,
                scale: 2, // Improve rendering quality                useCORS: true  //Allow canvas to request external link pictures across domains, allowing cross-domain requests.              }).then(async (canvas) => {
                const pdf = new jsPDF('', 'pt', 'a4');
                const imgData = ('image/png', 1.0);
                const imgWidth = 555.28;
                const imgHeight = 555.28 /  * ;

                // Calculate paging                const pageHeight = 841.89;
                let leftHeight = imgHeight;
                let position = 0;

                if (leftHeight < pageHeight) {
                  (imgData, 'PNG', 20, 20, imgWidth, imgHeight);
                } else {
                  while (leftHeight > 0) {
                    (imgData, 'PNG', 20, position, imgWidth, imgHeight);
                    leftHeight -= pageHeight;
                    position -= 841.89;
                    if (leftHeight > 0) {
                      ();
                    }
                  }
                }

                // Convert PDF files to Blob objects                const pdfBlob = ('blob');
              
                //Upload Blob objects using OSS client                try {
                  const fileRes = await (`${}-${statexsBh}.pdf`, pdfBlob);
                  ('client res', fileRes);
                } catch (err) {
                  ('Pdf upload failed, please resubmit!  ', err);
                }

                if (changeHeight) {
                   = 'calc(100vh - 182px)';
                }
              });
            }, 1000);
          }
        } catch (error) {
          ("Error!", error);
          if (changeHeight) {
             = 'calc(100vh - 182px)';
          }
        }
      };

Summarize

This is the article about generating PDFs (jsPDF) in pure front-end and downloading, saving or uploading to OSS. For more related articles, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!