使用FPDF调用AWS S3存储桶图片生成PDF提示找不到文件如何解决?
问题产生原因
- FPDF的
image()方法默认仅支持读取本地文件系统的资源,你传入的是S3存储桶的虚拟路径,不属于本地存在的文件路径,因此触发文件不存在报错。 - 你没有提前将S3上的图片资源下载到本地或者加载为内存流,FPDF无法直接解析S3远程路径对应的资源内容。
解决方法
你可以选择以下两种方案解决,推荐优先使用内存流方案,不需要写入本地磁盘,效率更高。
前置依赖
首先安装AWS Python SDK和相关依赖:
pip install boto3 fpdf2 pillow
注意fpdf2是FPDF的官方维护版本,支持直接传入内存流对象,避免旧版本兼容性问题。
方案1:内存流读取(推荐)
直接把S3图片读取到内存,不需要生成本地临时文件:
import fpdf import boto3 import io # 初始化S3客户端,确保运行环境已经配置AWS访问权限 s3 = boto3.client('s3') bucket_name = "替换为你的S3桶名称" bucket_folder_name = "替换为桶内文件夹路径" file_name = "替换为你的图片文件名" # 原有PDF初始化逻辑 pdf = FPDF() pdf.add_page() pdf.set_font('Arial', 'B', 16) pdf.cell(175, 10, 'TEST - report',0,1,'C') # 从S3读取图片到内存流 s3_res = s3.get_object( Bucket=bucket_name, Key=f"{bucket_folder_name}/{file_name}.png" ) img_stream = io.BytesIO(s3_res['Body'].read()) # 直接传入内存流生成PDF pdf.image(img_stream)
方案2:临时文件下载
如果需要保留本地图片备份,可以选择先下载到本地临时目录再调用:
import fpdf import boto3 import tempfile import os s3 = boto3.client('s3') bucket_name = "替换为你的S3桶名称" bucket_folder_name = "替换为桶内文件夹路径" file_name = "替换为你的图片文件名" pdf = FPDF() pdf.add_page() pdf.set_font('Arial', 'B', 16) pdf.cell(175, 10, 'TEST - report',0,1,'C') # 创建临时文件存储S3下载的图片 with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp: s3.download_fileobj( Bucket=bucket_name, Key=f"{bucket_folder_name}/{file_name}.png", Fileobj=tmp ) tmp_path = tmp.name pdf.image(tmp_path) # 使用完成后删除临时文件 os.remove(tmp_path)
注意事项
- 确保运行代码的环境有对应S3存储桶的读取权限,可通过配置环境变量
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY,或者给云服务实例绑定对应权限的IAM角色实现。 - 如果使用旧版PyFPDF不支持内存流,升级到最新版
fpdf2即可。
内容的提问来源于stack exchange,提问作者sdom
相关产品推荐
相关产品推荐

