mcpField

PDF Generator

github.com/eddiebe147文档处理61 次安装
代码仓库

关于 PDF Generator

PDF Generator 是用于将 Markdown、HTML、文本和结构化数据生成 PDF 的技能,提供排版、报告、水印及合并功能,适合制作报告或印刷材料。

主要功能

  1. 01将 Markdown 和 HTML 转为 PDF
  2. 02生成多页报告
  3. 03添加文本或图片水印
  4. 04合并多个 PDF 文件
  5. 05设置文档元数据
  6. 06处理页面布局与图片

适用场景

  1. 01将文档导出为 PDF
  2. 02根据结构化数据制作报告
  3. 03批量转换 HTML 文档
  4. 04为 PDF 加水印或合并文件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/eddiebe147/claude-settings --skill pdf-generator

安装后在 Claude Code 中输入/pdf-generator确认已加载。

详细介绍

PDF 生成器

PDF Generator 技能支持从多种来源创建专业的 PDF 文档,包括 Markdown、HTML、纯文本和结构化数据。它可以处理格式、图像、元数据、水印和多页布局。该技能利用 puppeteer、pdfkit 或 jsPDF 等 Node.js 库,提供全面的 PDF 生成能力。

无论您需要将文档转换为 PDF、生成带图表的报告、创建可打印表单,还是制作交付给客户的材料,该技能都能提供相应工具和工作流,以编程方式创建出版级质量的 PDF。

核心工作流

工作流 1:将 Markdown 转换为 PDF

用途: 将 Markdown 文件转换为经过格式化的 PDF 文档

步骤:

  1. 读取源 Markdown 文件
  2. 使用 marked 等库将 Markdown 解析为 HTML
  3. 应用 CSS 样式,呈现专业外观
  4. 使用 Puppeteer 将 HTML 渲染为 PDF,并设置适当的分页
  5. 添加元数据(标题、作者、创建日期)
  6. 保存到指定的输出路径

实现:

const puppeteer = require('puppeteer');
const marked = require('marked');
const fs = require('fs');

async function markdownToPdf(mdPath, outputPath, options = {}) {
  const markdown = fs.readFileSync(mdPath, 'utf8');
  const html = marked.parse(markdown);

  const styledHtml = `
    <!DOCTYPE html>
    <html>
    <head>
      <style>
        body { font-family: 'Helvetica', sans-serif; margin: 40px; line-height: 1.6; }
        h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
        h2 { color: #34495e; margin-top: 30px; }
        code { background: #f4f4f4; padding: 2px 6px; border-radius: 3px; }
        pre { background: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto; }
        blockquote { border-left: 4px solid #3498db; padding-left: 20px; color: #7f8c8d; }
      </style>
    </head>
    <body>${html}</body>
    </html>
  `;

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(styledHtml);
  await page.pdf({
    path: outputPath,
    format: 'A4',
    margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' },
    printBackground: true,
    ...options
  });
  await browser.close();
}
工作流 2:生成多页 PDF 报告

用途: 创建包含页眉、页脚、页码和章节的结构化报告

步骤:

  1. 定义报告结构(封面、目录、章节、附录)
  2. 创建 PDFKit 文档实例
  3. 添加封面页,包含标题、徽标和日期
  4. 生成带页码引用的目录
  5. 添加格式一致的章节
  6. 在每页添加页眉和页脚
  7. 添加页码并完成文档

实现:

const PDFDocument = require('pdfkit');
const fs = require('fs');

function generateReport(data, outputPath) {
  const doc = new PDFDocument({
    size: 'A4',
    margins: { top: 50, bottom: 50, left: 50, right: 50 }
  });

  const stream = fs.createWriteStream(outputPath);
  doc.pipe(stream);

  // Cover page
  doc.fontSize(28)
     .text(data.title, { align: 'center' })
     .moveDown(2)
     .fontSize(14)
     .text(`Generated: ${new Date().toLocaleDateString()}`, { align: 'center' });

  doc.addPage();

  // Table of contents
  doc.fontSize(20).text('Table of Contents', { underline: true });
  doc.moveDown();
  data.sections.forEach((section, idx) => {
    doc.fontSize(12)
       .fillColor('blue')
       .text(`${idx + 1}. ${section.title}`, { link: `#section${idx}` })
       .fillColor('black');
  });

  // Sections
  data.sections.forEach((section, idx) => {
    doc.addPage();
    doc.fontSize(18)
       .fillColor('black')
       .text(section.title, { destination: `section${idx}` });
    doc.moveDown();
    doc.fontSize(11).text(section.content, { align: 'justify' });
  });

  // Add page numbers
  const pages = doc.bufferedPageRange();
  for (let i = 0; i < pages.count; i++) {
    doc.switchToPage(i);
    doc.fontSize(10)
       .text(`Page ${i + 1} of ${pages.count}`,
             50, doc.page.height - 50,
             { align: 'center' });
  }

  doc.end();
}
工作流 3:批量将 HTML 转换为 PDF

用途: 在一次操作中将多个 HTML 文件转换为 PDF

步骤:

  1. 扫描目录中的 HTML 文件,或接收文件列表
  2. 设置 Puppeteer 浏览器实例(重复使用以提高效率)
  3. 对每个 HTML 文件:
    • 加载 HTML 内容
    • 应用标准样式
    • 使用一致的设置渲染为 PDF
    • 使用对应的文件名保存
  4. 关闭浏览器并报告结果
工作流 4:为现有 PDF 添加水印

用途: 为 PDF 文档添加文本或图像水印

步骤:

  1. 使用 pdf-lib 加载现有 PDF
  2. 获取所有页面
  3. 对每一页:
    • 绘制水印文本(倾斜、半透明)
    • 或叠加水印图像
  4. 保存修改后的 PDF
  5. 保留原始元数据

实现:

const { PDFDocument, rgb, degrees } = require('pdf-lib');
const fs = require('fs');

async function addWatermark(inputPath, outputPath, watermarkText) {
  const existingPdfBytes = fs.readFileSync(inputPath);
  const pdfDoc = await PDFDocument.load(existingPdfBytes);
  const pages = pdfDoc.getPages();

  pages.forEach(page => {
    const { width, height } = page.getSize();
    page.drawText(watermarkText, {
      x: width / 2 - 100,
      y: height / 2,
      size: 48,
      color: rgb(0.75, 0.75, 0.75),
      opacity: 0.3,
      rotate: degrees(-45)
    });
  });

  const pdfBytes = await pdfDoc.save();
  fs.writeFileSync(outputPath, pdfBytes);
}
工作流 5:合并多个 PDF

用途: 将多个 PDF 文档合并为一个文件

步骤:

  1. 创建新的 PDF 文档
  2. 加载每个源 PDF
  3. 复制每个源文件中的所有页面
  4. 将页面添加到新文档
  5. 保存合并后的 PDF,并合并元数据

快速参考

操作命令/触发语
将 Markdown 转换为 PDF“将 [file.md] 转换为 pdf”
根据数据生成报告“根据 [data] 创建 pdf 报告”
批量转换 HTML“将所有 html 文件转换为 pdf”
添加水印“将水印 [text] 添加到 [file.pdf]”
合并 PDF“合并 [file1.pdf] 和 [file2.pdf]”
提取页面“从 [file.pdf] 中提取第 1-5 页”
压缩 PDF“压缩 [file.pdf]”
添加元数据“设置 [file.pdf] 的 pdf 元数据”

最佳实践

  • 页面尺寸: 始终指定纸张格式('A4'、'Letter')和方向,以保持一致
  • 页边距: 使用至少 15mm 的页边距,确保适合打印
  • 字体: 嵌入字体或使用标准 PDF 字体(Helvetica、Times、Courier),以确保兼容性
  • 图像: 嵌入图像前先压缩,以减小文件大小
  • 文件大小: 监控 PDF 大小;文件超过 5MB 时使用压缩
  • 无障碍性: 尽可能添加文档结构标签,方便屏幕阅读器读取
  • 元数据: 始终设置标题、作者和创建日期元数据
  • 分页符: 使用 CSS page-break-before 或 page-break-after 控制分页
  • 测试: 在多个查看器(Adobe、Preview、浏览器)中测试 PDF
  • 安全性: 为敏感文档提供密码保护和权限设置
  • 验证: 如果需要达到归档质量,请验证是否符合 PDF/A 标准
  • 批量操作: 转换多个文件时重复使用浏览器实例

常见模式

文档导出:

// Convert project README to PDF with styling
await markdownToPdf('./README.md', './docs/README.pdf', {
  headerTemplate: '<div style="font-size:10px; text-align:center;">Project Documentation</div>',
  footerTemplate: '<div style="font-size:10px; text-align:center;">Page <span class="pageNumber"></span></div>',
  displayHeaderFooter: true
});

发票生成:

// Create PDF invoice from template
const doc = new PDFDocument();
doc.pipe(fs.createWriteStream('invoice.pdf'));
doc.fontSize(20).text('INVOICE', { align: 'center' });
doc.fontSize(12).text(`Invoice #: ${invoiceNumber}`);
doc.text(`Date: ${date}`);
// ... add line items, totals, etc.
doc.end();

依赖项

安装所需软件包:

npm install puppeteer pdfkit pdf-lib marked

错误处理

  • 文件未找到: 处理前验证源文件路径
  • 内存问题: 处理大型 PDF 时,使用流式处理和分块处理
  • 字体错误: 自定义字体加载失败时,回退到标准字体
  • 渲染超时: 对于复杂页面,延长 Puppeteer 超时时间
  • 权限: 妥善处理读写权限错误

性能提示

  • 批量操作时重复使用 Puppeteer 浏览器实例
  • 对包含大量图像的文件使用 PDF 压缩
  • 对重复转换的内容缓存渲染后的 HTML
  • 逐页处理大型 PDF,而不是将其全部加载到内存中
  • 使用工作线程并行生成 PDF

评论

支持 Markdown