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

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
libxl是一种用于操作Excel文件的开源,其具有简单易用、功能强大的特点。下面将详细介绍libxl使用方法。 首先,我们需要在项目中引入libxl的头文件,并链接相应的文件。然后,创建一个Workbook对象,用于表示一个Excel文件。可以使用createWorkbook函数创建一个新的空白Excel文件,也可以使用openWorkbook函数打开一个已有的Excel文件。 在创建或打开Excel文件后,可以通过各种函数来对文件进行操作。可以使用addSheet函数添加一个新的工作表,并使用setSheetName函数设置工作表的名称。可以使用write函数将数据写入指定的单元格。可以使用mergeCells函数合并单元格,并使用setColWidth和setRowHeight函数设置列宽和行高。 在写入数据后,可以通过save函数保存Excel文件,并使用release函数释放Workbook对象。还可以使用setCellFormat函数设置单元格的格式,如字体、对齐方式等。 除了写入数据,libxl还支持读取Excel文件的操作。可以使用read函数读取指定单元格的数据,使用sheetCount函数获取工作表数量,使用sheetName函数获取指定工作表的名称。 此外,libxl还提供了一些高级功能,如设置页眉页脚、设置打印区域、设置打印属性等。 总结一下,libxl是一个功能强大且易于使用的Excel文件操作。通过学习和掌握libxl的使用方法,我们可以方便地对Excel文件进行创建、读取和写入操作,满足各种Excel处理需求。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值