← 返回首页

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();
需求场景PythonGolangJavaScript
文本提取pypdfunipdfpdf.js
创建 PDFreportlabgofpdfpdf-lib
表格生成reportlabunipdfpdfkit
图表绘制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 更轻量但维护较少