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.
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 jspdfDefine 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>Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaoDou Frontend Team
Open-source, innovative, collaborative, win‑win – sharing frontend tech and shaping its future.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
