PDF 编程示例
使用不同编程语言解析和操作 PDF 文件
1. 基础文本提取(pypdf)
from pypdf import PdfReader
def extract_text(pdf_path):
reader = PdfReader(pdf_path)
text = ""
for page in reader.pages:
text += page.extract_text()
return text
text = extract_text("document.pdf")
print(text)
2. 合并多个 PDF
from pypdf import PdfMerger
def merge_pdfs(files, output):
merger = PdfMerger()
for f in files:
merger.append(f)
merger.write(output)
merger.close()
merge_pdfs(["a.pdf", "b.pdf"], "merged.pdf")
3. ReportLab 创建表格
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
def create_table_pdf():
doc = SimpleDocTemplate("table.pdf")
data = [
['产品', 'Q1', 'Q2', 'Q3', 'Q4'],
['产品 A', '12500', '15800', '18200', '22100'],
['产品 B', '8900', '10200', '12500', '14800'],
]
table = Table(data)
table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.blue),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('GRID', (0,0), (-1,-1), 1, colors.grey),
]))
doc.build([table])
create_table_pdf()
4. ReportLab 绘制图表
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.charts.barcharts import VerticalBarChart
def create_chart():
drawing = Drawing(400, 200)
chart = VerticalBarChart()
chart.data = [(12500, 15800, 18200, 22100)]
chart.categoryAxis.categoryNames = ['Q1', 'Q2', 'Q3', 'Q4']
chart.bars.fillColor = colors.blue
drawing.add(chart)
return drawing
5. Mermaid-Py 生成流程图
# 安装
pip install mermaid-py
# 基本使用
from mermaid import Mermaid, Graph, SequenceDiagram, ClassDiagram
# 创建流程图
graph = Graph('TD')
graph.add_node('A', '开始')
graph.add_node('B', '处理')
graph.add_node('C', '结束')
graph.add_edge('A', 'B')
graph.add_edge('B', 'C')
# 渲染为 SVG
mermaid_code = str(graph)
print(mermaid_code)
# 保存为文件
with open('diagram.mmd', 'w') as f:
f.write(mermaid_code)
# 转换为 PDF(需要 mermaid-cli)
# mmdc -i diagram.mmd -o diagram.pdf
# 序列图示例
seq = SequenceDiagram()
seq.participant('用户')
seq.participant('系统')
seq.message('用户', '系统', '请求数据')
seq.message('系统', '用户', '返回结果')
# 类图示例
class_diag = ClassDiagram()
class_diag.add_class('User', ['name', 'email'], ['login()', 'logout()'])
class_diag.add_class('Order', ['id', 'total'], ['create()', 'cancel()'])
class_diag.add_relation('User', 'Order', 'places', '1..*')
# 完整 PDF 报告示例
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Image, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
def create_mermaid_pdf():
doc = SimpleDocTemplate("mermaid_report.pdf", pagesize=A4)
elements = []
styles = getSampleStyleSheet()
# 添加标题
elements.append(Paragraph("Mermaid 流程图报告", styles['Title']))
elements.append(Paragraph("使用 Mermaid-Py 生成", styles['Normal']))
# 添加 Mermaid 图表(需要先生成 SVG/PNG)
# 1. 使用 mermaid-cli 转换
# 2. 或使用在线 API 渲染
# 示例:添加流程图描述
elements.append(Paragraph("流程图说明:", styles['Heading2']))
elements.append(Paragraph("开始 → 处理 → 结束", styles['Normal']))
doc.build(elements)
create_mermaid_pdf()
Mermaid-Py 特点
- 优点 - Python 方式编写 Mermaid 图表,代码即文档,支持流程图/序列图/类图等
- 缺点 - 需要 mermaid-cli 或在线服务转换为 PDF/图像
- 适用场景 - 技术文档,架构 diagrams,流程说明
- 转换工具 - mermaid-cli (mmdc), Mermaid Live Editor, 在线 API
6. Pyecharts 生成可视化图表
# 安装
pip install pyecharts
# 基本使用 - 柱状图
from pyecharts import options as opts
from pyecharts.charts import Bar
bar = Bar()
bar.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
bar.add_yaxis("商家 A", [120, 200, 150, 80, 70, 110])
bar.add_yaxis("商家 B", [80, 150, 110, 100, 90, 130])
bar.set_global_opts(title_opts=opts.TitleOpts(title="销售数据"))
# 渲染为 HTML
bar.render("bar_chart.html")
# 渲染为 PNG(需要 snapshot-selenium)
# pip install snapshot-selenium
from snapshot_selenium import snapshot
bar.render_snapshot("bar_chart.png")
# 饼图
from pyecharts.charts import Pie
pie = Pie()
pie.add(
"销售占比",
[
("衬衫", 120),
("羊毛衫", 200),
("雪纺衫", 150),
("裤子", 80),
("高跟鞋", 70),
("袜子", 110)
]
)
pie.set_global_opts(title_opts=opts.TitleOpts(title="饼图示例"))
pie.render("pie_chart.html")
# 折线图
from pyecharts.charts import Line
line = Line()
line.add_xaxis(["1 月", "2 月", "3 月", "4 月", "5 月", "6 月"])
line.add_yaxis("销售额", [220, 182, 191, 234, 290, 330])
line.set_global_opts(title_opts=opts.TitleOpts(title="月度趋势"))
line.render("line_chart.html")
# 完整 PDF 报告示例
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Image, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
from pyecharts.charts import Bar
import pyecharts.options as opts
def create_pyecharts_pdf():
# 1. 创建图表并保存为图片
bar = Bar()
bar.add_xaxis(["产品 A", "产品 B", "产品 C", "产品 D"])
bar.add_yaxis("销量", [120, 200, 150, 80])
bar.set_global_opts(title_opts=opts.TitleOpts(title="销售对比"))
bar.render_snapshot("chart.png")
# 2. 创建 PDF 报告
doc = SimpleDocTemplate("pyecharts_report.pdf", pagesize=A4)
elements = []
styles = getSampleStyleSheet()
# 添加标题
elements.append(Paragraph("Pyecharts 可视化报告", styles['Title']))
elements.append(Paragraph("使用 Python 生成 ECharts 图表", styles['Normal']))
elements.append(PageBreak())
# 添加图表
elements.append(Paragraph("销售数据对比", styles['Heading2']))
elements.append(Image("chart.png", width=400, height=300))
doc.build(elements)
create_pyecharts_pdf()
Pyecharts 特点
- 优点 - 基于百度 ECharts,图表类型丰富(50+),交互性强,支持 HTML/PNG 导出
- 缺点 - 需要额外安装 snapshot-selenium 才能导出图片
- 适用场景 - 数据可视化报告,仪表盘,动态图表
- 图表类型 - 柱状图、折线图、饼图、散点图、地图、雷达图、箱线图等
1. 安装依赖
go get github.com/unidoc/unipdf/v3
go get github.com/jung-kurt/gofpdf
2. 文本提取(unipdf)
package main
import (
"fmt"
"github.com/unidoc/unipdf/v3/model"
)
func extractText(path string) error {
f, err := model.NewPdfReaderFromFile(path, nil)
if err != nil { return err }
numPages, _ := f.GetNumPages()
for i := 1; i <= numPages; i++ {
page, _ := f.GetPage(i)
ex, _ := extractor.New(page)
text, _ := ex.ExtractText()
fmt.Println(text)
}
return nil
}
3. gofpdf 创建 PDF
package main
import "github.com/jung-kurt/gofpdf"
func createPDF() {
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddPage()
pdf.SetFont("Arial", "B", 16)
pdf.Cell(40, 10, "Hello World!")
pdf.OutputFileAndClose("hello.pdf")
}
1. pdf.js 提取文本
import * as pdfjsLib from 'pdfjs-dist';
async function extractText(url) {
const pdf = await pdfjsLib.getDocument(url).promise;
let text = '';
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const content = await page.getTextContent();
text += content.items.map(item => item.str).join(' ');
}
return text;
}
2. pdf-lib 创建 PDF
import { PDFDocument, rgb } from 'pdf-lib';
async function createPDF() {
const doc = await PDFDocument.create();
const page = doc.addPage([600, 400]);
page.drawText('Hello, PDF!', {
x: 50, y: 350, size: 30,
color: rgb(0, 0.4, 0.8)
});
const bytes = await doc.save();
// 保存或下载 bytes
}
3. pdfkit 创建表格
const PDFDocument = require('pdfkit');
const doc = new PDFDocument();
doc.pipe(require('fs').createWriteStream('table.pdf'));
const data = [['产品', 'Q1', 'Q2'], ['A', '100', '150']];
let y = 50, x = 50;
// 表头
doc.font('Helvetica-Bold').fontSize(12);
data[0].forEach((h, i) => doc.text(h, x + i * 100, y));
// 数据行
doc.font('Helvetica').fontSize(10);
data[1].forEach((d, i) => doc.text(d, x + i * 100, y + 20));
doc.end();
| 需求场景 | Python | Golang | JavaScript |
|---|---|---|---|
| 文本提取 | pypdf | unipdf | pdf.js |
| 创建 PDF | reportlab | gofpdf | pdf-lib |
| 表格生成 | reportlab | unipdf | pdfkit |
| 图表绘制 | reportlab | 自定义 | Chart.js+pdfkit |
| Web 显示 | - | - | pdf.js |
🌐 HTML 转 PDF 工具
将 HTML/CSS 页面转换为 PDF 文档的常用工具
wkhtmltopdf - WebKit 内核 PDF 生成器
# 安装
# macOS
brew install wkhtmltopdf
# Ubuntu/Debian
sudo apt-get install wkhtmltopdf
# 基本使用
wkhtmltopdf input.html output.pdf
# 命令行示例
wkhtmltopdf --page-size A4 --margin-top 20mm \
--encoding UTF-8 https://example.com output.pdf
# Python 集成 (pdfkit)
pip install pdfkit
import pdfkit
pdfkit.from_url('https://example.com', 'output.pdf')
pdfkit.from_file('input.html', 'output.pdf')
pdfkit.from_string('Hello
', 'output.pdf')
# 配置选项
config = pdfkit.configuration(wkhtmltopdf='/usr/bin/wkhtmltopdf')
pdfkit.from_string(html, 'output.pdf', configuration=config)
wkhtmltopdf 特点
- 优点 - 基于 WebKit 引擎,CSS 支持好,使用简单,跨平台
- 缺点 - 已停止维护,不支持 CSS Grid/Flexbox 等新特性
- 适用场景 - 简单 HTML 页面转换,快速原型
WeasyPrint - Python CSS 渲染引擎
# 安装
pip install weasyprint
# 命令行使用
weasyprint input.html output.pdf
weasyprint https://example.com output.pdf
# Python API
from weasyprint import HTML, CSS
# 从 HTML 字符串
HTML(string='Hello World
').write_pdf('output.pdf')
# 从文件
HTML('input.html').write_pdf('output.pdf')
# 自定义 CSS
HTML('input.html').write_pdf('output.pdf',
stylesheets=[CSS('style.css')])
# 高级配置
from weasyprint import HTML, CSS, default_url_fetcher
html = HTML(string=html_content, base_url='.')
html.write_pdf('output.pdf',
stylesheets=[CSS(string='@page { size: A4; }')],
url_fetcher=default_url_fetcher,
optimize_size=('fonts', 'images'))
WeasyPrint 特点
- 优点 - 纯 Python 实现,支持 CSS Paged Media,持续维护
- 缺点 - JavaScript 不支持,复杂布局渲染可能不一致
- 适用场景 - 报告生成,打印样式文档,书籍排版
Pandoc - 万能文档转换器
# 安装
# macOS
brew install pandoc
# Ubuntu/Debian
sudo apt-get install pandoc
# 基本使用
pandoc input.md -o output.pdf
pandoc input.html -o output.pdf
# 指定 PDF 引擎
pandoc input.md -o output.pdf --pdf-engine=wkhtmltopdf
pandoc input.md -o output.pdf --pdf-engine=weasyprint
pandoc input.md -o output.pdf --pdf-engine=xelatex
# Markdown 转 PDF(推荐)
pandoc document.md -o document.pdf \
--pdf-engine=xelatex \
--variable mainfont="SimSun" \
--toc --toc-depth=3
# 批量转换
pandoc *.md -o combined.pdf
# Python 集成 (pypandoc)
pip install pypandoc
import pypandoc
output = pypandoc.convert_file('input.md', 'pdf',
extra_args=['--pdf-engine=xelatex'])
Pandoc 特点
- 优点 - 支持 50+ 格式,Markdown 友好,可切换多种 PDF 引擎
- 缺点 - 需要额外安装 LaTeX 或 PDF 引擎,配置复杂
- 适用场景 - 学术文档,技术文档,多格式转换
| 工具 | 语言 | CSS 支持 | JS 支持 | 维护状态 | 推荐度 |
|---|---|---|---|---|---|
| wkhtmltopdf | C++ | 中等 | ✅ | ⚠️ 已停止 | ⭐⭐ |
| WeasyPrint | Python | 良好 | ❌ | ✅ 活跃 | ⭐⭐⭐⭐ |
| Pandoc | Haskell | 依赖引擎 | 依赖引擎 | ✅ 活跃 | ⭐⭐⭐⭐ |
| Puppeteer | Node.js | 优秀 | ✅ | ✅ 活跃 | ⭐⭐⭐⭐⭐ |
| Playwright | Node.js/Python | 优秀 | ✅ | ✅ 活跃 | ⭐⭐⭐⭐⭐ |
| Pyppeteer | Python | 优秀 | ✅ | ⚠️ 缓慢 | ⭐⭐⭐ |
Puppeteer - Node.js 无头浏览器
// 安装
npm install puppeteer
// 基本使用
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle2'
});
await page.pdf({
path: 'output.pdf',
format: 'A4',
printBackground: true,
margin: { top: '20mm', bottom: '20mm' }
});
await browser.close();
})();
// 高级配置
await page.pdf({
path: 'report.pdf',
format: 'A4',
width: '210mm',
height: '297mm',
margin: { top: '10mm', right: '10mm', bottom: '10mm', left: '10mm' },
printBackground: true,
displayHeaderFooter: true,
headerTemplate: '报告标题',
footerTemplate: '/',
preferCSSPageSize: true
});
Playwright - 跨浏览器自动化框架
// 安装(Node.js)
npm install playwright
// 基本使用
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle'
});
await page.pdf({
path: 'output.pdf',
format: 'A4',
printBackground: true
});
await browser.close();
})();
// 多浏览器支持(Chromium/Firefox/WebKit)
const { firefox, webkit } = require('playwright');
// Firefox
const ffBrowser = await firefox.launch();
const ffPage = await ffBrowser.newPage();
await ffPage.goto('https://example.com');
await ffPage.pdf({ path: 'firefox.pdf', format: 'A4' });
await ffBrowser.close();
// WebKit
const wkBrowser = await webkit.launch();
const wkPage = await wkBrowser.newPage();
await wkPage.goto('https://example.com');
await wkPage.pdf({ path: 'webkit.pdf', format: 'A4' });
await wkBrowser.close();
// 高级配置
await page.pdf({
path: 'report.pdf',
format: 'A4',
width: '210mm',
height: '297mm',
margin: {
top: '10mm',
right: '10mm',
bottom: '10mm',
left: '10mm'
},
printBackground: true,
displayHeaderFooter: true,
headerTemplate: '报告标题',
footerTemplate: '页码 /',
preferCSSPageSize: true,
landscape: false // 横向模式设为 true
});
// Python 版本
# 安装
pip install playwright
playwright install # 安装浏览器
# Python 代码
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto('https://example.com')
page.pdf(path='output.pdf', format='A4')
browser.close()
# Python 异步版本
import asyncio
from playwright.async_api import async_playwright
async def generate_pdf():
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto('https://example.com')
await page.pdf(path='output.pdf', format='A4')
await browser.close()
asyncio.run(generate_pdf())
Playwright 特点
- 优点 - 支持多浏览器(Chromium/Firefox/WebKit),持续维护,功能强大
- 缺点 - 需要下载浏览器,资源占用较大
- 适用场景 - 复杂网页 PDF 生成,跨浏览器测试,自动化任务
- 对比 Puppeteer - Puppeteer 仅支持 Chromium,但更轻量;Playwright 支持多浏览器更灵活
Pyppeteer - Python 版 Puppeteer
# 安装
pip install pyppeteer
# 基本使用
import asyncio
from pyppeteer import launch
async def generate_pdf():
browser = await launch()
page = await browser.newPage()
await page.goto('https://example.com')
await page.pdf({'path': 'output.pdf', 'format': 'A4'})
await browser.close()
asyncio.get_event_loop().run_until_complete(generate_pdf())
# 高级配置
async def generate_advanced_pdf():
browser = await launch({
'headless': True,
'args': ['--no-sandbox']
})
page = await browser.newPage()
await page.setViewport({'width': 1920, 'height': 1080})
await page.goto('https://example.com', {
'waitUntil': 'networkidle2'
})
await page.pdf({
'path': 'report.pdf',
'format': 'A4',
'width': '210mm',
'height': '297mm',
'margin': {
'top': '10mm',
'right': '10mm',
'bottom': '10mm',
'left': '10mm'
},
'printBackground': True,
'displayHeaderFooter': True,
'headerTemplate': '报告标题',
'footerTemplate': '页码 /',
'preferCSSPageSize': True
})
await browser.close()
asyncio.get_event_loop().run_until_complete(generate_advanced_pdf())
# 截图功能
await page.screenshot({'path': 'screenshot.png', 'fullPage': True})
# 等待元素后再生成
await page.waitForSelector('.content-loaded')
await page.pdf({'path': 'loaded.pdf', 'format': 'A4'})
Pyppeteer 特点
- 优点 - Python 异步 API,Puppeteer 的 Python 移植版,轻量级
- 缺点 - 社区维护版本,更新较慢;官方推荐 playwright-python
- 适用场景 - Python 项目,简单 PDF 生成,快速原型
- 对比 Playwright - Playwright 是官方继任者,功能更强大;Pyppeteer 更轻量但维护较少