从各处收来的 EPUB,书名张冠李戴、作者留着转换工具的名字、封面缺失、同一系列的分册散落在书架各处——这些都存在同一个地方:包内 OPF 文件的 <metadata> 段。
用 EPUB 元数据编辑 改起来只是填表单,但改完发现阅读器不认的情况非常常见。这篇按”元数据存在哪 → 为什么不生效 → 非破坏式怎么保证正文不坏”讲清楚。
各阅读器对具体字段的支持情况截至 2026-07-28,软件更新后可能变化;判断是否真的写入成功,永远以解包后 OPF 文件里的实际内容为准。
元数据存在 OPF 的一段 XML 里
解开 EPUB(改名 .zip),META-INF/container.xml 指向的那个 .opf 文件里,头部是这样:
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:identifier id="bookid">urn:uuid:8f3a...</dc:identifier>
<dc:title>三体</dc:title>
<dc:creator>刘慈欣</dc:creator>
<dc:language>zh-Hans</dc:language>
<dc:publisher>重庆出版社</dc:publisher>
<dc:date>2008-01-01</dc:date>
<dc:subject>科幻</dc:subject>
<dc:subject>长篇小说</dc:subject>
<meta name="calibre:series" content="地球往事"/>
<meta name="calibre:series_index" content="1"/>
<meta property="dcterms:modified">2026-07-28T10:00:00Z</meta>
<meta name="cover" content="cover-image"/>
</metadata>
两类元素:dc:* 是 Dublin Core 标准字段(书名、作者、语言这些),<meta> 是扩展字段(系列、封面指针、修改时间)。扩展字段没有统一标准,这是所有兼容性问题的根源。
| 表单栏位 | 实际写入 |
|---|---|
| 书名 / 作者 / 出版社 / 出版日期 / 语言 | dc:title / dc:creator / dc:publisher / dc:date / dc:language |
| 标签(多个) | 多个 dc:subject |
| 简介 / 版权 | dc:description / dc:rights |
| 标识符 / ISBN | dc:identifier |
| 系列 + 序号 | 两套 <meta>,见下 |
| 封面 | 图片字节 + manifest 项 + 两处标记 |
系列:必须写两套字段
这是最容易”填了没反应”的一栏,因为历史上有两套做法:
Calibre 系(EPUB2 风格自定义 meta)
<meta name="calibre:series" content="地球往事"/>
<meta name="calibre:series_index" content="1"/>
EPUB3 官方写法(带 refines 的属性链)
<meta property="belongs-to-collection" id="c1">地球往事</meta>
<meta refines="#c1" property="collection-type">series</meta>
<meta refines="#c1" property="group-position">1</meta>
各家读哪套:
| 阅读器 / 软件 | 读取的字段 |
|---|---|
| Calibre | calibre:series* |
| 静读天下、KOReader 等第三方 | calibre:series* |
| Apple Books | belongs-to-collection 一系 |
| 部分国产阅读器 | 两者之一,视版本 |
只写一套,另一半阅读器就不归组。工具的做法是两套同时写、值保持一致,所以在 Calibre 和 Apple Books 里都能正确成组、按序号排序。
两个实操细节:
- 系列名必须逐字一致——“地球往事” 和 “地球往事 ” (尾部多个空格)会被当成两个系列
- 序号可以用小数:番外、加卷用 1.5、2.5,Calibre 一侧排序支持最好
封面:也是两处标记
EPUB2 和 EPUB3 指认封面的方式不同,所以要写两处:
<!-- manifest 里:EPUB3 方式 -->
<item id="cover-image" href="images/cover.jpg"
media-type="image/jpeg" properties="cover-image"/>
<!-- metadata 里:EPUB2 方式 -->
<meta name="cover" content="cover-image"/>
替换封面时工具的行为分两种:
| 原书情况 | 处理方式 |
|---|---|
| 已有封面 | 覆盖原封面文件的字节,保留原路径,同步更新 manifest 里的 media-type |
| 没有封面 | 新增 images/cover.<ext>,补一条 manifest 项(带 properties="cover-image")和 <meta name="cover"> |
保留原路径的好处是:原书里所有引用封面的地方(封面页 XHTML、目录)都不用改,不会出现”封面页指向一个已经不存在的图片”。
格式支持 JPG / PNG / WebP / GIF,单张 20MB 内。建议优先 JPG 或 PNG——WebP 在老设备和部分 E-ink 阅读器上仍可能不显示。比例上竖版 2:3(如 1600×2400)在各家书架里观感最一致。
改完不生效?按这个顺序排查
| 排查顺序 | 现象 | 原因 | 处理 |
|---|---|---|---|
| 1 | 书名 / 封面还是旧的 | 阅读器缓存了书目和缩略图 | 从书架删除后重新导入 |
| 2 | Calibre 里没变 | Calibre 读自己的 metadata.db | 右键 → 从文件格式中读取元数据 |
| 3 | 系列不归组 | 阅读器读的是另一套字段 | 工具已双写,检查系列名是否逐字一致 |
| 4 | 导入后覆盖了另一本书 | 两本书的 dc:identifier 相同 | 给其中一本换一个新标识符 |
| 5 | 阅读进度丢了 | 改了 dc:identifier | 别改标识符,留空即保留原值 |
| 6 | 完全打不开 / 无法解析 | 带 DRM 的商店购买书 | 先用合法手段解除 DRM |
最可靠的验证方式:把导出的 .epub 改名成 .zip 解开,直接看 .opf 里的字段值。文件里是新值 + 阅读器显示旧值 = 缓存问题,跟工具无关。
非破坏式是怎么做到的
“只改身份信息、不碰正文”这句话具体拆成六步:
- 定位 OPF:读
META-INF/container.xml拿到 OPF 路径 - 原位替换 metadata 块:用正则把 OPF 里
<metadata>…</metadata>整段换成新生成的内容,OPF 的其余字节(manifest、spine、guide)完全不动 - 保留未托管字段:只有工具管理的那批字段会被重新生成,其余原样搬回(清单见下表)
- 良构自检:生成的 OPF 会被重新解析一遍,只要出现 XML 解析错误就中止导出并保留原文件不动——不会给你一个坏包
- 重打包:
mimetype用 STORE(不压缩)写在包内第一个位置,其余文件按原始字节复制、DEFLATE 级别 6 压缩 - 只替换两个文件:OPF,以及换封面时的那张图
第 3 步的托管范围:
| 工具托管(会重写) | 工具保留(原样搬回) |
|---|---|
dc:title dc:creator dc:language dc:publisher dc:description dc:date dc:identifier dc:rights dc:subject | dc:contributor(译者 / 编者) |
meta name="cover" | 其它 dcterms:* 字段 |
calibre:series / calibre:series_index | Calibre 自定义列 |
belongs-to-collection / collection-type / group-position | 其它自定义 <meta> |
dcterms:modified(自动刷新为当前时间) | — |
第 5 步的 mimetype 是 OCF 规范的硬要求(必须是首个文件、不压缩、无额外字段),很多手工用压缩软件”重新打个包”的 EPUB 就是在这一步坏掉的——阅读器和 epubcheck 会直接说这不是有效的 EPUB。
dcterms:modified 会自动更新为当前 UTC 时间,这是 EPUB 3 要求的最后修改时间字段,缺失会导致部分校验器报警。
规模与限制
- 单文件上限 200 MB,多本可一次拖入、打包 ZIP 下载
- 不支持 DRM 加密书——商店购买的加密包无法解析
- 只处理 EPUB。Kindle 的 AZW3 / MOBI 需要先转成 EPUB
- 全程在浏览器本地完成,文件不上传服务器,断网可用
相关
- 想把书变成纯文本喂给 TTS 或做检索:EPUB 转 TXT,坑点见 章节顺序和标题到底从哪来
- 手上是 TXT 想做成带目录的 EPUB:TXT 转 EPUB 与 网文章节识别为什么会翻车