How to generate PDF and download it in Vue front-end

How to generate PDF and download it in Vue front-end

Idea: Convert the HTML page into an image through html2canvas, and then generate the base64 of the image into a pdf file through jspdf.

1. Installation and introduction

//Convert the page html into an image npm install html2canvas --save  
// Generate a pdf from the image
npm install jspdf --save

Introduce the defined implementation method and register it in the main file main.js of the project

import htmlToPdf from '@/utils/htmlToPdf';
// Using the Vue.use() method will call the install method in the tool method Vue.use(htmlToPdf);

Portal: Principle and usage of Vue.use() in Vue

2. How to package and export PDF files

Configuration details

let pdf = new jsPDF('p', 'pt', [pdfX, pdfY]);
The first parameter: l: horizontal p: vertical The second parameter: measurement unit ("pt", "mm", "cm", "m", "in" or "px");
The third parameter: can be in the following format, the default is "a4". For a custom format, just pass the size as a numeric array, like: [592.28, 841.89];
		   a0 - a10
		   b0 - b10
		   c0 - c10
  		   dl
		   letter
		   government-letter
		   legal
		   junior-legal
		   ledger
		   tabloid
		   credit card

pdf.addPage() adds a new page to the PDF document, the default size is a4. The parameters are as follows:

pdf.addImage() adds an image to the PDF. The parameters are as follows:

Delete a page of pdf

let targetPage = pdf.internal.getNumberOfPages(); //Get the total pages pdf.deletePage(targetPage); //Delete the target page

Save pdf document

pdf.save(`test.pdf`);

Encapsulate the method of exporting pdf files (utils/htmlToPdf.js)

// Export the page to PDF format import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default{
  install (Vue, options) {
    Vue.prototype.getPdf = function () {
      // When downloading PDF, if it is not at the top of the page, the PDF style will be incorrect, so go back to the top of the page and then download let top = document.getElementById('pdfDom');
      if (top != null) {
        top.scrollIntoView();
        top = null;
      }
      let title = this.exportPDFtitle;
      html2Canvas(document.querySelector('#pdfDom'), {
        allowTaint: true
      }).then(function (canvas) {
        // Get the width and height of the canvas let contentWidth = canvas.width;
        let contentHeight = canvas.height;
	      // The height of the canvas generated by a pdf page displaying the html page;
        let pageHeight = contentWidth / 841.89 * 592.28;
	      //Height of HTML page without PDF generation let leftHeight = contentHeight;
	      // Page offset let position = 0;
	      // The width and height of the canvas image generated by the HTML page in the PDF (in this case: horizontal A4 paper [841.89, 592.28], the vertical size needs to be changed)
        let imgWidth = 841.89;
        let imgHeight = 841.89 / contentWidth * contentHeight;
        let pageData = canvas.toDataURL('image/jpeg', 1.0);
        let PDF = new JsPDF('l', 'pt', 'a4');
        // Two heights need to be distinguished: one is the actual height of the HTML page, and the other is the height of the generated PDF page. // When the content does not exceed the range of one PDF page, no paging is required if (leftHeight < pageHeight) {
          PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        } else {
          while (leftHeight > 0) {
            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
            leftHeight -= pageHeight;
            position -= 592.28;
            // Avoid adding blank pages if (leftHeight > 0) {
              PDF.addPage();
            }
          }
        }
        PDF.save(title + '.pdf')
      })
    }
  }
}

Application in related components

<template>
  <div class="wrap" >
    <div id="pdfDom" style="padding: 10px;">
      <el-table
        :data="tableData"
        border>
        <el-table-column prop="date" label="Date" width="250"></el-table-column>
        <el-table-column prop="name" label="姓名" width="250"></el-table-column>
        <el-table-column prop="address" label="Address"></el-table-column>
      </el-table>
    </div>
    <button type="button" style="margin-top: 20px;" @click="btnClick">Export PDF</button>
  </div>

</template>
 
<script>
export default {
  data() { 
    return {
      exportPDFtitle: "Page export PDF file name",
      tableData: [
         {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'Huoju Avenue, Jiulongpo District, Chongqing'
        }, {
          date: '2016-05-07',
          name: 'Wang Xiaohu',
          address: 'Huoju Avenue, Jiulongpo District, Chongqing'
        },{
          date: '2016-05-03',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-02',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-04',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-01',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-08',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-07',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-01',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-08',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-07',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'Jiangjun Avenue, Jiangning District, Nanjing'
        }, {
          date: '2016-05-07',
          name: 'Wang Xiaohu',
          address: 'Jiangjun Avenue, Jiangning District, Nanjing'
        },, {
          date: '2016-05-04',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-01',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-08',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-07',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        },{
          date: '2016-05-01',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-08',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'No. 1518, Jinshajiang Road, Putuo District, Shanghai'
        }, {
          date: '2016-05-08',
          name: 'Wang Xiaohu',
          address: 'Cultural Avenue, Hongshan District, Wuhan'
        }, {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'Cultural Avenue, Hongshan District, Wuhan'
        }, {
          date: '2016-05-07',
          name: 'Wang Xiaohu',
          address: 'Cultural Avenue, Hongshan District, Wuhan'
        }, {
          date: '2016-05-06',
          name: 'Wang Xiaohu',
          address: 'Jiangjun Avenue, Jiangning District, Nanjing'
        }, {
          date: '2016-05-07',
          name: 'Wang Xiaohu',
          address: 'Cultural Avenue, Hongshan District, Wuhan'
        },
      ]
    } 
  }, 
  methods: {
    btnClick(){
      this.$nextTick(() => {this.getPdf();})
    },
  },  
}
</script>  

Effect

Parts to be optimized

  1. When paging, the page content is truncated (welcome to leave a message for discussion);
  2. Different content starts on a new page; Idea: calculate the excess content and occupy the height of the last page (set spacing = page height - excess height).

Summarize

This is the end of this article about how to generate PDF and download in Vue front-end. For more relevant content about generating PDF and downloading in Vue front-end, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue implements PDF export to solve problems such as blurry generated canvas (recommended)
  • How to implement PDF file preview in Vue
  • Vue implements online preview of PDF files and downloading (pdf.js)
  • Detailed explanation of PDF of Vue2.0 global components
  • Vue implements online preview function of PDF document
  • Print web pages to pdf example code in vue
  • Vue exports the page as an image or PDF
  • Implementation ideas of Vue exporting pages to PDF format
  • Detailed explanation of how to use vue-pdf in vue
  • How to export Vue pages into PDF files

<<:  Nginx access log and error log parameter description

>>:  HTML input file control limits the type of uploaded files

Recommend

MySQL data aggregation and grouping

We often need to summarize data without actually ...

Installation, activation and configuration of ModSecurity under Apache

ModSecurity is a powerful packet filtering tool t...

Detailed tutorial for upgrading zabbix monitoring 4.4 to 5.0

1. Zabbix backup [root@iZ2zeapnvuohe8p14289u6Z /]...

A brief discussion on the issue of element dragging and sorting in table

Recently, when using element table, I often encou...

How to deploy springcloud project with Docker

Table of contents Docker image download Start mys...

MySQL 8.0.11 installation summary tutorial diagram

Installation environment: CAT /etc/os-release Vie...

Use pure CSS to achieve switch effect

First is the idea We use the <input type="...

Vue implements an Input component that gets the key display shortcut key effect

I encountered a requirement to customize shortcut...

What to do if you forget your password in MySQL 5.7.17

1. Add skip-grant-tables to the my.ini file and r...

MySQL 8.0.13 decompression version installation graphic tutorial under Windows

This article shares with you the MySQL 8.0.13 ins...

Three ways to avoid duplicate insertion of data in MySql

Preface In the case of primary key conflict or un...

The difference between docker run and start

The difference between run and start in docker Do...

Solutions to Mysql index performance optimization problems

The optimization created by MySQL is to add index...

How to configure wordpress with nginx

Before, I had built WordPress myself, but at that...