FPDF生成PDF上传S3报错:临时文件不存在,求解决方案
解决PDF输出时临时文件目录不存在的报错问题
问题描述
报错信息:
No such file or directory: '/tmp/tmpnj0aocz9'
执行代码中pdf_content = pdf.output(dest='S').encode('latin1')时崩溃,原因是PDF库的output方法错误地尝试写入不存在的临时目录,尽管代码已经手动创建了临时文件。
问题分析
- 你使用
tempfile.NamedTemporaryFile创建了临时文件,但pdf.output(dest='S')的设计是直接返回PDF内容字符串,本不应涉及文件存储; - 部分PDF生成库(如ReportLab)可能存在参数兼容问题,或者环境中
/tmp目录未创建/无权限访问,导致output方法内部触发文件写入逻辑失败; - 原代码存在冗余操作:先创建临时文件,再生成内容写入,最后又重新打开文件上传,可优化为直接上传字节流。
解决方案
方案1:直接上传PDF字节流(推荐)
跳过临时文件,直接将output生成的字节内容上传到S3,彻底绕开本地文件操作:
def save_pdf_to_s3(pdf, pdf_type, s3_bucket, s3_bucket_path): s3 = boto3.client('s3') try: # 生成PDF字节内容 pdf_content = pdf.output(dest='S').encode('latin1') # 直接上传字节流至S3 s3.put_object( Key=f'{s3_bucket_path}/{pdf_type}.pdf', Body=pdf_content, Bucket=s3_bucket ) print("PDF saved to S3") except Exception as e: print(f"上传失败: {str(e)}")
方案2:确保临时目录可用并正确管理临时文件
如果必须使用临时文件,先检查并创建临时目录,同时规范文件操作流程:
import os import tempfile import boto3 def save_pdf_to_s3(pdf, pdf_type, s3_bucket, s3_bucket_path): s3 = boto3.client('s3') # 确保临时目录存在并可访问 temp_dir = '/tmp' if not os.path.exists(temp_dir): os.makedirs(temp_dir, exist_ok=True) temp_file_path = None try: # 在指定目录创建临时文件 with tempfile.NamedTemporaryFile(dir=temp_dir, delete=False) as temp_file: temp_file_path = temp_file.name # 写入PDF内容 pdf_content = pdf.output(dest='S').encode('latin1') temp_file.write(pdf_content) # 上传临时文件至S3 with open(temp_file_path, 'rb') as f: s3.put_object( Key=f'{s3_bucket_path}/{pdf_type}.pdf', Body=f, Bucket=s3_bucket ) print("PDF saved to S3") finally: # 清理临时文件 if temp_file_path and os.path.exists(temp_file_path): os.unlink(temp_file_path)
补充说明
- 方案1减少了本地IO操作,性能更优,适合绝大多数场景;
- 若使用的PDF库存在
dest='S'参数失效问题,建议升级库版本或查阅官方文档确认参数用法; - 部分服务器环境可能限制
/tmp目录权限,可替换为其他有权限的目录作为临时存储。
内容的提问来源于stack exchange,提问作者jvm
相关产品推荐
相关产品推荐

