ReportLab生成PDF中文乱码需注册中文字体并指定字体名,避免直接用drawString;WeasyPrint需用CSS 2.1子集、绝对路径或base64图片;同步生成PDF超时应改用Celery异步或预生成缓存。

ReportLab生成PDF时中文乱码怎么解决
ReportLab默认不支持中文字体,直接写中文会变成方块或报错 UnicodeEncodeError。核心是显式注册字体并使用 Paragraph 或 SimpleDocTemplate 配合 getSampleStyleSheet() 改写样式。
- 把系统中已有的中文字体(如
NotoSansCJKsc-Regular.ttf或 Windows 的simhei.ttf)复制到项目目录,比如static/fonts/ - 在生成 PDF 前调用
pdfmetrics.registerFont(TTFont('SimHei', 'static/fonts/simhei.ttf')) - 所有
Paragraph必须指定style.fontName = 'SimHei';若用Table,需为每个Paragraph单独设字体,不能只改全局样式表 - 避免用
canvas.drawString()直接写中文——它不走字体注册流程,必须换用canvas.setFont('SimHei', 12)再画
WeasyPrint渲染Django模板成PDF时CSS不生效
WeasyPrint对CSS的支持有限,尤其是 flex、grid、@media print 等现代特性基本忽略,且不执行JavaScript。常见现象是页面在浏览器里正常,导出后排版错乱、字体丢失、背景图消失。
- 只用 CSS 2.1 子集:优先用
float、display: table-cell布局,禁用position: sticky和transform - 字体必须内联或通过
@font-face加载本地路径(如src: url('../static/fonts/NotoSansCJKsc-Regular.woff2')),且文件路径要相对于调用HTML(string=...)或HTML(filename=...)的位置 - 图片路径务必用绝对路径(
file:///full/path/to/image.png)或转为 base64 内嵌,相对路径在 WeasyPrint 中几乎总失败 - 调试时加
presentational_hints=True参数,让 HTML 的align、bgcolor等属性也参与渲染
Django视图中同步生成PDF导致请求超时怎么办
PDF生成(尤其含图表、大量表格或高分辨率图片时)可能耗时数秒,Django 同步视图会阻塞整个 worker 进程,用户看到白屏或 504 错误。
强戈环形山: q15040409-刻画家功能概述强戈环形山: q15040409-刻画家是一项面向实际任务的技能,主要用于平顶山: 维西翁: 1:1.0. 塔格斯: rap.github: 自动化。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。核心要点使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。从功能定位来看,该
- 简单场景:用
StreamingHttpResponse+BytesIO流式返回,避免内存堆积,但不解决耗时问题 - 中等负载:将 PDF 生成逻辑移到 Celery 异步任务,视图立即返回任务 ID,前端轮询
/api/pdf-status/?task_id=xxx获取结果 URL - 高频报表:预生成并缓存(如按日/周生成,存入
default_storage),URL 直接指向FileResponse,避免重复计算 - 别在
__str__或save()里触发 PDF 生成——容易引发事务锁或递归调用
ReportLab和WeasyPrint选型关键差异点
ReportLab 更适合结构固定、数据密集的报表(如发票、对账单);WeasyPrint 更适合样式复杂、需复用现有 HTML/CSS 的场景(如营销页导出),但二者在 Django 中集成成本和稳定性差异明显。
- ReportLab 无外部依赖,纯 Python,部署简单;WeasyPrint 依赖 Cairo、Pango、HarfBuzz,Linux 上常因系统库版本不兼容报
Library not loaded错误 - ReportLab 表格支持强(
Table,LongTable,Platypus),但写 CSS 等价样式要手动算列宽;WeasyPrint 天然支持 CSS 表格,但跨页分页控制弱(page-break-inside: avoid不总生效) - WeasyPrint 支持
@page规则(页眉页脚),ReportLab 需重写PageTemplate的beforeDrawPage回调,代码量翻倍 - 调试难度:ReportLab 错误信息模糊(常报
IndexError而非具体哪行 Table 数据异常);WeasyPrint 日志可读性高,但错误常卡在底层 C 库,堆栈难定位
真正麻烦的是混合内容——比如用 WeasyPrint 渲染主体,再用 ReportLab 插入动态生成的折线图(matplotlib 输出的 PNG)。这种组合方案得手动对齐 DPI、页边距和字体大小,很容易在不同环境出现 1px 偏移或换页错位。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










