Convert Vue Pages to PDF with html2canvas and jsPDF

Learn how to create a Vue plugin that captures a page with html2canvas and generates a PDF using jsPDF, covering required dependencies, plugin implementation, installation steps, and usage example to export dynamic table content as a PDF file.

MaoDou Frontend Team
MaoDou Frontend Team
MaoDou Frontend Team
Convert Vue Pages to PDF with html2canvas and jsPDF

In many scenarios such as contracts or agreements, downloading a page while preserving its layout is needed; converting the page to PDF provides an effective solution. This guide demonstrates how to build a Vue plugin that uses html2canvas to capture a page as an image and jsPDF to generate a PDF.

Module Dependencies

The plugin relies on two npm packages: html2canvas for converting HTML to an image, and jspdf for creating PDF files.

npm install --save html2canvas
npm install --save jspdf

Define the HtmlToPdf Plugin

Create a htmlToPdf.js file with the following implementation:

// Export page as PDF
import html2canvas from 'html2canvas'
import JSPDF from 'jspdf'
export default {
    install(Vue, options) {
        Vue.prototype.ExportSavePdf = function (htmlTitle, currentTime) {
            var element = document.getElementById('pdfContent')
            html2canvas(element, { logging: false }).then(function (canvas) {
                var pdf = new JSPDF('p', 'mm', 'a4')
                var ctx = canvas.getContext('2d')
                var a4w = 170;
                var a4h = 257
                var imgHeight = Math.floor(a4h * canvas.width / a4w)
                var renderedHeight = 0
                while (renderedHeight < canvas.height) {
                    var page = document.createElement('canvas')
                    page.width = canvas.width
                    page.height = Math.min(imgHeight, canvas.height - renderedHeight)
                    page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0)
                    pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width))
                    renderedHeight += imgHeight
                    if (renderedHeight < canvas.height) {
                        pdf.addPage()
                    }
                }
                pdf.save(htmlTitle + currentTime)
            })
        }
    }
}

Install the Plugin

Import and register the plugin in main.js:

import htmlToPdf from '@/components/utils/htmlToPdf'
Vue.use(htmlToPdf)

Use ExportSavePdf to Convert

Define the DOM container to capture and call ExportSavePdf with the desired file name and timestamp:

<template>
  <div>
    <div ref="pdfContent" id="pdfContent">
      <el-table :data="tableData" border style="width: 100%">
        <el-table-column fixed prop="date" label="日期" width="150"></el-table-column>
        <el-table-column prop="name" label="姓名" width="120"></el-table-column>
        <el-table-column prop="province" label="省份" width="120"></el-table-column>
        <el-table-column prop="city" label="市区" width="120"></el-table-column>
        <el-table-column prop="address" label="地址" width="300"></el-table-column>
        <el-table-column prop="zip" label="邮编" width="120"></el-table-column>
        <el-table-column fixed="right" label="操作" width="100">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
            <el-button type="text" size="small">编辑</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-button type="danger" @click="ExportSavePdf()">导出PDF</el-button>
  </div>
</template>

<script>
import html2canvas from 'html2canvas'
import JSPDF from 'jspdf'
export default {
  methods: {
    handleClick(row) {
      console.log(row)
    },
  },
  data() {
    return {
      htmlTitle: 'PDF名称',
      nowTime: '',
      tableData: [
        { date: '2016-05-03', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 },
        { date: '2016-05-02', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 },
        { date: '2016-05-04', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 },
        { date: '2016-05-01', name: '王小虎', province: '上海', city: '普陀区', address: '上海市普陀区金沙江路 1518 弄', zip: 200333 }
      ]
    }
  }
}
</script>
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

FrontendpluginVuehtml2canvaspdf-generationjspdf
MaoDou Frontend Team
Written by

MaoDou Frontend Team

Open-source, innovative, collaborative, win‑win – sharing frontend tech and shaping its future.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.