当前位置: 首页 > article >正文

前端导出pdf,所见即所得

一、推荐方案:html2canvas + jsPDF(图片式PDF)

javascript

import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';

const exportPDF = async (elementId, fileName) => {
  const element = document.getElementById(elementId);
  
  // 1. 将DOM转为Canvas
  const canvas = await html2canvas(element, {
    scale: 2, // 提升清晰度
    useCORS: true, // 允许跨域图片
    logging: true, // 调试时开启
  });

  // 2. Canvas转图片数据
  const imgData = canvas.toDataURL('image/png', 1.0);
  
  // 3. 计算PDF尺寸
  const pdf = new jsPDF('p', 'mm', 'a4');
  const pageWidth = pdf.internal.pageSize.getWidth();
  const pageHeight = pdf.internal.pageSize.getHeight();
  const imgRatio = canvas.width / canvas.height;
  
  // 4. 自动适应页面大小
  let imgHeight = pageHeight;
  let imgWidth = pageWidth;
  if (pageWidth / imgRatio < pageHeight) {
    imgWidth = pageWidth;
    imgHeight = imgWidth / imgRatio;
  } else {
    imgHeight = pageHeight;
    imgWidth = imgHeight * imgRatio;
  }

  // 5. 添加图片到PDF
  pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
  
  // 6. 保存文件
  pdf.save(`${fileName}.pdf`);
};

// 使用示例
exportPDF('export-container', 'report');
 

二、进阶方案:jsPDF内置HTML渲染(矢量文本)

javascript

import { jsPDF } from "jspdf";

const exportPDF = async () => {
  const doc = new jsPDF('p', 'pt', 'a4');
  
  // 1. 获取需要导出的HTML元素
  const element = document.getElementById('content');
  
  // 2. 直接渲染HTML到PDF(需要配合html2canvas)
  await doc.html(element, {
    callback: (doc) => doc.save('document.pdf'),
    margin: [20, 20, 20, 20],
    autoPaging: 'text',
    width: 170, // 有效内容区宽度(mm)
    windowWidth: element.scrollWidth,
    html2canvas: {
      scale: 0.5, // 控制分辨率
      letterRendering: true,
    },
    x: 10,
    y: 10,
  });
};

三、专业方案:Puppeteer(需后端配合)

javascript

// 前端
fetch('/generate-pdf', {
  method: 'POST',
  body: JSON.stringify({ html: document.documentElement.outerHTML }),
  headers: { 'Content-Type': 'application/json' }
});

// Node.js后端
const puppeteer = require('puppeteer');

app.post('/generate-pdf', async (req, res) => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(req.body.html);
  const pdf = await page.pdf({ 
    format: 'A4',
    printBackground: true 
  });
  await browser.close();
  res.setHeader('Content-Type', 'application/pdf');
  res.send(pdf);
});

四、样式优化要点

  1. 打印样式表

css

@media print {
  @page { margin: 0; }
  body { -webkit-print-color-adjust: exact; }
  .no-print { display: none; }
}
  1. 强制分页

css

.page-break {
  page-break-after: always;
  break-after: page;
}
  1. 字体处理

css

@font-face {
  font-family: 'PDFFont';
  src: url('fonts/Songti.ttf') format('truetype');
}

body {
  font-family: 'PDFFont', sans-serif;
}
 

五、方案对比

方案优点缺点
html2canvas+jsPDF纯前端实现,视觉保真度高文字变图片,文件体积较大
jsPDF HTML渲染支持矢量文字,自动分页兼容性问题,复杂布局易出错
Puppeteer完美还原,支持复杂CSS需要后端支持,消耗服务器资源
window.print()零依赖,简单快捷样式控制能力弱,交互体验差

六、常见问题处理

  1. 内容截断

javascript

// 手动计算分页位置
const elementHeight = element.offsetHeight;
const pageHeight = 1122; // A4像素高度(96dpi)
if (elementHeight > pageHeight) {
  // 插入分页符逻辑
}
  1. 图片跨域

html

​
<img crossorigin="anonymous" src="https://example.com/image.jpg">

​

运行 HTML

  1. 提升清晰度

javascript

html2canvas(element, {
  scale: 3, // 最高3倍
  dpi: 300,
  letterRendering: true
});
 

根据具体需求选择方案:需要快速实现选择方案一,注重文字质量选方案二,企业级应用推荐方案三。


http://www.kler.cn/a/537042.html

相关文章:

  • Linux高级IO
  • 【算法】动态规划专题⑦ —— 多重背包问题 + 二进制分解优化 python
  • 数据结构在 Web 开发中的重要性与应用
  • 如何在macOS上安装Ollama
  • pycharm 中的 Mark Directory As 的作用是什么?
  • web-文件上传-CTFHub
  • 芯科科技的BG22L和BG24L带来应用优化的超低功耗蓝牙®连接
  • Spring Boot 有哪些优点
  • 【Redis】事务因WATCH的键被修改而失败 事务队列中的操作被自动丢弃 UNWATCH的应用场景
  • 视频编辑质量评价的开源项目 VE-Bench 介绍
  • 使用deepseek快速创作ppt
  • 基于物联网技术的智能寻车引导系统方案:工作原理、核心功能及系统架构
  • 如何设置Jsoup请求头模拟浏览器访问?
  • redis之AOF持久化过程
  • Plugin有什么作用?Plugin是什么?
  • 探索robots.txt:网站管理者的搜索引擎指南
  • yolov11模型在Android设备上运行【踩坑记录】
  • 【面试】Java高频面试题(2023最新版)
  • e2studio开发RA2E1(9)----定时器GPT配置输入捕获
  • 5.2Internet及其作用
  • EasyExcel 导出合并层级单元格
  • 技术选型对比:Redis 与 MySQL、Dubbo 与 Spring Cloud
  • Baumer工业相机堡盟相机的相机传感器芯片清洁指南
  • QT全局所有QSS样式实时切换
  • 《机器学习数学基础》补充资料:秩-零化度定理
  • 【AI应用】免费的文本转语音工具:微软 Edge TTS 和 开源版 ChatTTS 对比