开源库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文件开头都会多一个这个头,是个小问题,截取掉就可以了。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页