開源庫epublib使用詳解

ScottePerk 2022-01-07 17:13:16 阅读数:12

epublib 使用

開源庫epublib使用詳解

這個開源庫是一個老外寫的,我用這個寫了一個epublib的swing閱讀器。功能還是比較全的,目錄解析和文本關聯的功能都比較好實現。缺點就是沒文檔,不知道作者怎麼想的。

下面貼個實現的swing gui效果,還是有很多小問題。不過目錄和文本都解析出來了,事件也能關聯上。功能還是比較强的(指epublib這個庫)。
在這裏插入圖片描述

0.epub格式解析

還是要從epub格式說起。
epub文件本質上就是個壓縮文件,可以通過解壓軟件直接解壓。
在這裏插入圖片描述
這是解壓後的目錄結構。進入text目錄,裏面是一堆的html。本質上,epub就是包裝了網頁而已。
在這裏插入圖片描述
看到有css,html,還有images這些目錄和文件你差不多就懂了。epub就是通過一個個網頁來展示書籍的。

這裏比較關鍵的就是content.opf這個文件。
在這裏插入圖片描述
裏面包含了這個epub資源的組織形式。其實也非常的簡單,一個資源文件(html,css,image)對應一個id,通過id就可以獲取到這些資源文件的路徑。

如果你想造輪子,通過一些dom庫都可以實現解析。

1.配置環境

作者用到了slf4j日志庫,添加圖中的兩個slf4j的依賴就開源了,不需要做別的配置。沒有的這個依賴調用庫直接報錯。然後就是作者提供的兩個epub庫了。flatlaf.jar是我找的一個swing主題。
在這裏插入圖片描述

2.主要類分析

主要涉及的類有

  • Book:一個Book類錶示一本書,通過Book可以獲取到一本書的一切內容。
  • TableOfContents:目錄錶,通過這個類可以獲取到一個樹形結構的目錄,非常的有用
  • TOCReference:前面的TOC指的就是上面的TableOfContents,也就是目錄引用的意思,可以獲取到目錄相關聯的內容。
  • Spine:和TableOfContents類似,只是它是線性結構的,而不是樹形
  • SpineReferences:類似TOCReference,只是它是線性結構的。

2.1Book類

 EpubReader reader=new EpubReader();
Book book = reader.readEpub(new FileInputStream(bookPath));

獲取到book類後就可以獲取到整本書的任何資源了。看名字就知道了獲取封面,獲取標題,最主要的就是獲取目錄和文本內容,也就是getTableOfContents()和getContents()
在這裏插入圖片描述

2.2 Resources和Resource類

注意一個是複數一個是單數。Resources(複數)實際上是一個資源管理類,通過它可以查找資源。
在這裏插入圖片描述
注意它的這些get方法,getById(),getByhref()通過這些可以查找到對應的html,css,image等資源文件。而Resource(單數)錶示的就是這些文件。
當獲取到具體的Resource後,可以調用getData()獲取整個文件流,或者通過gettitle()等方法獲取一些基本信息。
在這裏插入圖片描述

3.踩坑指南

最大的可能不在epublib本身,而是swing gui。

3.1目錄樹的顯示問題

目錄是分一級菜單,二級菜單,三級菜單的。在JTree解析加載的時候會有一個root結點,這個結點即使字符串被設置為空,還是有一個箭頭圖標在。這時候需要設置
tree.setShowsRootHandles(false);//會顯示第一級目錄的圖標
這樣就可以實現目錄的效果。但是默認情况下目錄是不展開的,隱藏了root結點,整個目錄就不見了。

需要自動展開tree.

 public static void expandTree(JTree tree) {

TreeNode root = (TreeNode) tree.getModel().getRoot();
expandAll(tree, new TreePath(root), true);
}
private static void expandAll(JTree tree, TreePath parent, boolean expand) {

// Traverse children
TreeNode node = (TreeNode) parent.getLastPathComponent();
if (node.getChildCount() >= 0) {

for (Enumeration e = node.children(); e.hasMoreElements(); ) {

TreeNode n = (TreeNode) e.nextElement();
TreePath path = parent.pathByAddingChild(n);
expandAll(tree, path, expand);
}
}
// Expansion or collapse must be done bottom-up
if (expand) {

tree.expandPath(parent);
} else {

tree.collapsePath(parent);
}
}

這裏會出現問題就是樹展開顯示不全,一開始我以為是這個展開方法有問題,後來發現是這個方法調用的太早了,需要等frame加載完了再調。

3.2Jtextpane不顯示文本內容

這個問題找了很久,我們解析出下面的html代碼。

<?xml version='1.0' encoding='utf-8'?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head>
<title>Never Eat Alone, Expanded and Updated: And Other Secrets to Success, One Relationship at a Time</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
<link href="../page_styles.css" rel="stylesheet" type="text/css"/>
</head>
<body id="CCNA0-6bc8a47c0669410c9079b5781debb684" class="calibre2">
<h1 class="chapter" id="c07"><a id="page68"></a><a id="page69"></a><span class="back">CHAPTER 7</span></h1>
<h1 class="chapter_title">Do Your Homework</h1>
<div class="block">
<p class="bl_nonindent">Spectacular achievement is always preceded by spectacular preparation.</p>
<p class="bl_right">—Robert H. Schuller</p>
</div>
<p class="nonindent">Whom you meet, how you meet them, and what they think of you afterward should not be left to chance. As Winston Churchill would tell us, preparation is—if not the key to genius—then at least the key to sounding like a genius.</p>
</body></html>

注意最後一行
在這裏插入圖片描述

有下面的類似亂碼的東西,這個亂碼很長大概有2000個字符,一開始我以為是這個亂碼導致的。後來發現不是,這個亂碼是不影響解析顯示的,可以不要處理。

真正的原因是meta標簽裏面的charset。這是jtextpane導致的,和html無關,解决部分就是設置下面的屬性。

 textPane.getDocument().putProperty("IgnoreCharsetDirective", Boolean.TRUE);
if (htmlData != null) {

System.out.println("htmldata length" + htmlData.length());
textPane.setText(htmlData.substring(xmlTag.length()));
}

3.3 jtextpane多顯示<?xml version='1.0' encoding='utf-8'?>

這個是這個html文件開頭都會多一個這個頭,是個小問題,截取掉就可以了。

版权声明:本文为[ScottePerk]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/01/202201071713162159.html