笨方法学 Java -28-综合练习2-实现分析-Word 文本提取
作者:谎言诞行    发布时间:2024年03月21日

一、前言

从这章节开始,我们就要着手研究 Office Word 文档的读、写操作了。在开始前,我们先确认下软件包的依赖关系。在《笨方法学 Java -21-综合练习1-实现分析-Excel文件读写》中,我们已经添加了关于POI的软件依赖。如下:

image.png

为了能顺利解析Office Word文档,我们还需要追加一个 poi-scratchpad 依赖关系如下:

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad   -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>5.2.5</version>
</dependency>


二、关于Office Word文档的解析方式

其实,在POI组件中,Word 文档有2种解析方式:使用文本提取器一次性读取 和 使用文档对象逐个解析。这2种方式,我们本次综合练习2都会涉及。

在系统功能上,我们有一个查看模板信息的功能。为了简化实现,我们就使用文本提取器(Extractor)来获取模板的文本信息。

 

三、文本提取器的使用

在POI组件中,它提供了2个关于Word文档的文本提取器:

l   关于doc格式文档的提取器 org.apache.poi.hwpf.extractor.WordExtractor

l   关于docx格式文档的提取器 org.apache.poi.xwpf.extractor.XWPFWordExtractor

在组件设计上,2个提取器都实现了接口 org.apache.poi.extractor.POITextExtractor。因此,我们可以在代码处理上,减少一些差异化处理。通过Java的多态特性,转换为面向接口 POITextExtractor 的文本提取


四、样例功能实现

注意:

1、这里只是演示如何使用文本提取器,所以不用太关注资源回收,第五点内容才是完整的实现代码。

2、这里getText方法获取的文本不单单是正文内容,还包含页眉、页脚信息。

public static void main(String[] args)   throws Exception {
    //操作系统用户主目录
    String userDir =   System.getProperties().getProperty("user.home");
    //文件所在文件夹
    String fileDir = userDir+File.separator+"examproj";
    //模板文件路径
    String oldFilePath = fileDir+File.separator+"请假单模板(旧).doc";
    String newFilePath = fileDir+File.separator+"请假单模板(新).docx";
    //文档对象
    HWPFDocument oldDoc = new HWPFDocument(new FileInputStream(oldFilePath));
    XWPFDocument newDocx = new XWPFDocument(new FileInputStream(newFilePath));
    //创建提取器
    POITextExtractor oldExtor = new WordExtractor(oldDoc);
    POITextExtractor newExtor = new XWPFWordExtractor(newDocx);
    //输出提取的信息(提取的内容可能包含格式符,替换为空格)
    System.out.println("旧模板信息:"+oldExtor.getText().replaceAll("\\s+",   " "));
    System.out.println("新模板信息:"+newExtor.getText().replaceAll("\\s+",   " "));
    
    // ============== 下面开始关闭资源,这里是练习,所以随便关闭下
    //关闭提取器
    oldExtor.close();
    newExtor.close();
    //关闭文档
    oldDoc.close();
    newDocx.close();
    //关闭输入流
}

结果如下:

image.png


五、综合练习2的项目代码展现

/**
 * >>&nbsp;通过提取器,获取纯文本然后返回。
 * @param filePath 文件路径
 * @return Word 文档的正文内容
 * @throws Exception 当发生异常情况,抛出异常由外部程序处理
 */
public static final String getTextByExtractor(String filePath) throws Exception {
    String result = null;
    if(filePath==null || filePath.trim().length()<=0) {
        throw new Exception("传入的参数filePath为空,请检查");
    }
    //文件后缀
    String suffix = filePath.substring(filePath.lastIndexOf(".")+1);
    //
    FileInputStream fin = null;
    POITextExtractor textExtrator = null;
    XWPFDocument documentX = null;
    HWPFDocument documentH = null;
    //
    try {
        fin = new FileInputStream(filePath);
        if(suffix.equalsIgnoreCase("doc")) {
            documentH = new HWPFDocument(fin);
            textExtrator = new WordExtractor(documentH);
        }else if(suffix.equalsIgnoreCase("docx")) {
            documentX = new XWPFDocument(fin);
            textExtrator = new XWPFWordExtractor(documentX);
        }else {
            throw new FileNotFoundException("传入的文档识别异常,无法识别为word文档,请检查文件路径[filePath="+filePath+"]");
        }
        //将文档中的内容读取(获取的内容带有格式,所以替换掉格式符。)
        String tmp = textExtrator.getText();
        result = tmp==null?"":tmp.replaceAll("\\s+", " ");
    } catch(Exception e) {
        throw e;
    } finally {
        if(textExtrator!=null) {
            try {textExtrator.close();} catch (Exception e) {}
            textExtrator=null;
        }
        if(documentX!=null) {
            try {documentX.close();} catch (Exception e0) {}
            documentX=null;
        }
        if(documentH!=null) {
            try {documentH.close();} catch (Exception e1) {}
            documentH=null;
        }
        if(fin!=null) {
            try {fin.close();} catch (Exception e2) {}
            fin=null;
        }
    }
    return result;
}

本章节完结。


填写一种颜色的字符(不区分大小写),1分钟有效,点击图片刷新