All formats

epub4j

LanguageJava (also Android)
LicenseApache-2.0
Repositorygithub.com/documentnode/epub4j
DocumentationREADME and source
Depends onzip4j, kxml2, xmlpull, minilog
Read / writeyes / yes (writes EPUB 2 package files)

epub4j reads an EPUB into a Book object with Metadata, Resources (every file in the book), a Spine (reading order) and a TableOfContents, and writes a Book back to an EPUB file. You can load a book, change it (title, authors, cover, chapters) and save it again. It’s a fork of epublib with the same design, a Gradle build and no SLF4J dependency, maintained by Document Node.

The writer produces EPUB 2 package files (OPF 2.0 and an NCX table of contents). These open in all current readers, but if you need EPUB 3 features (navigation document, fixed layout, accessibility metadata) you have to add them yourself.

Installation#

Gradle:

Kotlin
dependencies {
    implementation("io.documentnode:epub4j-core:4.2.2")
}

Maven:

XML
<dependency>
  <groupId>io.documentnode</groupId>
  <artifactId>epub4j-core</artifactId>
  <version>4.2.2</version>
</dependency>

On Android exclude the xmlpull group, which Android already provides: implementation("io.documentnode:epub4j-core:4.2.2") { exclude(group = "xmlpull") }.

Basic usage: read an EPUB#

Java
import io.documentnode.epub4j.domain.Author;
import io.documentnode.epub4j.domain.Book;
import io.documentnode.epub4j.domain.SpineReference;
import io.documentnode.epub4j.epub.EpubReader;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

public class ReadEpub {
    public static void main(String[] args) throws IOException {
        try (InputStream in = new FileInputStream("book.epub")) {
            Book book = new EpubReader().readEpub(in);

            System.out.println("Title: " + book.getTitle());
            for (Author a : book.getMetadata().getAuthors()) {
                System.out.println("Author: " + a.getFirstname() + " " + a.getLastname());
            }
            System.out.println("Language: " + book.getMetadata().getLanguage());

            // chapters in reading order
            for (SpineReference ref : book.getSpine().getSpineReferences()) {
                String html = new String(ref.getResource().getData(), StandardCharsets.UTF_8);
                System.out.println(ref.getResource().getHref() + ": " + html.length() + " chars");
            }
        }
    }
}

How to print the table of contents#

Java
import io.documentnode.epub4j.domain.TOCReference;
import java.util.List;

static void printToc(List<TOCReference> refs, int level) {
    for (TOCReference ref : refs) {
        System.out.println("  ".repeat(level) + ref.getTitle() + " -> " + ref.getCompleteHref());
        printToc(ref.getChildren(), level + 1);
    }
}

// ...
printToc(book.getTableOfContents().getTocReferences(), 0);

How to create an EPUB#

Java
import io.documentnode.epub4j.domain.Author;
import io.documentnode.epub4j.domain.Book;
import io.documentnode.epub4j.domain.Resource;
import io.documentnode.epub4j.epub.EpubWriter;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

public class CreateEpub {
    static Resource html(String body, String href) {
        String xhtml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            + "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>" + href + "</title></head>"
            + "<body>" + body + "</body></html>";
        return new Resource(xhtml.getBytes(StandardCharsets.UTF_8), href);
    }

    public static void main(String[] args) throws IOException {
        Book book = new Book();
        book.getMetadata().addTitle("My Book");
        book.getMetadata().addAuthor(new Author("Jane", "Doe"));
        book.getMetadata().setLanguage("en");

        book.addSection("Chapter 1", html("<h1>Chapter 1</h1><p>First chapter.</p>", "chapter1.xhtml"));
        book.addSection("Chapter 2", html("<h1>Chapter 2</h1><p>Second chapter.</p>", "chapter2.xhtml"));

        try (OutputStream out = new FileOutputStream("book.epub")) {
            new EpubWriter().write(book, out);
        }
    }
}

addSection adds the resource, a table of contents entry and a spine entry. The media type is guessed from the file extension.

How to set the cover image#

Java
import java.nio.file.Files;
import java.nio.file.Path;

byte[] jpg = Files.readAllBytes(Path.of("cover.jpg"));
book.setCoverImage(new Resource(jpg, "images/cover.jpg"));

How to change the title of an existing EPUB#

Java
Book book;
try (InputStream in = new FileInputStream("in.epub")) {
    book = new EpubReader().readEpub(in);
}
book.getMetadata().setTitles(java.util.List.of("New Title"));
try (OutputStream out = new FileOutputStream("out.epub")) {
    new EpubWriter().write(book, out);
}

Tips#