You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调试WeasyPrint生成的PDF在主流阅读器损坏无报错问题

问题描述

我尝试用WeasyPrint通过HTML和CSS生成Python报表,整个过程耗时远超预期,还遇到了PDF损坏却找不到原因的问题,具体情况如下:

一开始我以为是Bootstrap冲突,所以所有样式都从零编写,基于官方仓库的代码修改。
我仅在HTML代码中复制部分行、修改ID新增了如下区块:

<article id="execution-results">
    <h2 id="execution-results-title">Execution Results</h2>
</article>

生成的PDF在Firefox中提示this document might not be displayed correctly,内容完全无法阅读;在Adobe Reader中提示There was an error processing a page. There was a problem readin the document(110);仅能在Foxit Reader中正常显示,无法满足多环境兼容需求。

我通过python -m weasyprint .\report.html .\report.pdf --debug开启调试模式,未添加上述代码时的运行日志如下(运行成功但有锚点错误):

INFO: Step 1 - Fetching and parsing HTML - .\report.html
INFO: Step 2 - Fetching and parsing CSS - file:///.../static/styles/report.css
INFO: Step 3 - Applying CSS
INFO: Step 4 - Creating formatting structure
ERROR: Content discarded: target points to undefined anchor "('string', '#execution-results')"
ERROR: Content discarded: target points to undefined anchor "('string', '#execution-results')"
INFO: Step 5 - Creating layout - Page 1
INFO: Step 5 - Creating layout - Page 2
INFO: Step 5 - Creating layout - Page 3
INFO: Step 5 - Creating layout - Page 4
INFO: Step 5 - Creating layout - Page 5
INFO: Step 5 - Creating layout - Page 6
INFO: Step 5 - Creating layout - Page 7
INFO: Step 5 - Creating layout - Repagination #1
INFO: Step 5 - Creating layout - Page 1 (up-to-date)
INFO: Step 5 - Creating layout - Page 2 (up-to-date)
INFO: Step 5 - Creating layout - Page 3
INFO: Step 5 - Creating layout - Page 4 (up-to-date)
INFO: Step 5 - Creating layout - Page 5 (up-to-date)
INFO: Step 5 - Creating layout - Page 6 (up-to-date)
INFO: Step 5 - Creating layout - Page 7 (up-to-date)
INFO: Step 5 - Creating layout - Page 8 (up-to-date)
INFO: Step 6 - Drawing
ERROR: No anchor #execution-results for internal URI reference
ERROR: No anchor #execution-results for internal URI reference
ERROR: No anchor #execution-results for internal URI reference

添加上述代码后运行日志无任何报错,但生成的PDF已损坏,日志如下:

INFO: Step 1 - Fetching and parsing HTML - .\report.html
INFO: Step 2 - Fetching and parsing CSS - file:///C:/.../static/styles/report.css
INFO: Step 3 - Applying CSS
INFO: Step 4 - Creating formatting structure
INFO: Step 5 - Creating layout - Page 1
INFO: Step 5 - Creating layout - Page 2
INFO: Step 5 - Creating layout - Page 3
INFO: Step 5 - Creating layout - Page 4
INFO: Step 5 - Creating layout - Page 5
INFO: Step 5 - Creating layout - Page 6
INFO: Step 5 - Creating layout - Page 7
INFO: Step 5 - Creating layout - Page 8
INFO: Step 5 - Creating layout - Page 9
INFO: Step 5 - Creating layout - Repagination #1
INFO: Step 5 - Creating layout - Page 1 (up-to-date)
INFO: Step 5 - Creating layout - Page 2 (up-to-date)
INFO: Step 5 - Creating layout - Page 3
INFO: Step 5 - Creating layout - Page 4 (up-to-date)
INFO: Step 5 - Creating layout - Page 5 (up-to-date)
INFO: Step 5 - Creating layout - Page 6 (up-to-date)
INFO: Step 5 - Creating layout - Page 7 (up-to-date)
INFO: Step 5 - Creating layout - Page 8 (up-to-date)
INFO: Step 5 - Creating layout - Page 9 (up-to-date)
INFO: Step 6 - Drawing
INFO: Step 7 - Adding PDF metadata

我的HTML本身没有问题,在浏览器开发者工具中检查所有内容正常,控制台无报错,请问该如何调试为何多款PDF阅读器无法打开生成的文件?

更新:我尝试直接使用仓库的示例代码复现问题,发现官方示例生成的PDF也存在该问题,复现步骤如下:

git clone https://github.com/Kozea/WeasyPrint.git
git checkout gh-pages
cd \WeasyPrint\samples\report
python -m weasyprint .\report.html .\report.pdf --debug

用Adobe Acrobat Reader打开生成的PDF会提示:

There was an error porcessing a page. There was a problem reading this document (110).

调试日志仅输出如下内容:

INFO: Step 1 - Fetching and parsing HTML - .\report.html
INFO: Step 2 - Fetching and parsing CSS - file:///...WeasyPrint/samples/report/report.css
WARNING: Ignored `text-decoration: inherit` at 153:11, invalid value.
INFO: Step 3 - Applying CSS
INFO: Step 4 - Creating formatting structure
INFO: Step 5 - Creating layout - Page 1
INFO: Step 5 - Creating layout - Page 2
INFO: Step 5 - Creating layout - Page 3
INFO: Step 5 - Creating layout - Page 4
INFO: Step 5 - Creating layout - Page 5
INFO: Step 5 - Creating layout - Page 6
INFO: Step 5 - Creating layout - Page 7
INFO: Step 5 - Creating layout - Page 8
INFO: Step 5 - Creating layout - Repagination #1
INFO: Step 5 - Creating layout - Page 1 (up-to-date)
INFO: Step 5 - Creating layout - Page 2 (up-to-date)
INFO: Step 5 - Creating layout - Page 3
INFO: Step 5 - Creating layout - Page 4 (up-to-date)
INFO: Step 5 - Creating layout - Page 5 (up-to-date)
INFO: Step 5 - Creating layout - Page 6 (up-to-date)
INFO: Step 5 - Creating layout - Page 7 (up-to-date)
INFO: Step 5 - Creating layout - Page 8 (up-to-date)
INFO: Step 6 - Drawing
INFO: Step 7 - Adding PDF metadata

上述警告不影响运行。我花费1小时逐行注释/取消注释CSS文件,最终定位到问题是由如下样式触发的:

html body article#columns section p:first-of-type {
  font-weight: 700; 
}

修改为如下内容后PDF即可正常打开:

html body article#columns section p:first-of-type {
  font-weight: 200; 
}

现在我需要复制新增一个页面,操作如下:
HTML中新增内容:

<article id="chapter">
  <h2 id="chapter-title">This is a chapter of a new section</h2>
</article>

<!-- 我新增的内容 -->
<article id="chapter-2">
  <h2 id="chapter-2-title">This is a chapter of a new section</h2>
</article>

样式中新增内容:

@page chapter {
  background: #fbc847;
  margin: 0;
  @top-left {
    content: none; 
  }
  @top-center {
    content: none; 
  }
  @top-right {
    content: none; 
  } 
}

/*我新增的内容*/
@page chapter-2 {
  background: #fbc847;
  margin: 0;
  @top-left {
    content: none; 
  }
  @top-center {
    content: none; 
  }
  @top-right {
    content: none; 
  } 
}

html body article#chapter {
  align-items: center;
  display: flex;
  height: 297mm;
  justify-content: center;
  page: chapter; 
}  
/*我新增的内容*/
html body article#chapter-2 {
  align-items: center;
  display: flex;
  height: 297mm;
  justify-content: center;
  page: chapter-2; 
}

操作后PDF再次在Acrobat和Firefox中损坏,但日志中没有任何报错可以辅助排障。请问有没有对开发者更友好的方式可以排查这类问题?


排查方案

第一步:用PDF校验工具直接定位结构错误

WeasyPrint内置日志仅会捕获渲染流程的异常,不会校验最终生成的PDF是否符合规范,用专门的校验工具可以直接拿到具体错误点:

  • 安装qpdf后执行qpdf --check 目标文件.pdf,会输出PDF结构里的所有异常,包括字体嵌入错误、页面对象损坏、资源引用非法这类导致阅读器报错的根因
  • 也可以用poppler工具集的pdftotext尝试转换PDF内容,报错信息会直接指向损坏的页面位置

第二步:针对本次新增@page的场景缩小排查范围

  • 首先删除重复的@page规则:相同配置的页面不需要单独定义chapter-2规则,直接给两个article都设置page: chapter即可,重复的@page规则很容易触发WeasyPrint的页面对象生成bug
  • 注释掉@page的background属性,测试是否是背景色渲染时生成了非法的颜色对象
  • 把article的硬编码高度height:297mm替换为page-break-after: always,避免页面尺寸计算溢出产生异常对象

第三步:通用优化规则避免同类问题

  • 显式声明font-family,不要依赖系统默认字体:之前遇到的font-weight修改解决问题,本质是默认字体缺少对应字重时,WeasyPrint嵌入了非法的字体对象,Adobe这类严格校验的阅读器会直接拒绝加载
  • 尽量用类选择器替代伪类选择器:WeasyPrint对:first-of-type这类伪类的渲染逻辑有未修复的兼容问题,直接给对应元素加类名设置样式更稳定
  • 生成PDF时指定--pdf-version 1.4参数,低版本PDF的兼容性更好,避免高版本特性不被旧版阅读器支持

内容的提问来源于stack exchange,提问作者nck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 20:45:07