All formats

VersOne.Epub

LanguageC# (.NET Standard 1.3+, .NET Framework 4.6+)
LicenseUnlicense (public domain)
Repositorygithub.com/vers-one/EpubReader
Documentationos.vers.one/EpubReader
Depends onnothing outside .NET
Read / writeyes / no (EPUB 2.0, 2.0.1, 3.0 to 3.3)

VersOne.Epub is the most complete EPUB reader for .NET. It parses the OCF container, the OPF package (all Dublin Core metadata, manifest, spine), the EPUB 3 navigation document and EPUB 2 NCX, and gives you the content files as strings or byte arrays. It handles many malformed books with relaxed options.

There are 2 ways to open a book: EpubReader.ReadBook loads every file into memory (simple, fine for typical books), and EpubReader.OpenBook returns an EpubBookRef that reads files only when you ask (lower memory, faster to open). The library doesn’t write EPUB files and doesn’t convert HTML to plain text: use HtmlAgilityPack or AngleSharp for that.

Installation#

Shell
dotnet add package VersOne.Epub

Basic usage: read metadata, table of contents and chapters#

C#
using VersOne.Epub;

EpubBook book = EpubReader.ReadBook("book.epub");

Console.WriteLine($"Title:  {book.Title}");
Console.WriteLine($"Author: {book.Author}");   // all authors joined; book.AuthorList for a list
Console.WriteLine($"Description: {book.Description}");

// table of contents (EPUB 3 nav or EPUB 2 NCX)
void PrintNav(List<EpubNavigationItem> items, int level)
{
    foreach (EpubNavigationItem item in items)
    {
        Console.WriteLine(new string(' ', level * 2) + item.Title);
        PrintNav(item.NestedItems, level + 1);
    }
}
if (book.Navigation != null)
    PrintNav(book.Navigation, 0);

// chapters in reading order (spine), as XHTML strings
foreach (EpubLocalTextContentFile chapter in book.ReadingOrder)
{
    Console.WriteLine($"{chapter.FilePath}: {chapter.Content.Length} characters");
}

How to extract the cover image from an EPUB#

CoverImage finds the cover from EPUB 3 properties="cover-image", the EPUB 2 <meta name="cover"> or the guide:

C#
EpubBook book = EpubReader.ReadBook("book.epub");
if (book.CoverImage != null)
{
    string ext = book.Content.Cover?.ContentMimeType == "image/png" ? ".png" : ".jpg";
    File.WriteAllBytes("cover" + ext, book.CoverImage);
}

How to read an EPUB without loading it all into memory#

C#
using EpubBookRef bookRef = EpubReader.OpenBook("book.epub");
Console.WriteLine(bookRef.Title);
Console.WriteLine($"EPUB version: {bookRef.Schema.Package.GetVersionString()}");

foreach (EpubLocalTextContentFileRef chapterRef in bookRef.GetReadingOrder())
{
    string html = chapterRef.ReadContent();  // reads this file from the ZIP now
    Console.WriteLine($"{chapterRef.FilePath}: {html.Length} characters");
}
byte[]? cover = bookRef.ReadCover();

OpenBookAsync, ReadContentAsync and ReadCoverAsync are the async versions.

How to read all metadata (publisher, language, identifiers)#

The parsed OPF is in Schema.Package.Metadata:

C#
EpubMetadata meta = book.Schema.Package.Metadata;
foreach (var id in meta.Identifiers)
    Console.WriteLine($"Identifier: {id.Identifier} ({id.Scheme})");
foreach (var lang in meta.Languages)
    Console.WriteLine($"Language: {lang.Language}");
foreach (var pub in meta.Publishers)
    Console.WriteLine($"Publisher: {pub.Publisher}");

How to extract all images#

C#
foreach (EpubLocalByteContentFile image in book.Content.Images.Local)
{
    string path = Path.Combine("images", Path.GetFileName(image.FilePath));
    Directory.CreateDirectory("images");
    File.WriteAllBytes(path, image.Content);
}

book.Content also has Html, Css, Fonts, Audio and AllFiles collections.

Tips#