前端生成 PDF 求指教

查看 39|回复 1
作者:qingshui33   
vue2 中有没有将 HTML 转成 PDF 的类库,要实现的功能是:页面中一半是固定的图片,一半的数据是动态的,并且包含图表、表格类,同时需要有目录,目录中每栏对应各自的页码。
网上查了下,前端做的话,基本上都是使用 html2canvas + jsPDF 来实现,有帅哥美女用过这种方案吗,不知道是否能满足上面的功能?
我个人理解是这种功能,放后端做会更好点,但是后端说这个涉及到图表之类的,后端实现起来会比较麻烦,所以想看看前端能不能做
pythagorasd   
问 gpt-4o 就行吧,我复制你的问题问的
在 Vue2 中,可以使用以下类库和工具组合将 HTML 页面转为 PDF ,同时满足你的需求:
1. html2canvas 和 jspdf
        •        html2canvas 用于将 HTML 元素渲染为 Canvas 图像。
        •        jspdf 用于生成 PDF 文件,可以支持动态内容、图片、表格和目录。
安装
npm install html2canvas jspdf
示例代码
以下是实现页面一半固定图片,一半动态数据(包含图表、表格)以及目录的示例代码:
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
export default {
  methods: {
    async generatePDF() {
      const pdf = new jsPDF("p", "mm", "a4"); // 创建 A4 纸张的 PDF
      let yOffset = 10; // PDF 初始 Y 位置
      // 添加固定的图片
      const imgElement = document.getElementById("fixed-image");
      const imgCanvas = await html2canvas(imgElement);
      const imgData = imgCanvas.toDataURL("image/png");
      pdf.addImage(imgData, "PNG", 10, yOffset, 90, 40); // 图片位置和大小
      yOffset += 50;
      // 添加动态内容
      const contentElement = document.getElementById("dynamic-content");
      const contentCanvas = await html2canvas(contentElement);
      const contentData = contentCanvas.toDataURL("image/png");
      pdf.addImage(contentData, "PNG", 10, yOffset, 190, 80); // 动态内容
      yOffset += 90;
      // 添加表格、图表
      const chartElement = document.getElementById("chart-content");
      const chartCanvas = await html2canvas(chartElement);
      const chartData = chartCanvas.toDataURL("image/png");
      pdf.addImage(chartData, "PNG", 10, yOffset, 190, 80);
      yOffset += 90;
      // 添加目录
      pdf.addPage(); // 新页面
      pdf.text("目录", 10, 10);
      pdf.text("1. 固定图片...............1", 10, 20);
      pdf.text("2. 动态数据...............2", 10, 30);
      pdf.text("3. 图表、表格.............3", 10, 40);
      // 保存 PDF
      pdf.save("document.pdf");
    },
  },
};
关键点
        •        固定图片部分:将图片元素渲染为 Canvas ,并嵌入 PDF 。
        •        动态数据部分:支持动态表格、图表等通过 HTML 转换。
        •        目录功能:手动添加目录页,并标记每个部分的页码。
2. pdfmake
如果你的数据主要是动态的,可以考虑使用 pdfmake 。它允许使用 JSON 格式定义 PDF 内容,支持表格、图表、目录等。
安装
npm install pdfmake
示例代码
import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";
pdfMake.vfs = pdfFonts.pdfMake.vfs;
export default {
  methods: {
    generatePDF() {
      const docDefinition = {
        content: [
          { text: "目录", style: "header", toc: { title: { text: "目录", style: "subheader" } } },
          { text: "固定图片", style: "subheader" },
          { image: "data:image/png;base64,...", width: 400 },
          { text: "动态数据", style: "subheader" },
          {
            table: {
              body: [
                ["列 1", "列 2", "列 3"],
                ["数据 1", "数据 2", "数据 3"],
              ],
            },
          },
          { text: "图表", style: "subheader" },
          { text: "此处插入图表..." },
        ],
        styles: {
          header: { fontSize: 22, bold: true },
          subheader: { fontSize: 18, bold: true },
        },
      };
      pdfMake.createPdf(docDefinition).download("document.pdf");
    },
  },
};
3. puppeteer (服务器端解决方案)
如果需要更精确的排版和打印效果,推荐使用 puppeteer 在服务器端生成 PDF 。这种方式可以直接将整个 HTML 页面渲染为 PDF 。
安装
npm install puppeteer
示例代码
const puppeteer = require("puppeteer");
async function generatePDF() {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto("http://localhost:8080", { waitUntil: "networkidle2" });
  await page.pdf({
    path: "output.pdf",
    format: "A4",
    printBackground: true,
  });
  await browser.close();
}
generatePDF();
选择方案
        1.        前端生成( html2canvas + jspdf ):适合小型、动态页面。
        2.        动态内容为主( pdfmake ):适合需要大量动态生成内容(如表格、目录)。
        3.        高精度排版( puppeteer ):适合对 PDF 排版有较高要求的场景。
您需要登录后才可以回帖 登录 | 立即注册

返回顶部