使用pypdf 3.7.1生成合并PDF遇静态资源不显示及AttributeError问题求助
问题解决:PDF静态资源不显示及合并时AttributeError错误
一、修复合并PDF时的AttributeError错误
你的代码核心问题是将merger.write()和merger.close()放在了for循环内部,导致第一次循环后就关闭了PdfWriter对象,后续循环调用merger.append()时触发异常。修正后的完整代码如下:
query_set = booklet.objects.filter(booklet_id = id) combine = [] for i in query_set: size = i.size options = { 'page-size': f'{size}', 'orientation': 'Landscape' if i.template_mode == "2" else "Portrait", 'margin-top': '0mm', 'margin-right': '0mm', 'margin-bottom': '0mm', 'margin-left': '0mm', 'encoding': "UTF-8", 'dpi': 900, # 新增:允许wkhtmltopdf访问本地文件资源 'enable-local-file-access': None } # 修正URL参数语法错误:pre{id.id} 改为 pre={id.id} url = f"http://ipaddress/test?ids={get_ids}&uuid={i.uuid}&size={i.size}&mode={i.mode}&type_set={i.te_type}&template={i.name}&pre={id.id}" pdf_path = f"{file_path}/pdfs/{i.te_type}_{i.name}_{i.id}_.pdf" pdfkit.from_url(url, output_path=pdf_path, options=options, verbose=False) combine.append(pdf_path) # 合并逻辑移到循环外部,确保所有PDF都添加完成后再写入关闭 merger = PdfWriter() for pdf_path in combine: merger.append(pdf_path) pdf_name = "base.pdf" merger.write(pdf_name) merger.close() return JsonResponse({"pdf": pdf_name})
二、解决PDF中静态资源(图片、字体)不显示问题
1. 配置wkhtmltopdf访问权限
在pdfkit的options中添加'enable-local-file-access': None,允许工具加载本地文件系统的静态资源,这是解决本地资源无法渲染的关键配置。
2. 修正静态资源路径
- 优先使用绝对URL(如
http://ipaddress/static/images/logo.png)替代相对路径,确保wkhtmltopdf能直接访问到资源。 - 如果使用本地文件路径,必须是完整的绝对路径(如
/var/www/project/static/fonts/custom.ttf),同时确保wkhtmltopdf进程有该路径的读取权限。
3. 嵌入Base64格式资源
如果资源无法通过URL/本地路径访问,可在生成HTML时将图片、字体转成Base64编码嵌入:
<!-- 图片示例 --> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." /> <!-- 字体示例 --> <style> @font-face { font-family: 'CustomFont'; src: url(data:font/ttf;base64,AAEAAAATAQAABAAgR0RFRgAA...) format('truetype'); } </style>
4. 验证单个PDF生成效果
先单独生成单个PDF文件,检查是否能正常显示资源。如果单个PDF也异常,说明问题出在pdfkit/wkhtmltopdf的资源加载环节,而非合并步骤,可进一步排查:
- 确认服务器上的wkhtmltopdf是最新稳定版本,旧版本存在资源渲染兼容性问题;
- 检查目标URL返回的HTML页面是否能在浏览器中正常加载所有资源。
内容的提问来源于stack exchange,提问作者Jaydip Vasoya
相关产品推荐
相关产品推荐

