首页 前端知识 Vue3 通过 html2pdf 实现 PDF 预览和导出功能

Vue3 通过 html2pdf 实现 PDF 预览和导出功能

2025-03-01 12:03:10 前端知识 前端哥 202 347 我要收藏

Vue3 通过 html2pdf 实现 PDF 预览和导出功能


1. 前言
  • 简介:PDF 在前端开发中的应用场景,例如报表生成、文档下载、打印功能等。
  • 背景:使用 html2pdf 作为生成 PDF 的工具,支持 PDF 的预览和导出。
  • 目标:通过 Vue3html2pdf.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 的生成。
    • 通过 BlobURL.createObjectURL 实现了 PDF 预览。
    • 动态调整导出样式,生成 PDF 清晰、美观。
  • 适用场景
    • 报表生成。
    • 文档打印。
    • 数据导出和展示。
转载请注明出处或者链接地址:https://www.qianduange.cn//article/22129.html
标签
评论
发布的文章

算法002——复写零

2025-03-02 13:03:05

github上传代码(自用)

2025-03-02 13:03:59

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!