java如何利用poi解析doc和docx中的數(shù)據(jù)
前言
這個(gè)功能是工作中遇到的一個(gè)需求,需要把上傳的word中的內(nèi)容解析出來(lái),其中包含段落字符串解析,和表格中的數(shù)據(jù)解析出來(lái),需要支持doc和docx格式的數(shù)據(jù)
Apache POI是Apache軟件基金會(huì)的開(kāi)源項(xiàng)目,POI提供API給Java程序?qū)icrosoft Office格式檔案讀和寫(xiě)的功能。 .NET的開(kāi)發(fā)人員則可以利用NPOI (POI for .NET) 來(lái)存取 Microsoft Office文檔的功能。
方法如下:
1、增加maven中的包
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.17</version> </dependency> <!--POI包 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency>
2、解析doc中的數(shù)據(jù)
獲取文件,把MultipartFile對(duì)象的數(shù)據(jù)轉(zhuǎn)成本地file
File file = new File(FileUtils.getUserDirectoryPath() + "/" + multipartFile.getOriginalFilename()); FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
String fileName = file.getName().toLowerCase();
FileInputStream in = new FileInputStream(file);
if (fileName.endsWith(".doc")) {
// 處理doc格式 即office2003版本
handlerDoc(in);
}
if (fileName.endsWith(".docx")) {
handlerDocx(in);
}
解析doc格式中的段落和第一個(gè)表格數(shù)據(jù)
/**
* doc 格式解析
*
* @param in
* @throws IOException
*/
private void handlerDoc(FileInputStream in) throws IOException {
POIFSFileSystem pfs = new POIFSFileSystem(in);
HWPFDocument hwpf = new HWPFDocument(pfs);
//得到文檔的讀取范圍
Range range = hwpf.getRange();
for (int i = 0; i < range.numParagraphs(); i++) {
//段落
Paragraph p = range.getParagraph(i);
//段落文本
String paragraphText = p.text().replace("\r", "");
log.info("paragraphText = {}", paragraphText );
if (paragraphText.contains(VALUE_YLYC)) {
analyze = false;
}
}
TableIterator it = new TableIterator(range);
// 迭代文檔中的表格
// 如果有多個(gè)表格只讀取需要的一個(gè) set是設(shè)置需要讀取的第幾個(gè)表格,total是文件中表格的總數(shù)
int set = 1, total = 1;
int num = set;
for (int i = 0; i < set - 1; i++) {
it.hasNext();
it.next();
}
while (it.hasNext()) {
Map<String, List<String>> tabelText = DocUtils.getTabelDocText((Table) it.next());
log.info("tabelText = {}", tabelText);
}
// 過(guò)濾多余的表格
while (num < total) {
it.hasNext();
it.next();
num += 1;
}
}
3、解析docx中數(shù)據(jù)
解析docx格式中的段落和第一個(gè)表格數(shù)據(jù)
/**
* docx 格式解析
*
* @param in
* @throws IOException
*/
private void handlerDocx(FileInputStream in) throws IOException {
XWPFDocument xwpf = new XWPFDocument(in);
// 獲取word中的所有段落與表格
List<IBodyElement> elements = xwpf.getBodyElements();
// 解析表格后續(xù)不解析
for (IBodyElement element : elements) {
// 段落
if (element instanceof XWPFParagraph) {
String paragraphText = DocUtils.getParagraphText((XWPFParagraph) element);
log.info("paragraphText = {}", paragraphText);
} else if (element instanceof XWPFTable) {
// 表格
Map<String, List<String>> tabelText = DocUtils.getTabelText((XWPFTable) element);
log.info("tabelText = {}", tabelText);
} else {
log.info("其他內(nèi)容");
}
}
}
工具類
package com.hundsun.fais.innerreport.utils;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableRow;
import org.apache.poi.xwpf.usermodel.*;
import java.util.*;
/**
* @author lvbaolin
* @date 2021/4/2 10:39
*/
public class DocUtils {
/**
* docx 格式獲取表格內(nèi)容
*
* @param table
*/
public static Map<String, List<String>> getTabelText(XWPFTable table) {
Map<String, List<String>> result = new LinkedHashMap<>();
List<XWPFTableRow> rows = table.getRows();
for (XWPFTableRow row : rows) {
String key = null;
List<String> list = new ArrayList<>(16);
int i = 0;
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
// 簡(jiǎn)單獲取內(nèi)容(簡(jiǎn)單方式是不能獲取字體對(duì)齊方式的)
StringBuffer sb = new StringBuffer();
// 一個(gè)單元格可以理解為一個(gè)word文檔,單元格里也可以加段落與表格
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
sb.append(DocUtils.getParagraphText(paragraph));
}
if (i == 0) {
key = sb.toString();
} else {
String value = sb.toString();
list.add(value == null || Objects.deepEquals(value, "") ? null : value.replace(",", ""));
}
i++;
}
result.put(key, list);
}
return result;
}
/**
* docx 獲取段落字符串
* 獲取段落內(nèi)容
*
* @param paragraph
*/
public static String getParagraphText(XWPFParagraph paragraph) {
StringBuffer runText = new StringBuffer();
// 獲取段落中所有內(nèi)容
List<XWPFRun> runs = paragraph.getRuns();
if (runs.size() == 0) {
return runText.toString();
}
for (XWPFRun run : runs) {
runText.append(run.text());
}
return runText.toString();
}
/**
* doc 格式的字段解析表格
* @param tb
* @return
*/
public static Map<String, List<String>> getTabelDocText(Table tb) {
Map<String, List<String>> result = new HashMap<>(16);
//迭代行,默認(rèn)從0開(kāi)始,可以依據(jù)需要設(shè)置i的值,改變起始行數(shù),也可設(shè)置讀取到那行,只需修改循環(huán)的判斷條件即可
for (int i = 0; i < tb.numRows(); i++) {
List<String> list = new ArrayList<>(16);
int x = 0;
TableRow tr = tb.getRow(i);
String key = null;
//迭代列,默認(rèn)從0開(kāi)始
for (int j = 0; j < tr.numCells(); j++) {
//取得單元格
TableCell td = tr.getCell(j);
StringBuffer sb = new StringBuffer();
//取得單元格的內(nèi)容
for (int k = 0; k < td.numParagraphs(); k++) {
Paragraph paragraph = td.getParagraph(k);
String s = paragraph.text();
//去除后面的特殊符號(hào)
if (null != s && !"".equals(s)) {
s = s.substring(0, s.length() - 1);
}
sb.append(s);
}
if (x == 0) {
key = sb.toString();
} else {
String value = sb.toString();
list.add(value == null || Objects.deepEquals(value, "") ? null : value.replace(",", ""));
}
x++;
}
result.put(key, list);
}
return result;
}
}
總結(jié)
到此這篇關(guān)于java如何利用poi解析doc和docx中數(shù)據(jù)的文章就介紹到這了,更多相關(guān)java poi解析doc數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring前后端跨域請(qǐng)求設(shè)置代碼實(shí)例
這篇文章主要介紹了Spring前后端跨域請(qǐng)求設(shè)置代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Java基礎(chǔ)之內(nèi)部類與代理知識(shí)總結(jié)
今天帶大家復(fù)習(xí)Java的基礎(chǔ)知識(shí),文中有非常詳細(xì)的介紹及圖文示例,對(duì)正在學(xué)習(xí)Java的小伙伴們很有幫助,需要的朋友可以參考下2021-06-06
SpringBoot+Vue實(shí)現(xiàn)EasyPOI導(dǎo)入導(dǎo)出的方法詳解
項(xiàng)目開(kāi)發(fā)過(guò)程中,很大的需求都有 導(dǎo)入導(dǎo)出功能。本文將利用SpringBoot+Vue實(shí)現(xiàn)EasyPOI導(dǎo)入導(dǎo)出功能,感興趣的可以了解一下2022-08-08
Spring boot jpa 刪除數(shù)據(jù)和事務(wù)管理的問(wèn)題實(shí)例詳解
這篇文章主要介紹了Spring boot jpa 刪除數(shù)據(jù)和事務(wù)管理的問(wèn)題實(shí)例詳解,涉及業(yè)務(wù)場(chǎng)景的一些知識(shí)和遇到的的問(wèn)題,需要的朋友可以參考。2017-09-09
開(kāi)源的Java圖片處理庫(kù)實(shí)例詳解
Java?圖片處理庫(kù)提供了豐富的功能,用于處理和增強(qiáng)圖像,在Java生態(tài)系統(tǒng)中,有幾個(gè)流行的開(kāi)源庫(kù)可以用于圖片處理,這些庫(kù)提供了豐富的功能,如圖像縮放、裁剪、顏色調(diào)整、格式轉(zhuǎn)換等,本文介紹開(kāi)源的Java圖片處理庫(kù)介紹,感興趣的朋友一起看看吧2024-03-03
IntelliJ IDEA 2021.1 推出語(yǔ)音、視頻功能,邊寫(xiě)代碼邊聊天(功能超級(jí)強(qiáng)大
這篇文章主要介紹了IntelliJ IDEA 2021.1 推出語(yǔ)音、視頻功能,邊寫(xiě)代碼邊聊天(功能超級(jí)強(qiáng)大),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04

