You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ReportLab将Matplotlib绘图插入PDF并生成下载链接?

解决ReportLab插入Matplotlib绘图到PDF的问题

问题根源

原代码存在几个关键错误导致无法插入绘图:

  • 重复调用pdf.build(),第二次调用会完全覆盖第一次生成的内容,最终PDF只会保留最后一次build的元素
  • Matplotlib的fig对象无法直接作为ReportLab的可流动元素,必须先转换为ReportLab支持的Image格式
  • 缺失必要的库导入语句,代码无法正常运行
  • 不必要地将图形保存为本地PDF文件,既浪费资源又不符合内存流处理的需求

修正后的完整代码

from io import BytesIO
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Image, Table
import base64
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import HTML, display

# 创建示例DataFrame
data = {'Name': ['John', 'Jane', 'Bob'], 'Age': [30, 25, 40], 'Gender': ['M', 'F', 'M']}
df = pd.DataFrame(data)

# 创建PDF内存缓冲区
buffer = BytesIO()
pdf = SimpleDocTemplate(buffer, pagesize=letter)

# 生成ReportLab表格
table_data = [df.columns.tolist()] + df.values.tolist()
table = Table(table_data)

# 生成Matplotlib图形并转为内存图片流
fig, ax = plt.subplots()
ax.plot(df['Name'], df['Age'])  # 修正绘图逻辑,用Name对应Age生成有意义的折线图
# 将图形保存到BytesIO,格式选PNG(ReportLab支持)
img_buffer = BytesIO()
plt.savefig(img_buffer, format='png')
img_buffer.seek(0)
plt.close(fig)  # 关闭图形释放内存

# 创建ReportLab Image对象,设置合适的尺寸
rl_img = Image(img_buffer, width=400, height=300)

# 将表格和图片放入同一个元素列表,一次性生成PDF
elements = [table, rl_img]
pdf.build(elements)

# 重置缓冲区指针到起始位置
buffer.seek(0)

# 编码为base64生成下载链接
b64 = base64.b64encode(buffer.getvalue()).decode()
link = '<a href="data:application/pdf;base64,{0}" download="dataframe_report.pdf">右键点击 -> 另存为 下载PDF</a>'.format(b64)

# 显示下载链接
display(HTML(link))

关键修正说明

  • 补充了pandas、matplotlib.pyplot、Table的导入语句,确保代码可运行
  • 将Matplotlib图形保存到内存BytesIO流,而非本地文件,再转为ReportLab的Image对象
  • 把表格和图片放入同一个elements列表,仅调用一次pdf.build(),确保所有内容都被加入PDF
  • 修正了绘图逻辑,使用Name对应Age数据生成有意义的折线图
  • 关闭Matplotlib图形释放内存,避免在线环境中的资源泄漏

内容的提问来源于stack exchange,提问作者Amber Nagel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:39:58