基礎知識
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