关于 PDF Generator
PDF Generator 是用于将 Markdown、HTML、文本和结构化数据生成 PDF 的技能,提供排版、报告、水印及合并功能,适合制作报告或印刷材料。
主要功能
- 01将 Markdown 和 HTML 转为 PDF
- 02生成多页报告
- 03添加文本或图片水印
- 04合并多个 PDF 文件
- 05设置文档元数据
- 06处理页面布局与图片
适用场景
- 01将文档导出为 PDF
- 02根据结构化数据制作报告
- 03批量转换 HTML 文档
- 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 文档
步骤:
- 读取源 Markdown 文件
- 使用
marked等库将 Markdown 解析为 HTML - 应用 CSS 样式,呈现专业外观
- 使用 Puppeteer 将 HTML 渲染为 PDF,并设置适当的分页
- 添加元数据(标题、作者、创建日期)
- 保存到指定的输出路径
实现:
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 报告
用途: 创建包含页眉、页脚、页码和章节的结构化报告
步骤:
- 定义报告结构(封面、目录、章节、附录)
- 创建 PDFKit 文档实例
- 添加封面页,包含标题、徽标和日期
- 生成带页码引用的目录
- 添加格式一致的章节
- 在每页添加页眉和页脚
- 添加页码并完成文档
实现:
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
步骤:
- 扫描目录中的 HTML 文件,或接收文件列表
- 设置 Puppeteer 浏览器实例(重复使用以提高效率)
- 对每个 HTML 文件:
- 加载 HTML 内容
- 应用标准样式
- 使用一致的设置渲染为 PDF
- 使用对应的文件名保存
- 关闭浏览器并报告结果
工作流 4:为现有 PDF 添加水印
用途: 为 PDF 文档添加文本或图像水印
步骤:
- 使用 pdf-lib 加载现有 PDF
- 获取所有页面
- 对每一页:
- 绘制水印文本(倾斜、半透明)
- 或叠加水印图像
- 保存修改后的 PDF
- 保留原始元数据
实现:
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 文档合并为一个文件
步骤:
- 创建新的 PDF 文档
- 加载每个源 PDF
- 复制每个源文件中的所有页面
- 将页面添加到新文档
- 保存合并后的 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