关于 weasyprint-pdf-creation
weasyprint-pdf-creation 是一项技能,指导使用 HTML、CSS 模板和 WeasyPrint 创建新 PDF,适用于发票、报告和提案等文档。它强调可重复渲染,并提供页面、文本和视觉检查流程。
主要功能
- 01从 HTML/CSS 模板生成 PDF
- 02使用 Jinja2 注入数据
- 03设置打印样式与页面布局
- 04检查渲染警告、页数和提取文本
- 05预览并检查排版与分页
适用场景
- 01制作可复用的发票或报告模板
- 02将业务数据排版为打印文档
- 03检查 PDF 的内容、分页和重叠问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ slapash/ weasyprint-pdf-skill --skill weasyprint-pdf-creation安装后在 Claude Code 中输入/weasyprint-pdf-creation确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdLICENSE.gitignorerequirements.txtdata/sample-one-page-brief.jsonsample-report.jsonsample-statement.jsonsample-invoice.jsonsample-receipt.jsonsample-proposal.jsondocs/pdf-qa.mdtemplate-rules.mdexamples/index.htmlinvoice.htmlreport.htmlone-page-brief.htmlproposal.htmlreceipt.htmlstatement.htmlfonts/README.mdoutputs/.gitkeepscripts/build_examples.pyqa_pdf.pyrender_pdf.pytemplates/proposal.htmlone-page-brief.htmlinvoice.htmlreport.htmlstatement.htmlreceipt.html详细介绍
WeasyPrint PDF 创建
概述
使用此技能,通过受源代码控制的 HTML/CSS 模板创建精美的 PDF。核心工作流如下:
HTML template + print CSS + data → WeasyPrint → PDF → QA → publish/share
适用于由你负责创建的新 PDF:发票、报告、提案、简报、对账单、单页文档、可打印指南,以及基于模板的业务文档。
不要将此技能作为编辑任意现有 PDF 或捕获 JavaScript 密集型网页的默认方法。请参阅下方的决策表。
适用场景
在用户要求以下操作时使用此技能:
- 创建发票、报告、提案、简报、合同类文档、讲义或可打印 PDF
- 使用 HTML/CSS 制作可重复使用的 PDF 模板
- 生成比默认 Markdown 导出效果更好的 PDF
- 在 artifact shelf/静态托管服务上发布 PDF 预览以供审阅
- 测试设计好的文档能否经受打印/PDF 渲染
以下情况不要使用此技能:
- 编辑现有 PDF 中的文本 → 使用 nano-pdf/PyMuPDF
- 对扫描件进行 OCR/提取文本 → 使用 OCR/文档提取工具
- 截取屏幕截图或 JS 渲染的仪表板 → 使用 Playwright/Chromium
- 原始程序化矢量绘图 → 考虑使用 ReportLab/SVG/PyMuPDF
决策表
| 需求 | 工具 |
|---|---|
| 使用模板创建新的设计型发票/报告/文档 | WeasyPrint |
| 编辑现有 PDF 文本 | nano-pdf / PyMuPDF |
| 将 JS 密集型网页或仪表板转为 PDF | Playwright/Chromium |
| 提取/OCR PDF | OCR/文档工具 |
| 低级 PDF 修改/合并/拆分 | pikepdf / PyMuPDF |
推荐的仓库结构
pdf-project/
templates/
invoice.html
report.html
proposal.html
one-page-brief.html
receipt.html
statement.html
styles/
print.css
data/
sample-invoice.json
sample-report.json
sample-proposal.json
scripts/
render_pdf.py
qa_pdf.py
outputs/
.gitkeep
examples/
index.html
invoice.pdf
invoice.png
docs/
pdf-qa.md
template-rules.md
fonts/
README.md
requirements.txt
README.md
模板应易于运行且外观得体:
- 语义化 HTML
- 优先用于打印的 CSS
- 不依赖 JavaScript
- 尽可能使用本地资源/字体
- 将数据注入与布局分离
- 受源代码控制的示例 JSON
- 确定性生成的输出
安装
Python venv
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
python -m weasyprint --info
requirements.txt 最低要求:
weasyprint==68.1
Jinja2>=3.1
pypdf>=5.0
Debian/Ubuntu 原生依赖项
对于大多数现代 Debian/Ubuntu 主机:
sudo apt-get update
sudo apt-get install -y \
python3-pip \
libpango-1.0-0 \
libpangoft2-1.0-0 \
libharfbuzz-subset0 \
fontconfig \
fonts-dejavu-core
模板规则
CSS
有意使用 @page 和打印媒体:
@page { size: A4; margin: 0; }
@media print {
body { background: white; }
.page { width: 210mm; height: 297mm; overflow: hidden; }
.no-print { display: none; }
}
优先采用:
- 用
mm设置页面画布和关键打印间距 - 用 CSS grid/table 实现稳定的文档布局
- 对金额和 ID 使用
font-variant-numeric: tabular-nums - 为发票表格明确指定列宽
- 为印章/徽章/装饰元素预留空间
- 为 IBAN、电子邮件、ID 等长字符串设置换行规则
避免或仔细验证:
- 在内容附近使用绝对定位
- 仅浏览器支持的 CSS
box-shadow、filter、mix-blend-mode等复杂效果- 仅依靠 JS 的图表/渲染流程
- 只有示例文本较短时才能容纳的内容
HTML
使用语义化区块和稳定的类名:
<section class="page invoice">
<header class="invoice-header">...</header>
<section class="invoice-meta">...</section>
<table class="line-items">...</table>
<section class="payment-box">...</section>
</section>
对于较长的值:
.long-value { overflow-wrap: anywhere; }
.amount { white-space: nowrap; text-align: right; }
渲染脚本模式
使用简短的 Python 脚本,以确保渲染过程可重复且可测试。
from pathlib import Path
import argparse, json
from jinja2 import Environment, FileSystemLoader, select_autoescape
from weasyprint import HTML
parser = argparse.ArgumentParser()
parser.add_argument('--template', required=True)
parser.add_argument('--data', required=True)
parser.add_argument('--out', required=True)
args = parser.parse_args()
template_path = Path(args.template)
data = json.loads(Path(args.data).read_text())
env = Environment(
loader=FileSystemLoader(str(template_path.parent)),
autoescape=select_autoescape(['html', 'xml'])
)
html = env.get_template(template_path.name).render(**data)
Path(args.out).parent.mkdir(parents=True, exist_ok=True)
HTML(string=html, base_url=str(template_path.parent.resolve())).write_pdf(args.out)
QA 检查清单
在确认 PDF 完成前,请运行以下所有检查。
1. 检查 WeasyPrint 警告
python scripts/render_pdf.py --template templates/invoice.html --data data/sample-invoice.json --out outputs/invoice.pdf 2> outputs/weasyprint.log
test ! -s outputs/weasyprint.log
警告通常表明存在不受支持的 CSS 或损坏的资源。除非这些问题无害且已有记录,否则请予以修复。
2. 检查 PDF 元数据/页面
pdfinfo outputs/invoice.pdf | grep -E 'Pages|Page size|PDF version'
预期的 A4:
Page size: 595.276 x 841.89 pts (A4)
3. 文本提取冒烟测试
pdftotext outputs/invoice.pdf - | grep -E 'Invoice|Total|Payment'
这可发现不可见文本、内容缺失,以及许多意外空白页问题。
4. 浏览器预览
打开 HTML 预览并检查控制台错误。用于 artifact shelf/静态托管时:
artifact add-dir my-pdf-lab ./public --title "PDF Lab" --type site --tag artifact
curl -fsSI https://artifacts.example.com/artifacts/my-pdf-lab/
5. 视觉/重叠检查
目视检查渲染后的 HTML/PDF。重点关注:
- 总计和金额列
- 付款框
- 较长的 ID/IBAN/电子邮件字段
- 印章/徽章
- 页脚间距
- 分页符
- 页面边界处的表格行
如果用户报告内容重叠,不要敷衍了事。请通过浏览器/视觉检查重新核查,并重新设计拥挤区域。
发布模式
供审阅时,发布包含预览和 PDF 的静态文件夹:
public/
index.html
invoice.html
invoice.pdf
report.html
report.pdf
然后:
artifact add-dir pdf-lab public --title "PDF Lab" --type site --tag artifact
curl -fsSI https://artifacts.omarbenaidy.com/artifacts/pdf-lab/
如果使用其他环境,任何静态托管服务都可以:GitHub Pages、Cloudflare Pages、Netlify、nginx、S3 等。
字体指南
字体会影响分页和内容溢出。为确保生成的 PDF 可复现:
- 明确指定字体栈
- 打包或安装生产环境所用字体
- 除非渲染器运行在 macOS 上,否则不要依赖仅适用于 macOS 的字体
- 更改字体后重新进行 QA
- 更新
fonts/README.md,记录所选字体及其许可证
常见问题
-
把浏览器 CSS 支持当成 WeasyPrint CSS 支持。 WeasyPrint 非常适合打印 CSS,但并不是完整的 Chrome 克隆。尽早生成一次,并查看警告。
-
在实际内容上方进行装饰性绝对定位。 印章、色块和徽章需要预留布局空间。如果它们悬浮在付款信息、合计金额或页脚上方,就会与实际数据重叠。
-
在单行字段中放置过长的值。 IBAN、地址、电子邮件和发票参考号需要使用
overflow-wrap:anywhere或堆叠布局。 -
意外产生额外的空白页。 固定的
min-height:297mm加上内边距或内容可能导致溢出。在打印模式下,使用height:297mm和受控的内边距,并通过pdfinfo检查页数。 -
渲染器版本未固定。 不同版本的 WeasyPrint 可能导致渲染结果变化。固定版本,并在升级后重新检查基准 PDF。
-
字体未固定。 缺少字体或字体不同都会改变布局。安装已知字体,并避免依赖特定系统的字体。
-
只进行截图 QA。 截图仅供辅助检查。请检查日志、页数、提取出的文本、浏览器控制台以及实际 PDF 是否可用。
验证清单
- 已固定 WeasyPrint 版本
- 已安装并记录原生依赖项和字体
- 渲染命令可重复执行
- 渲染日志中没有意外警告
-
pdfinfo显示的页数和尺寸符合预期 -
pdftotext能找到关键内容 - 浏览器预览没有控制台错误
- 视觉 QA 已检查合计金额、付款信息、页脚和分页
- 在需要发布时,公开链接/审核链接返回 200