Vue3 通过 html2pdf 实现 PDF 预览和导出功能
1. 前言
- 简介:PDF 在前端开发中的应用场景,例如报表生成、文档下载、打印功能等。
- 背景:使用
html2pdf
作为生成 PDF 的工具,支持 PDF 的预览和导出。 - 目标:通过
Vue3
和html2pdf.js
,实现 PDF 文件的预览和导出功能。
2. 准备工作
- 安装依赖:
npm install html2pdf.js // 或 npm install html2pdf.js@latest
- 项目环境说明:
- 前端框架:Vue3
- 样式库:Element Plus(用于表单和对话框展示)
3. 核心功能分析
- 功能 1:PDF 导出(直接下载 PDF 文件)。
- 功能 2:PDF 预览(生成 Blob URL 并在
el-dialog
中通过<embed>
标签展示 PDF)。 - 功能扩展:
- 优化样式:在导出或预览过程中隐藏多余元素,例如按钮。
- 清晰度设置:通过
html2canvas.scale
调整 PDF 渲染清晰度。
4. 实现步骤
-
4.1 PDF 导出功能
- 目标:用户点击“导出 PDF”按钮后,生成并下载 PDF 文件。
- 代码实现:
- 通过
html2pdf().save()
实现导出功能。 - 动态调整样式(隐藏按钮等)。
- 捕获错误并处理样式还原。
- 通过
- 示例代码:
const exportPDF = () => { const element = pdfContent.value; // 需要导出的 HTML 元素 if (!element) { console.error('Error: pdfContent is not defined or not bound to the DOM.'); return; } const container = document.getElementById('pdf-content'); if (!container) { console.error('Error: #pdf-content element not found in the DOM.'); return; } container.classList.add('export'); const options = { margin: [10, 10], filename: '导出的文件.pdf', image: { type: 'jpeg', quality: 1 }, html2canvas: { scale: 3 }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }; html2pdf() .from(element) .set(options) .save() .finally(() => { container.classList.remove('export'); }); };
-
4.2 PDF 预览功能
- 目标:用户点击“预览 PDF”按钮后,生成 PDF 并通过对话框展示。
- 代码实现:
- 通过
html2pdf().toPdf()
获取 PDF 对象。 - 转为
Blob
数据并生成 URL。 - 打开对话框并动态加载 PDF。
- 通过
- 示例代码:
const previewPDF = () => { const element = pdfContent.value; if (!element) { console.error('Error: pdfContent is not defined or not bound to the DOM.'); return; } const container = document.getElementById('pdf-content'); if (!container) { console.error('Error: #pdf-content element not found in the DOM.'); return; } container.classList.add('export'); pdfPreviewDialog.value = true; pdfPreviewUrl.value = null; const options = { margin: [10, 10], image: { type: 'jpeg', quality: 1 }, html2canvas: { scale: 3 }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }; html2pdf() .from(element) .set(options) .toPdf() .get('pdf') .then((pdf) => { const pdfBlob = pdf.output('blob'); pdfPreviewUrl.value = URL.createObjectURL(pdfBlob); }) .finally(() => { container.classList.remove('export'); }); };
-
4.3 全局样式优化
- 目标:在导出和预览过程中动态调整样式,例如隐藏按钮,优化边框。
- 示例样式:
.export .el-button { display: none; } .export .el-descriptions__body, .export .el-descriptions__table { border-color: black !important; } .export .el-descriptions__body td, .export .el-descriptions__body th { border: 1px solid black !important; } .export .el-textarea__inner { border: 1px solid #000 !important; box-shadow: none !important; outline: none !important; }
5. 示例页面代码
完整页面代码,包括导出和预览功能的实现。
<template>
<el-card>
<el-row>
<el-button @click="previewPDF">预览 PDF</el-button>
<el-button @click="exportPDF">导出 PDF</el-button>
</el-row>
<div id="pdf-content" ref="pdfContent">
<!-- PDF 内容 -->
<h2>PDF 示例内容</h2>
<el-descriptions :column="2" border>
<el-descriptions-item label="名称">示例数据</el-descriptions-item>
<el-descriptions-item label="日期">2024-12-18</el-descriptions-item>
</el-descriptions>
</div>
<el-dialog v-model="pdfPreviewDialog" title="PDF 预览" width="60%">
<div v-if="pdfPreviewUrl" style="height: 600px;">
<embed :src="pdfPreviewUrl" type="application/pdf" style="width: 100%; height: 100%;" />
</div>
<div v-else>正在生成预览,请稍候...</div>
</el-dialog>
</el-card>
</template>
<script setup>
import { ref } from 'vue';
import html2pdf from 'html2pdf.js';
const pdfContent = ref(null);
const pdfPreviewDialog = ref(false);
const pdfPreviewUrl = ref(null);
const previewPDF = () => {
// 同上述代码
};
const exportPDF = () => {
// 同上述代码
};
</script>
<style>
/* 同上述样式 */
</style>
6. 总结
- 亮点:
- 使用
html2pdf.js
实现了 PDF 的生成。 - 通过
Blob
和URL.createObjectURL
实现了 PDF 预览。 - 动态调整导出样式,生成 PDF 清晰、美观。
- 使用
- 适用场景:
- 报表生成。
- 文档打印。
- 数据导出和展示。