笨方法学 Java -29-综合练习2-实现分析-doc 文本替换
作者:谎言诞行    发布时间:2024年03月22日

一、前言

由于POI组件,在doc格式文档和docx格式文档读写处理上,API设计差异较大。目前,关于Apache POI组件在Office Word文档的读、写操作上,只有纯文本提取可以使用同一套程序来处理的。

也就是说,如果要对文档进行更加细致的解析和操作,需要分开2套程序代码来完成。

本章节,我们讲下关于doc格式文档的文本替换处理。


二、关于文本替换符

一般来说,如果要对文档中的部分内容进行替换,那么我们需要知道它的具体位置。所以,我们一般会用到一些特殊的符号来标记。如下图所示:

image.png

图中,“{{teacherName}}”是一个替换符。它由开始符号“{{”,替换变量名“teacherName”,以及结束符号“}}” 3部分组成。当文档中这些替换符满足变量替换规则,则会被替换为需要展示的内容。

注意:

1、替换符并非固定格式,可以自己设计,越独特越好。因为很多时候,常见的符号容易与正文内容冲突,造成替换错误。

2、生成结果样例展示如下:

image.png


三、doc格式文档的结构

其实,相比于docx格式的文档,doc文档的结构相对来说较为简单。在网络上找到一段关于文档的描述,大家可以参考看看:

Apache POI的HWPF模块是专门用来对Word doc文件进行读写操作的。在HWPF里面我们使用HWPFDocument来表示一个word doc文档。在HWPFDocument里面有这么几个概念:

l   Range:它表示一个范围,这个范围可以是整个文档,也可以是里面的某一小节(Section),也可以是某一个段落(Paragraph),还可以是拥有共同属性的一段文本(CharacterRun)。

l   Section:word文档的一个小节,一个word文档可以由多个小节构成。

l   Paragraph:word文档的一个段落,一个小节可以由多个段落构成。

l   CharacterRun:具有相同属性的一段文本,一个段落可以由多个CharacterRun组成。

l   Table:一个表格。

    n   TableRow:表格对应的行。

    n   TableCell:表格对应的单元格。

Section、Paragraph、CharacterRun和Table都继承自Range。


四、替换处理

对于doc格式的文档,我们的解析是相对简单的。根据上面第三节的内容,我们可以把doc文档看作一个Range对象。并且,Range对象自带了替换字符串的方法(replaceText)。如下图:

image.png

这里,我们需要用到的方法如下:

image.png

替换方法包含2个参数,第一个是pPlaceHolder,要替换的字符串占位符;第二个是pValue,将要填充的内容。程序中,我们处理的代码如下:

image.png

到这里,我们就把模板文件的文本替换处理介绍完毕了。接下来,我们讲下,关于HWPFDocument文档对象的其它处理方法。

 

五、其它对象的操作解析操作样例

前面第三节中,我们介绍了几个对象。现在,我们就把文档按照段落(Paragraph)解析,并分段输出看看:

public static void main(String[] args) throws Exception {
    //操作系统用户主目录
    String userDir = System.getProperties().getProperty("user.home");
    //文件所在文件夹
    String fileDir = userDir+File.separator+"examproj";
    //word文档路径1
    String templateFilePath1 = fileDir+File.separator+"请假单模板(旧).doc";
    //创建 doc 文档对象
    HWPFDocument doc = new HWPFDocument(new FileInputStream(templateFilePath1));
    //获取范围对象
    Range range = doc.getRange();
    //获取段落数量
    int numPr = range.numParagraphs();
    //分段输出内容信息
    if(numPr>0) {
        for(int i=0;i<numPr;i++) {
            Paragraph p = range.getParagraph(i);
            String content = p.text();
            if(content!=null) {
                System.out.println("段落"+(i+1)+":"+content.replaceAll("\\s+", " "));
            }else {
                System.out.println("段落"+(i+1)+":无内容");
            }
        }
    }else {
        System.out.println("文档获取不到段落信息。");
    }
    //资源回收,这里是测试程序,随便吧
    doc.close();
}

执行结果如下:

image.png


本章完结


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