2025-11-10
Python
00

目录

🔍 问题分析
为什么选择Python生成PDF?
常见的PDF生成需求
💡 解决方案
🛠️ 主流PDF生成库对比
💻 代码实战
🔧 环境准备
📄 方案一:使用reportlab生成复杂PDF
基础文档生成
数据表格PDF生成
图表集成PDF生成
🎯 结尾总结

在日常的Python开发工作中,我们经常需要将数据、报告或者图表导出为PDF格式。无论是生成财务报表、用户证书、还是系统日志,PDF作为一种通用的文档格式,具有跨平台兼容性好、格式稳定的优势。

本文将从实际项目需求出发,详细介绍如何使用Python生成PDF文档。我们将涵盖从简单的文本PDF到复杂的图表报告生成,帮助你掌握Python PDF生成的核心技术和实战技巧。无论你是刚接触Python开发的新手,还是需要在上位机开发中集成PDF功能的资深开发者,这篇文章都将为你提供实用的解决方案。

🔍 问题分析

为什么选择Python生成PDF?

在Windows开发环境中,Python生成PDF有以下几个显著优势:

  1. 生态丰富:Python拥有多个成熟的PDF处理库
  2. 跨平台兼容:生成的PDF可以在任何设备上正常显示
  3. 自动化程度高:可以批量生成,无需人工干预
  4. 集成性强:可以轻松与数据库、Web框架结合

常见的PDF生成需求

  • 报告生成:将数据分析结果导出为PDF报告
  • 证书制作:批量生成用户证书或凭证
  • 发票开具:自动生成标准格式的发票
  • 文档转换:将HTML、Markdown等格式转换为PDF

💡 解决方案

🛠️ 主流PDF生成库对比

库名特点适用场景
reportlab功能强大,支持复杂布局复杂报告、图表生成
fpdf轻量级,易于学习简单文档生成
weasyprint支持HTML/CSS转PDF网页内容转换
pdfkit基于wkhtmltopdfHTML模板转PDF

本文将重点介绍reportlabfpdf两个库的使用方法。

💻 代码实战

🔧 环境准备

首先安装必要的依赖包:

Bash
pip install reportlab pillow matplotlib

📄 方案一:使用reportlab生成复杂PDF

reportlab是Python中最强大的PDF生成库,特别适合创建复杂的文档布局。

基础文档生成

Python
from reportlab.lib.pagesizes import A4 from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib import colors from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase import pdfmetrics from datetime import datetime import os def create_basic_pdf(): # 微软雅黑在 Windows 系统一般的路径如下: font_path = r"C:\Windows\Fonts\msyh.ttc" # .ttf 或 .ttc 结尾都可,ttc表示字体集 # 注册字体(ttc文件需指定字体索引,.ttf不用) pdfmetrics.registerFont(TTFont("MSYH", font_path)) doc = SimpleDocTemplate("basic_report_msyh.pdf", pagesize=A4) styles = getSampleStyleSheet() title_style = ParagraphStyle( 'CustomTitle', parent=styles['Heading1'], fontName="MSYH", fontSize=24, textColor=colors.darkblue, alignment=1, ) normal_style = ParagraphStyle( 'Normal_CN', parent=styles['Normal'], fontName="MSYH", fontSize=12, ) content = [] content.append(Paragraph("Python PDF生成报告", title_style)) content.append(Spacer(1, 20)) content.append(Paragraph( f"生成日期:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", normal_style )) content.append(Spacer(1, 15)) body_text = """ 这是一个使用Python reportlab库生成的PDF文档示例。 通过Python编程技巧,我们可以轻松地创建专业的PDF报告。 这种方法特别适合在上位机开发中自动生成各种文档。 """ content.append(Paragraph(body_text, normal_style)) doc.build(content) print("✅ 基础PDF生成成功:basic_report_msyh.pdf") create_basic_pdf()

image.png

数据表格PDF生成

Python
def register_chinese_fonts(): """注册中文字体""" # Windows系统字体路径 font_paths = [ r'C:\Windows\Fonts\simhei.ttf', # 黑体 r'C:\Windows\Fonts\simsun.ttc', # 宋体 r'C:\Windows\Fonts\msyh.ttc', # 微软雅黑 ] for font_path in font_paths: if os.path.exists(font_path): try: if 'simhei' in font_path: pdfmetrics.registerFont(TTFont('SimHei', font_path)) return 'SimHei' elif 'simsun' in font_path: pdfmetrics.registerFont(TTFont('SimSun', font_path)) return 'SimSun' elif 'msyh' in font_path: pdfmetrics.registerFont(TTFont('Microsoft-YaHei', font_path)) return 'Microsoft-YaHei' except: continue # 如果系统字体不可用,使用在线字体 print("⚠️ 系统字体不可用,建议手动下载中文字体") return None def create_table_pdf(): """创建包含表格的PDF文档""" # 注册中文字体 chinese_font = register_chinese_fonts() if not chinese_font: chinese_font = 'Helvetica' # 降级到默认字体 doc = SimpleDocTemplate("table_report.pdf", pagesize=A4) styles = getSampleStyleSheet() content = [] # 创建自定义样式支持中文 from reportlab.lib.styles import ParagraphStyle chinese_title_style = ParagraphStyle( 'ChineseTitle', parent=styles['Title'], fontName=chinese_font, fontSize=16, alignment=1, # 居中 ) # 标题 title = Paragraph("销售数据报表", chinese_title_style) content.append(title) content.append(Spacer(1, 0.3 * inch)) # 模拟数据 data = [ ['产品名称', '销售数量', '单价(元)', '总金额(元)'], ['iPhone 14', '120', '6999', '839,880'], ['MacBook Pro', '85', '12999', '1,104,915'], ['iPad Air', '200', '4599', '919,800'], ['AirPods Pro', '300', '1999', '599,700'], ['', '', '合计:', '3,464,295'] ] # 创建表格 table = Table(data, colWidths=[2 * inch, 1 * inch, 1 * inch, 1.5 * inch]) # 设置表格样式 table.setStyle(TableStyle([ # 表头样式 ('BACKGROUND', (0, 0), (-1, 0), colors.darkblue), ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('FONTNAME', (0, 0), (-1, 0), chinese_font), # 使用中文字体 ('FONTSIZE', (0, 0), (-1, 0), 12), # 数据行样式 ('BACKGROUND', (0, 1), (-1, -2), colors.beige), ('FONTNAME', (0, 1), (-1, -1), chinese_font), # 使用中文字体 ('FONTSIZE', (0, 1), (-1, -1), 10), # 合计行样式 ('BACKGROUND', (0, -1), (-1, -1), colors.lightgrey), ('FONTNAME', (0, -1), (-1, -1), chinese_font), # 使用中文字体 # 边框 ('GRID', (0, 0), (-1, -1), 1, colors.black), ('LINEBELOW', (0, 0), (-1, 0), 2, colors.darkblue), ])) content.append(table) # 构建PDF doc.build(content) print("✅ 表格PDF生成成功:table_report.pdf")

图表集成PDF生成

Python
import matplotlib.pyplot as plt import matplotlib from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import inch from reportlab.platypus.para import Paragraph from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont import os matplotlib.use('Agg') # 使用非交互式后端 from reportlab.platypus import Image, SimpleDocTemplate, Spacer import io def setup_chinese_fonts(): """设置中文字体""" # 设置matplotlib中文字体 plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题 # 设置ReportLab中文字体 font_paths = [ r'C:\Windows\Fonts\simhei.ttf', # 黑体 r'C:\Windows\Fonts\msyh.ttc', # 微软雅黑 r'C:\Windows\Fonts\simsun.ttc', # 宋体 ] for font_path in font_paths: if os.path.exists(font_path): try: if 'simhei' in font_path: pdfmetrics.registerFont(TTFont('SimHei', font_path)) return 'SimHei' elif 'msyh' in font_path: pdfmetrics.registerFont(TTFont('Microsoft-YaHei', font_path)) return 'Microsoft-YaHei' elif 'simsun' in font_path: pdfmetrics.registerFont(TTFont('SimSun', font_path)) return 'SimSun' except: continue return 'Helvetica' # 如果没有找到中文字体,返回默认字体 def create_chart_pdf(): """创建包含图表的PDF文档""" # 设置中文字体 chinese_font = setup_chinese_fonts() doc = SimpleDocTemplate("chart_report.pdf", pagesize=A4) styles = getSampleStyleSheet() content = [] # 创建支持中文的样式 chinese_title_style = ParagraphStyle( 'ChineseTitle', parent=styles['Title'], fontName=chinese_font, fontSize=16, alignment=1, # 居中 ) chinese_normal_style = ParagraphStyle( 'ChineseNormal', parent=styles['Normal'], fontName=chinese_font, fontSize=12, leading=16, # 行间距 ) # 标题 title = Paragraph("数据分析图表报告", chinese_title_style) content.append(title) content.append(Spacer(1, 0.3 * inch)) # 生成matplotlib图表 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4)) # 柱状图 products = ['iPhone', 'MacBook', 'iPad', 'AirPods'] sales = [120, 85, 200, 300] ax1.bar(products, sales, color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4']) ax1.set_title('产品销售数量') ax1.set_ylabel('销售数量') # 设置x轴标签旋转,避免重叠 ax1.tick_params(axis='x', rotation=45) # 饼图 sizes = [25, 30, 20, 25] colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'] ax2.pie(sizes, labels=products, colors=colors, autopct='%1.1f%%') ax2.set_title('市场份额分布') plt.tight_layout() # 保存图表到内存 img_buffer = io.BytesIO() plt.savefig(img_buffer, format='png', dpi=300, bbox_inches='tight') img_buffer.seek(0) plt.close() # 将图表添加到PDF img = Image(img_buffer, width=6 * inch, height=2.4 * inch) content.append(img) content.append(Spacer(1, 0.3 * inch)) # 添加分析说明 - 使用正确的HTML标签 analysis_lines = [ "<b>数据分析总结:</b>", "1. AirPods产品销量最高,达到300件", "2. MacBook销量相对较低,但单价较高", "3. 各产品市场份额分布相对均衡", "4. 建议加强MacBook的市场推广" ] # 为每行创建单独的段落 for line in analysis_lines: analysis_para = Paragraph(line, chinese_normal_style) content.append(analysis_para) content.append(Spacer(1, 0.1 * inch)) # 构建PDF doc.build(content) print("✅ 图表PDF生成成功:chart_report.pdf") if __name__ == "__main__": create_chart_pdf()

image.png

🎯 结尾总结

通过本文的详细介绍,我们掌握了Python生成PDF的核心技术和实战技巧。让我们来总结三个关键要点:

1. 选择合适的工具库:根据项目需求选择reportlab(复杂文档),合理的工具选择是成功的一半。

2. 注重代码结构设计:通过模块化设计、异常处理和性能优化,确保生成的PDF既稳定又高效,这在上位机开发中尤为重要。

3. 掌握实用技巧:从基础的文本PDF到复杂的图表报告,再到批量生成和中文支持,这些编程技巧将大大提升你的开发效率。

Python PDF生成技术在实际项目中应用广泛,掌握这些技能将让你在Python开发的道路上更加游刃有余。建议大家在实际项目中多加练习,结合具体业务需求来优化代码结构。

如果你在实际应用中遇到问题,欢迎在评论区分享交流。让我们一起在Python开发的路上不断进步!


本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!