PDF → EPUB(华为墨水屏版)
把任意多表格 PDF(年报、财报、技术白皮书、说明书等)转成在华为墨水屏设备上
可读、表格不空白、不截断、附注完整的 EPUB。
已在腾讯控股 2025 年报(282 页,241 个表格)上完整跑通并定稿:成书 69 分卷、
约 199KB、48 条附注逐条入目录;正文逐块比对无新增缺失。
0. 一锤定音的核心结论(务必先读)
> 华为 MatePad Paper 的「微信读书墨水屏版」实测完全不渲染 <table> 标签——
> 哪怕没有任何 CSS 的裸表也是空白。手机微信读书支持 <table>,但墨水屏版不支持。
> 因此本技能默认走 pre 模式:用 <pre class="tbl"> 等宽预格式化文本呈现表格,
> 列对齐靠半角空格补齐,全角字符按实际字宽估算。
不确定目标设备是否支持 <table> 时,先跑 make_diag_epub.py 生成 8 变体诊断样本
在真机上确认,不要凭手机端正常就套用 table。
1. 何时使用
- 用户要把 PDF(年报/财报/技术文档)转成在华为墨水屏 / 7–8 英寸电纸书上看的 EPUB。
- 文档含大量无框线表格,普通转换工具要么丢表、要么在墨水屏上整片空白。
- 要求「表格友好、不截断、翻页流畅、附注完整」。
不适用于:纯文字小说(直接用普通 EPUB 工具即可,无需本技能);需要保留彩色图表
且设备支持图片的彩色平板(本技能以文字/表格保真为优先,图片仅作最后回退)。
2. 输入 / 输出规范
输入
| 项 | 说明 |
|---|---|
| 源 PDF | 完整文档(年报须为港交所/交易所披露易的完整年报,不是「全年业绩公布」简版) |
| book.json(可选) | 书籍配置:书名/作者/元数据、章节书签、表格模式、排版参数。缺省走单章 + pre 默认参数 |
| 页码范围(可选) | extract_core.py 支持 [start] [end] 先抽 10–15 页验证质量 |
输出
| 项 | 说明 |
|---|---|
*.epub |
EPUB 3.0,mimetype 首位 STORED,nav.xhtml + toc.ncx 双目录,按字数分小卷(墨水屏翻页不卡) |
排版预览.html |
make_preview.py 生成的本地 HTML,模拟 EPUB 渲染效果,发布前肉眼验收 |
_audit.json |
audit.py 产出:PDF 页覆盖率、XML 合法性、附注完整性等校验结果 |
文件体积参考(以腾讯 2025 年报为例)
- 282 页 / 241 表 / 约 16.7 万字 → 约 199KB / 69 分卷。
- 体积主要来自文字,表格为文本不占多少;若改用 PNG 图片回退会因页数多膨胀到 4–5MB,不推荐。
3. 墨水屏适配与优化目标
| 目标 | 默认做法 | 可调参数 |
|---|---|---|
表格可见(华为墨水屏不支持 <table>) |
默认 pre 等宽文本模式 |
table_mode: "pre" |
| 表格不截断 | 宽表按列数自动拆块;单行超宽自动折行并回上一行消除「孤字行」 | pre_maxw(目标行宽,半角字符数) |
| 表头可定位 | 每 rows_per_block 数据行重复一次表头;表头下 =、分组下 - 分层 |
rows_per_block |
| 字号舒适 | 7.8–8 寸基准 17px;表格 0.92em≈15.6px | base_font_px / pre_font_em |
| 翻页流畅 | 按字数小分卷(默认 ~9000 字/卷,硬上限 18000) | chunk_target_chars / hard_max_chars |
| 附注完整 | 附注章按「附注编号」标题无条件切卷,逐条入目录 | note_chapters |
| 繁→简 | 自动 t2s(OpenCC),正文与表格均转 | 依赖 opencc 包 |
| 层级清晰 | 按 PDF 原始字号阈值识别 h1/h2/h3/footnote | heading |
4. 环境依赖
PY="C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe"
# 所需包(装到隔离 venv,勿全局):
$PY -m pip install pdfplumber opencc pypdf 2>/dev/null
# 如缺 pypdf,build_epub 会回退到内置解析,不影响主流程
5. 快速开始
PY="C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe"
SK="C:/Users/Administrator/.workbuddy/skills/PDF转EPUB(华为墨水屏版)/scripts"
cd <工作目录>
# 1) 先抽 10–15 页验证提取质量(别一上来跑全本)
$PY $SK/extract_core.py report.pdf 3 18 _probe.json
$PY $SK/preview.py _probe.json 200 # 肉眼看文本/表格是否被正确切分
# 2) 某页列对齐可疑时,诊断该页列边界(页码为 0-based)
$PY $SK/diag.py report.pdf 131
# 3) 全本提取
$PY $SK/extract_core.py report.pdf 0 999999 blocks_full.json
# 4) 生成 EPUB(传入 book.json;省略则用默认单章参数)
$PY $SK/build_epub.py blocks_full.json 输出.epub $SK/../references/book.腾讯2025年报.json
# 5) 生成 HTML 预览,在浏览器验收排版
$PY $SK/make_preview.py blocks_full.json 排版预览.html $SK/../references/book.腾讯2025年报.json pre
# 6) 校验(覆盖率 / XML 合法性 / 附注完整性)
$PY $SK/audit.py report.pdf blocks_full.json _audit.json 2 281
6. book.json 配置参考
完整模板见 references/book.example.json,腾讯年报实例如 references/book.腾讯2025年报.json。
{
"title": "书名",
"creator": "作者/公司",
"publisher": "来源",
"date": "2026-04-09",
"language": "zh-CN",
// 表格渲染:华为墨水屏务必 "pre";仅当确认设备支持 table 才用 "table"
"table_mode": "pre",
"pre_maxw": 104, // pre 模式目标最大行宽(半角单位),须与 pretable 同步
"rows_per_block": 18, // 每多少数据行重复一次表头
// 排版(7.8–8 英寸基准;6 寸改为 15px)
"base_font_px": 17,
"pre_font_em": 0.92, // 0.92*17 ≈ 15.6px
"pre_line_height": 1.5,
"body_line_height": 1.62,
// 章节书签:[[章名, PDF起始页(1-based)], ...];章名可用繁体(自动转简)
"books": [
["封面", 1], ["目錄", 2], ["財務概要", 4], ["綜合財務報表附註", 141], ["封底", 282]
],
"skip_chapters": ["封面", "目錄", "封底"], // 不收进书
"note_chapters": ["綜合財務報表附註"], // 按附注编号无条件切卷
"heading": {"h1": 16.0, "h2": 11.6, "h3": 10.5, "footnote": 9.0},
"chunk_target_chars": 9000,
"hard_max_chars": 18000,
"min_sec_chars": 400
}
如何获取章节起始页:先 extract_core.py 全本 → preview.py 打印每页首行与字号,
或用 diag.py 看页宽;按「章名首次出现页」填 books。
7. 参数调优指南(真机实测后微调)
- 字号偏小/偏大:改
base_font_px(7.8–8 寸 17,6 寸 15,10 寸 19–20);
表格字号跟pre_font_em等比。 - 表格列歪(中文列对不齐):根因是系统中文全角/半角字宽比≠2.0(实测雅黑 3.64、等线 4.44)。
先跑make_diag2_epub.py看真机等宽字体表现;若仍歪,优先保证pre_maxw留足余量(104),
必要时把中文列做全角化对齐。 - 表格行太挤/太松:调
pre_line_height(1.4–1.6)。 - 表头重复太频繁/太稀:调
rows_per_block(14–24)。 - 翻页卡顿:调小
chunk_target_chars(如 6000)。 - 宽表被过度拆块:适当增大
pre_maxw(≤110,超过易触发横向滚动)。
8. 若表格全白:诊断流程
- 确认设备客户端:华为「微信读书墨水屏版」不支持
<table>→ 必须用pre模式(本技能默认)。 - 跑
make_diag_epub.py生成 A–H 八变体诊断样本,在真机确认哪种可见(经验:仅<pre>可见)。 - 跑
make_diag2_epub.py第二轮诊断:含等宽字体对比 + 视口标尺,定位字宽比问题。 - 若连
<pre>都白:检查是否被外部 CSS / 背景色 /white-space覆盖;本技能内联 CSS 已规避。
9. 校验清单(交付前必做)
- [ ]
audit.py报告:PDF 页覆盖率 ≈ 100%(除主动 skip 的封面/目录/封底)。 - [ ] XML 零错误(EPUB 容器与各 xhtml 良构)。
- [ ] 繁体残留 = 0(t2s 生效)。
- [ ] 附注逐条入目录(
note_chapters生效)。 - [ ] 关键表格在 HTML 预览 + 真机均可见、不截断、表头可定位。
- [ ] 体积合理(文字为主,远小于 PNG 回退方案)。
10. 局限与注意事项
- 图片/彩色图表:默认不转图,仅当表格真无法文本化时才考虑 PNG 回退(体积极速膨胀,且不能缩放/选中)。
- 扫描版 PDF(无文本层):需先 OCR,本技能不内置;pdfplumber 提取为空时先处理源。
- 中文字宽估算:依赖系统等宽假设,极端字体下可能微歪;以真机为准微调
pre_maxw。 - Kindle 推送:EPUB 经邮箱推送会自动转 AZW3,无需本地 Calibre。
- 不要在
pre_maxw与pretable.MAXW_DEFAULT两处分别改值——须保持同步(build_epub 已读取同一常量路径)。
11. 脚本清单
scripts/
- extract_core.py — PDF → blocks JSON(文本块 + 表格块,含列边界聚类)
- preview.py — blocks JSON → 可读文本,人工检查提取质量
- diag.py — 单页列边界 / 每行属性诊断(调试用)
- pretable.py — 表格 → 等宽文本(核心渲染逻辑,含折行/孤字行/跨列占位修复)
- build_epub.py — blocks JSON + book.json → EPUB(默认 pre 模式,已做 t2s、分卷、双目录)
- audit.py — 覆盖率 / XML / 附注完整性校验
- make_preview.py — blocks JSON + book.json → 模拟渲染的 HTML 预览
- make_diag_epub.py — 8 变体表格渲染诊断样本(排查空白)
- make_diag2_epub.py — 等宽字体 + 视口标尺第二轮诊断
references/
- book.example.json — 配置模板
- book.腾讯2025年报.json — 腾讯 2025 年报实配(可直接套用同类港股年报)