POI-word

POI-word

起男 784 2021-02-03

POI-word

apache poi的hwpf模块是专门用来对word doc文件进行读写操作的。在hwpf里面我们使用HWPFDocument来表示一个word doc文档

在HWPFDocument里有几个概念:

  • Range:它标识一个范围,这个范围可以是整个文档,也可以是里面的某一小节(Section),也可以是某一个段落(Paragraph),还可以是拥有共同属性的一段文本(CharacterRun)
  • Section:word文件的一个小节,一个word文档可以由多个小节组成
  • Paragraph:word文档的一个段落,一个小节可以由多个段列构成
  • CharacterRun:具有相同属性的一段文本,一个段列可以由多个CharacterRun组成
  • Table:一个表格
  • TableRow:表格里的行
  • TableCell:表格里的单元格

依赖

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.9</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.9</version>
         </dependency>

在日常应用中,我们从word文件里面读取信息的情况非常少见,更多的还是把内容写入到word文件中。使用POI从word doc文件读取数据时主要有两种方式:通过WordExtractor读或通过HWPFDocument读。在WordExtractor内部进行信息读取时还是通过HWPFDocument来读取的

WordExtractor

在使用WordExtractor读取文件时我们只能读到文件的文本内容和基于文档的一些属性,至于文档内容的属性等是无法读取到的。如果要读到文档内容的属性则需要使用HWPFDocument来读取了。

示例:

InputStream is = new FileInputStream("H:\\testDemo\\ccc.doc");
        WordExtractor wordExtractor = new WordExtractor(is);

        //输出所有文本内容
        System.out.println(wordExtractor.getText());
        //输出页眉
        System.out.println(wordExtractor.getHeaderText());
        //输出页脚
        System.out.println(wordExtractor.getFooterText());
        //输出元数据,包括作者、修改时间等
        System.out.println(wordExtractor.getMetadataTextExtractor().getText());
        //获取各个段落的文本
        String[] paragraphText = wordExtractor.getParagraphText();
        for (String s : paragraphText){
            System.out.println(s);
        }
        //输出当前word的一些信息
        SummaryInformation summaryInformation = wordExtractor.getSummaryInformation();
        //作者
        System.out.println(summaryInformation.getAuthor());
        //字符统计
        System.out.println(summaryInformation.getCharCount());
        //页数
        System.out.println(summaryInformation.getPageCount());
        //标题
        System.out.println(summaryInformation.getTitle());
        //主题
        System.out.println(summaryInformation.getSubject());

        is.close();

HWPFDocument

HWPFDocument是当前word文档的代表,它的功能比WordExtractor要强。通过它我们可以读取文档中的表格、列表等,还可以对文档的内容进行新增、修改和删除操作。只是在进行完这些新增、修改和删除相关信息是保存在HWPFDocument中的,也就是说我们改变的是HWPFDocument,而不是磁盘上的文件。如果要使这些修改生效的话,我们可以调用HWPFDocument的write方法把修改后的HWPFDocument输出到指定的输出流中。这可以是原文件的输出流,也可以是新文件的输出流(相当于另存为)或其它输出流。

示例:

InputStream is = new FileInputStream("H:\\testDemo\\ccc.doc");
        HWPFDocument document = new HWPFDocument(is);

        //输出书签信息
        Bookmarks bookmarks = document.getBookmarks();
        //书签数量
        System.out.println(bookmarks.getBookmarksCount());
        for (int i=0; i<bookmarks.getBookmarksCount(); i++){
            Bookmark bookmark = bookmarks.getBookmark(i);
            //书签名
            System.out.println(bookmark.getName());
            //开始位置
            System.out.println(bookmark.getStart());
            //结束位置
            System.out.println(bookmark.getEnd());
        }
        //输出文本
        System.out.println(document.getDocumentText());
        //
        Range range = document.getRange();
        //读表格
        TableIterator iterator = new TableIterator(range);
        while (iterator.hasNext()){
            Table next = iterator.next();
            int numRows = next.numRows();
            for (int i=0; i<numRows; i++){
                TableRow row = next.getRow(i);
                int numCells = row.numCells();
                for (int j=0; j<numCells; j++){
                    TableCell cell = row.getCell(j);
                    //输出单元格文本
                    System.out.println(cell.text());
                }
            }
        }

        is.close();

在使用POI写word doc文件的时候我们必须要先有一个doc文件才行,因为我们在写doc文件的时候是通过HWPFDocument来写的,而HWPFDocument是要依附于一个doc文件的。所以通常的做法是我们先在硬盘上准备好一个内容空白的doc文件,然后建立一个基于该空白文件的HWPFDocument。之后我们就可以往HWPFDocument里新增内容了,然后再把它写入到另一个doc文件中,这样就相当于我们使用poi生成了word doc文件

在实际应用中,我们在生成word文件的时候都是生成某一类文件,该类文件的格式是固定的,只是某些字段不一样罢了。所以在实际应用中,我们大可不必将整个word文件的内容都通过HWPFDocument生成。而是先在磁盘上新建一个word文档,其内容就是我们需要生成的word文件的内容,然后把里面一些属于变量的内容使用类似于“¥”这样的方式代替。这样我们在基于某些信息生成word文件的时候,只需要获取基于该word文件的HWPFDocument,然后调用Rang的replaceText方法把对应的变量替换为对应的值即可,之后再把当前的HWPFDocument写入到新的输出流中。这中方法在时间应用用比较多,因为它不但可以减少我们的工作量,还可以让文本的格式更加清晰

实例:

String temp = "H:\\testDemo\\temp.doc";
        InputStream is = new FileInputStream(temp);

        HWPFDocument document = new HWPFDocument(is);
        Range range = document.getRange();
        range.replaceText("${aaa}","abc");
        range.replaceText("${bbb}","100");

        OutputStream os = new FileOutputStream("H:\\testDemo\\write.doc");

        document.write(os);
        os.close();
        is.close();

原文:https://blog.51cto.com/puregirl/1979349