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();