基础知识
2026年8月4日
EPUB文件里面装了什么
解压开来看看它的机关
EPUB文件的真身是ZIP。只要改一下扩展名,谁都能打开来看。本文按顺序看看实际解压之后里面装着什么、每个文件各自在做什么。弄懂了机关,显示不正常时就能猜到「该往哪里看」。
试着解压一个EPUB
先动手试试。手边有EPUB文件的话,按下面的步骤就能看到里面。
1复制一份EPUB文件(以免弄坏原文件)
2把扩展名从 .epub 改成 .zip
3照平常那样解压
就这些,不需要特别的软件。EPUB就是ZIP本身,所以连警告都不会出,正常展开。
反过来可不行
「既然能解压,那把文件夹打成ZIP再把扩展名改成 .epub 不就成EPUB了」——你也许会这么想,但没那么简单。因为有下一章开始要讲的压缩方式的规定。
内容的整体样貌
解压之后,大致是这样的构成。
展开后的文件夹
├── mimetype 表明这个箱子是EPUB的标记
├── META-INF/
│ └── container.xml 指路牌,告诉你本体在哪
└── OEBPS/ 装书的内容的文件夹
├── content.opf 书的信息、收录物清单、阅读顺序
├── nav.xhtml 目录
├── text/
│ ├── p001.xhtml 正文(按页分)
│ └── p002.xhtml
├── image/
│ └── cover.jpg 封面等图片
└── style/
└── book.css 外观的指定
OEBPS 这个文件夹名字,以及里面怎么分,都会因制作工具而变。可能是item ,也可能是 xhtml ,那都没关系。
另一方面,开头的 mimetype 和 META-INF/container.xml ,名字和位置都不能改。 只有这两个是固定的,其余都自由——这是理解EPUB结构的第一步。
mimetype ── 最特别的文件
内容只有一行,就这些。
application/epub+zip
它的作用是宣告「这个ZIP是EPUB」。不过这个文件有别的文件没有的严格规定。
- 放在ZIP里的最前面
- 不能压缩(原样存入)
- 不加多余的信息
- 末尾不留换行
阅读软件只要读一点文件开头,就能判断「这是EPUB」。为此,它的位置和形式被定死了。
手工做EPUB,首先就卡在这里
用普通的压缩软件把文件夹打成ZIP,既选不了文件顺序,mimetype 也会被一起压缩。结果就是,即便把扩展名改成 .epub ,阅读软件也打不开。
要满足「放在最前面、不压缩」这个条件,需要把压缩的步骤分开执行。EPUB制作工具最先做的,就是这道处理。
container.xml ── 指路牌
META-INF/container.xml 的内容是这样的。
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="OEBPS/content.opf"
media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
它只做一件事:告诉你「书的信息在 OEBPS/content.opf 」。
文件夹名字之所以可以自由,就是因为有这块指路牌。阅读软件会先看 META-INF/container.xml ,再前往它写明的地方。
content.opf ── 书的心脏
这是EPUB里最重要的文件,大致分成三个部分。
| 部分 | 作用 |
| metadata | 标题、作者、语言等书本身的信息 |
| manifest | 收录的文件的一览表 |
| spine | 翻页的顺序 |
metadata ── 书的信息
<metadata>
<dc:title>爱丽丝梦游仙境</dc:title>
<dc:creator>刘易斯·卡罗尔</dc:creator>
<dc:language>zh</dc:language>
<dc:identifier id="uid">urn:uuid:xxxxxxxx</dc:identifier>
<meta property="dcterms:modified">2026-08-04T00:00:00Z</meta>
</metadata>
这里要留意的是 dc:title 。在阅读软件书架上排着的,是这个值,而不是文件名。 文件名起得再用心,这里为空的话,书架上就会显示「无题」。
dc:language 也很重要。中文写 zh ,日文写 ja。没有它,阅读软件有时不会套用该语言的排版规则——这一点在日文里影响最大。
manifest ── 收录文件的一览
<manifest>
<item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
<item id="p001" href="text/p001.xhtml" media-type="application/xhtml+xml"/>
<item id="css" href="style/book.css" media-type="text/css"/>
<item id="cover" href="image/cover.jpg" media-type="image/jpeg"/>
</manifest>
EPUB里装着的文件,全都必须登记在这里。 加了一张图却忘了登记,光是这样就会报错。反过来,登记了却没有实物,也是报错。
目录的文件要打上 properties="nav" 这个标记,用来表示「这个文件是目录」。
spine ── 阅读顺序
<spine page-progression-direction="rtl">
<itemref idref="p001"/>
<itemref idref="p002"/>
</spine>
manifest 是「装了什么」的一览,那么spine 就是决定「按什么顺序读」 的东西。这里的排列顺序就是页面顺序。
而对日文书来说尤其重要的是 page-progression-direction 。
| 值 | 含义 | 用于哪种书 |
| rtl | 从右往左推进 | 竖排、漫画 |
| ltr | 从左往右推进 | 横排 |
明明是竖排的书却没有这个设置,翻页方向就会相反。 竖排不顺利时,这是最先该确认的地方之一。
nav.xhtml ── 目录
EPUB 3必须把目录作为专门的文件准备好。它看上去就是普通的HTML链接列表,特征是带着epub:type="toc" 这个标记。
<nav epub:type="toc">
<ol>
<li><a href="text/p001.xhtml">第一章</a></li>
<li><a href="text/p002.xhtml">第二章</a></li>
</ol>
</nav>
按下阅读软件的目录按钮时出现的,就是这些内容。链接指向的文件不存在的话,就成了一本没法从目录跳转的书。
有时里面还会一起放着toc.ncx
在老的EPUB 2里,是一个叫 toc.ncx 的文件承担目录的角色。EPUB 3里已经换成了 nav.xhtml ,但有些EPUB为了老的阅读软件会把两个都放进去。
正文、CSS、图片
从这里往后,就和网页几乎一样了。
- 正文用XHTML书写。写法比普通HTML稍严格一些
- 外观由CSS指定。竖排也是CSS的职责
- 图片把JPEG或PNG原样放进去即可
- 字体也可以嵌入(体积会变大)
正文怎么分是自由的,不过单个文件太大会让阅读软件变卡,所以一般按章来分。
手工制作为什么很费劲
如上所见,EPUB的结构本身并不复杂。把正文、图片和设计指定,连同指路牌和一览表一起塞进箱子——就这么回事。
不过,要遵守的规定很琐碎。
mimetype 放在最前面,且不压缩
- 把收录的文件一个不漏地登记到
manifest
- 保证登记了的文件确实存在
- 把阅读顺序和装订方向正确地写进
spine
- 确认目录的链接目标是有效的
- 书名、语言等信息一个不漏地写上
只要缺一项,就可能导致阅读软件打不开,或者在商店投稿时被拒。而且报错的原因,往往从显示出来的内容里看不出来。
所以实际制作中,一般都会用「交给它原稿或图片,它自动组装结构」的工具。即便如此,只要亲眼看过一次里面,不顺利时就能猜到「该怀疑哪里」。这正是本文的目的。
结构会自动组装好
EPUB FACTORY会自动组装这里讲到的全部结构。只要选好图片文件夹或文字稿即可。无需注册,也不用安装。
试试EPUB FACTORY