Vue项目中将界面转换为PDF并导出的实现方案

1. 主要技术栈

项目使用了以下库来实现PDF导出功能:

  • html2canvas:将HTML元素转换为canvas图像
  • jspdf:生成PDF文件
  • 自定义的打印插件:基于vue-print-nb改进,支持水印等功能
javascript 复制代码
npm install html2canvas jspdf

2. 核心实现方式

使用html2canvas + jspdf直接生成PDF

javascript 复制代码
// 生成PDF的核心方法
async generatePDF() {
  try {
    // 获取要导出的DOM元素
    const element = this.$refs.pdfContent;
    
    // 临时隐藏不需要打印的元素
    const noPrintElements = element.querySelectorAll('.no-print');
    const originalDisplays = [];
    noPrintElements.forEach((el, index) => {
      originalDisplays[index] = el.style.display;
      el.style.display = 'none';
    });

    // 临时添加PDF导出专用样式
    const style = document.createElement('style');
    style.id = 'pdf-export-style';
    style.textContent = `
      .duty-table {
        width: 1200px !important;
        max-width: none !important;
        font-size: 14px !important;
        // ... 更多样式
      }
    `;
    document.head.appendChild(style);

    // 创建canvas
    const canvas = await html2canvas(element, {
      scale: 2, // 清晰度
      useCORS: true,
      allowTaint: true,
      backgroundColor: '#ffffff',
      width: 1200,
      height: element.scrollHeight,
      ignoreElements: (el) => {
        return el.classList.contains('no-print');
      }
    });

    // 恢复隐藏的元素和样式
    noPrintElements.forEach((el, index) => {
      el.style.display = originalDisplays[index];
    });
    document.getElementById('pdf-export-style')?.remove();

    // 创建PDF
    const imgData = canvas.toDataURL('image/png', 1.0);
    const pdf = new jsPDF('p', 'mm', 'a4');
    
    // 计算图片在PDF中的尺寸并添加到PDF
    const a4Width = 210;
    const a4Height = 297;
    const margin = 5;
    // ... 尺寸计算逻辑
    pdf.addImage(imgData, 'PNG', xOffset, yOffset, imgWidth, imgHeight);

    // 转换为Blob对象
    const pdfBlob = pdf.output('blob');
    const fileName = `排班表_${this.currentDate}_${new Date().getTime()}.pdf`;
    
    return {
      fileName: fileName,
      pdfBlob: pdfBlob,
      message: "PDF生成成功"
    };
  } catch (error) {
    console.error('PDF导出错误:', error);
    return null;
  }
}

3. 实现要点总结

样式处理

  1. 为不需要打印的元素添加no-print类
  2. 临时添加专为PDF导出优化的CSS样式
  3. 处理字体和颜色(打印时通常需要将背景色设为白色)

导出流程

  1. 获取需要导出的DOM元素
  2. 使用html2canvas将其渲染为canvas
  3. 使用jspdf将canvas图像转换为PDF
  4. 通过Blob对象处理PDF数据,提供下载或上传功能

特殊处理

  1. 水印添加:通过CSS或在canvas上叠加实现
  2. 分页处理:计算内容高度,必要时分页
  3. 样式隔离:临时添加导出专用样式,处理完成后恢复

4. 使用示例

javascript 复制代码
// 直接下载PDF
async exportPDF() {
  const result = await this.generatePDF();
  if (result) {
    const url = URL.createObjectURL(result.pdfBlob);
    const link = document.createElement('a');
    link.href = url;
    link.download = result.fileName;
    link.click();
    URL.revokeObjectURL(url);
  }
}

// 上传PDF到服务器
async exportAndUpload() {
  const result = await this.generatePDF();
  if (result && result.pdfBlob) {
    const formData = new FormData();
    const pdfFile = new File([result.pdfBlob], result.fileName, {
      type: "application/pdf",
    });
    formData.append("pdfFile", pdfFile);
    // 发送请求上传文件
    await uploadPDF(formData);
  }
}
相关推荐
触底反弹1 分钟前
🚀 删了数据刷新又回来?3 组件 × 4 回调 × 3 坑讲透 React 父子通信
前端·javascript·react.js
会周易的程序员2 小时前
js-shm: 高性能 Node.js 共享内存模块
开发语言·javascript·c++·node.js·共享内存·shm
带娃的IT创业者2 小时前
重新定义前端构建速度:深度解析 SWC 如何用 Rust 颠覆 JavaScript 工具链
前端·javascript·rust·前端构建·swc
m0_547486663 小时前
《Vue.js + uni-app全栈开发从入门到实践 》全套PPT课件2026版
vue.js·uni-app
审小匠OpenCPAi3 小时前
审计票据与财报 PDF 怎么识别?通用 OCR、表格结构识别与多模态大模型的精度对比
pdf·ocr·审计
2501_930707783 小时前
使用C#代码将 PDF 文件转换为 Markdown 格式
pdf
新中地GIS开发老师4 小时前
零基础WebGIS开发入门 | GeoJSON数据持久化
前端·javascript·gis·webgis·三维gis开发
blns_yxl4 小时前
正则驱动实时表单验证(HTML+CSS+JS+正则)
javascript·css·html
Quz5 小时前
QML 与 JavaScript 交互方式:内联函数、外部文件、信号槽与工作线程
javascript·qt
达子6665 小时前
第10章_HarmonyOs开发图解 用JS开发UI
vue.js