EPUB本质是ZIP压缩包,不是专用二进制格式
EPUB文件其实就是一个按特定目录结构组织的ZIP包,里面包含
META-INF/container.xml、
content.opf、
toc.ncx(或
nav.xhtml)、HTML内容页、CSS、图片等。C#不需要“EPUB专用库”也能生成,但手动拼装容易出错——比如
container.xml路径写错、MIME类型漏声明、OPF中
manifest与
spine不一致,都会导致阅读器打不开。
推荐用
SharpZipLib(处理ZIP) + 手动构造XML文件,或更稳妥地用
EpubLib(NuGet包:
Idelta.EpubLib),它封装了OPF/NCX生成逻辑,但注意它不支持EPUB 3的
nav.xhtml,只生成EPUB 2。
EpubLib对中文路径支持弱,图片文件名含中文时需先
Uri.EscapeDataString()编码再加入包内 所有HTML内容页必须用
.xhtml扩展名,且根元素为 CSS建议内联(避免外部引用失败),或确保CSS路径在OPF的
manifest中声明为
application/css
用EpubLib快速生成带图文本:关键三步
以一段含
<img alt="C#生成EPUB电子书文件 C#如何将文本和图片打包成EPUB格式" >标签的Markdown转HTML后打包为例:
var book = new EpubBook();
book.Title = "我的笔记";
book.Author = "作者";
// 添加封面图(可选,但多数阅读器要求)
var coverPath = "cover.jpg";
book.AddCoverImage(coverPath, File.ReadAllBytes(coverPath));
// 添加正文HTML(必须是UTF-8字节流,且含完整xhtml结构)
string htmlContent = @"<html xmlns='http://www.w3.org/1999/xhtml'>
<head><title>第一章</title></head>
<body>
<p>这是文字</p>
@@##@@
</body>
</html>";
book.AddHtml("chapter1.xhtml", Encoding.UTF8.GetBytes(htmlContent));
// 添加图片(路径需与HTML中src一致,且加到images/子目录下)
book.AddImage("images/https://www.php.cn/faq/photo.png", File.ReadAllBytes("https://www.php.cn/faq/photo.png"));
// 生成
book.Save("output.epub");
注意:
AddImage()第二个参数是
byte[],不是文件路径;
AddHtml()传入的是已编码的字节,不是字符串;如果HTML里用了相对路径如
images/https://www.php.cn/faq/photo.png,就必须用完全相同的路径字符串调用
AddImage(),大小写和斜杠方向都不能错。
手动ZIP方式:绕过库限制但需严守规范
当需要EPUB 3支持(如
nav.xhtml、视频、MathML)或定制OPF元数据时,直接用
ZipFile(SharpZipLib)更可控: 先创建临时文件夹,按EPUB结构放好所有文件(
META-INF/、
OEBPS/等)
container.xml必须放在
META-INF/container.xml,内容指向
OEBPS/content.opf
content.opf中每个资源都要有
<item></item>,图片的
media-type必须是
image/jpeg或
image/png,不能写
image/jpg生成
nav.xhtml时,
<nav></nav>必须有
epub:type="toc"属性,且
<ol></ol>嵌套层级要合法
常见报错:
Calibre报错“no spine item found”→ 检查
content.opf中
<spine></spine>下的
<itemref idref="..."></itemref>是否对应
<manifest></manifest>中已声明的
id;
微信读书打不开→ 多半是HTML未声明xhtml命名空间或字符编码不是UTF-8无BOM。
图片处理的隐性坑:尺寸、格式、嵌入路径
EPUB阅读器对图片兼容性差异大:Kindle仅支持JPEG/PNG,不认WebP;Apple Books对SVG支持有限;Kobo要求图片宽度不超过1024px否则缩放异常。
图片文件名避免空格和中文,用photo_01.png比
我的配图.jpg更安全 HTML中
<img src="images/https://www.php.cn/faq/photo.png" alt="配图">和
AddImage("https://www.php.cn/faq/photo.png", ...)的路径必须字面量一致(区分大小写)
若图片来自内存流(如Bitmap.Save(ms, ImageFormat.Png)),记得
ms.Position = 0再读取字节,否则写入ZIP为空 批量添加时别用
Directory.GetFiles()直接遍历——EPUB要求路径分隔符统一为
/,Windows返回
\会导致路径解析失败
最易被忽略的一点:EPUB标准要求所有资源路径在OPF中声明的
href值,必须与ZIP内实际路径**完全一致**,包括大小写、前后斜杠、是否带
./前缀——这里错一个字符,整个文件就可能被判定为损坏。
