Odoo 16批量打印3份及以上文档触发PyPDF2读取空文件错误求助
Odoo 16批量打印3份及以上文档触发PyPDF2空文件错误的原因分析
问题现象
单份文档打印/下载功能正常,但打印3份及以上文档时触发以下错误:
PyPDF2.utils.PdfReadError: Cannot read an empty file
涉及代码
def print_receituario(self): report = self.env.ref("dental_clinic.action_dental_prescription_report", False) dental_record = self.dental_record_id patient = self.dental_record_id.patient_id if not (len(dental_record) == 1): return if len(self) == 1: report_name = safe_eval(report.print_report_name, {"object": self}) else: report_name = f"Receituário - {patient.name}" pdf_content, _ = ( self.env["ir.actions.report"] .with_context(lang=patient.lang) .sudo() ._render_qweb_pdf(report.id, self.ids, data={"company_id": self.env.company}) ) attachment = self.env["ir.attachment"].create( { "name": report_name, "res_model": "dental.record", "res_id": dental_record.id, "datas": base64.b64encode(pdf_content), } ) return {"type": "ir.actions.act_url", "url": f"/web/content/{attachment.id}"}
错误原因解析
批量PDF合并的空内容触发异常
Odoo的_render_qweb_pdf处理多记录打印时,会先为每条记录单独生成PDF,再通过PyPDF2合并成一个文件。如果其中某一条记录的PDF渲染结果为空(字节长度为0),PyPDF2在读取该空文件时就会抛出Cannot read an empty file错误。多记录场景下的数据一致性问题
- 代码中
dental_record = self.dental_record_id在批量选中多记录时,self是记录集合,dental_record_id会返回多条关联记录,此时len(dental_record) == 1的判断会直接返回;但若选中的记录数刚好是3条且其中部分记录的dental_record_id为空,后续渲染时会生成空PDF。 - 批量场景下
patient = self.dental_record_id.patient_id同样存在集合取值问题,patient.lang可能取到第一条记录的语言,导致后续记录渲染时因语言不匹配或数据缺失生成空内容。
附件创建的逻辑缺陷
批量打印时,res_id = dental_record.id只会取集合中第一条记录的ID,后续记录的PDF无法正确关联到对应dental_record,可能触发渲染时的数据查询异常,生成空PDF。批量场景下的报表名称解析问题
safe_eval(report.print_report_name, {"object": self})在self为多记录集合时,safe_eval无法正确解析单对象的命名规则,可能导致报表名称生成失败,间接引发PDF渲染异常。
验证方向
- 检查批量选中的3条及以上记录,确认是否存在
dental_record_id为空或关联记录已删除的情况。 - 单独打印报错批次中的每一条记录,排查是否有单条记录本身无法生成PDF的情况。
- 在
_render_qweb_pdf后添加print(len(pdf_content)),确认是否存在返回0的空内容情况。
内容的提问来源于stack exchange,提问作者A C
相关产品推荐
相关产品推荐

