java解析.docx格式文檔,XWPFTable解析換行符,以及wps和office在讀寫.docx文檔時段落結構不同的大坑


需求

從前端傳來一個.docx文檔,后端解析該文檔里的表格,對其中的數據進行處理。

(我也不知道為什么非要解析word文檔里面的表格,而不是直接傳一個excel。)

實現

1.前端用的elementui-upload,把整個.docx文件傳給后端。

2.后端controller接收這個文檔,注意接收的格式是MultipartFile不是file,不然就報500了。

3.后端service解析這個文檔:

public Map < String, Object > dealWord(MultipartFile file) throws IOException {
		// 3.1 解析整個文檔
		XWPFDocument xwpf = new XWPFDocument(file.getInputStream());
		// 3.2 從文檔中獲取表格的迭代器
		Iterator < XWPFTable > it = xwpf.getTablesIterator();
		// 3.3 遍歷所有的表格,挨個解析
		while (it.hasNext()) {
			// 3.3.1 獲取到當前的表格
			XWPFTable table = it.next();
			// 3.3.2 獲取到行數據
			List < XWPFTableRow > rows = table.getRows();
			// 3.3.3 遍歷每行,獲取每個單元格
			for (int i = 1; i < rows.size(); i++) {
				XWPFTableRow row = rows.get(i);
				List<XWPFTableCell> cells = row.getTableCells();
				// 3.3.4 獲取每個單元格里面的文字
				for(int j = 0;j<cells.size();j++){
					String text = cells.get(j).getText()
				}
			}
		}

如果只需要獲取每個單元格內的文字內容,不考慮換行,那么到這里就結束了。

如果需要解析單元格內的換行符,請繼續往下看。

接下來介紹這里面的大坑。

一開始我以為XWPFTable是不能解析到換行符的,后來覺得怎么可能,就具體看了下XWPFTable里面的數據的結構。

但是用wps和office讀寫過的.docx文檔,解析出來的段落結構是不一樣的!

不過很好做兼容。

這里順便介紹下解析出來的結構吧!

以如下表格為例(WPS讀寫版本):

這個表格解析出來的數據是類似於這樣的:

字段解釋:

這里的runs我也不知道怎么解釋...看了看官方文檔也不太明白,希望有所了解的朋友可以補充。

wps和word讀寫過的表格,就是在runs這里發生了差異。

圖中可以看到,里面的一個段落paragrah里面有一個run對象,就是單元格1.
三個段落,各自有一個run對象。

但是在office讀寫過的表格里,這里可能有多個run對象,也就是單元格1可能被拆成多個run對象。

可以對比着看一下:

這里的單元格1被拆解成了單元格和1兩個run對象。

探究office

閑着也是閑着,探究一下office里面run對象的數量的規則吧。

推測:以數據類型分割整個段落的文字,表格是字符串文字,1是數字。

現在我們要解析的offcie讀寫的表格:

解析出來的結果:

對比一下:

這就有點整不明白了吧....以我有限的知識水平,不知道為什么要把3和L拆開,但又把4L%合並成一個run對象了....

解決辦法

這個問題挺好解決的:

要獲取單元格內的第一排內容:
獲取到tableCell,獲取所有的paragrahs,獲取第一個paragrah,遍歷獲取這個paragrah里面所有的runs.

這樣就同時能適配wps和office啦。

上一段代碼:

public Map < String, Object > dealWord(MultipartFile file) throws IOException {
		// 3.1 解析整個文檔
		XWPFDocument xwpf = new XWPFDocument(file.getInputStream());
		// 3.2 從文檔中獲取表格的迭代器
		Iterator < XWPFTable > it = xwpf.getTablesIterator();
		// 3.3 遍歷所有的表格,挨個解析
		while (it.hasNext()) {
			// 3.3.1 獲取到當前的表格
			XWPFTable table = it.next();
			// 3.3.2 獲取到行數據
			List < XWPFTableRow > rows = table.getRows();
			// 3.3.3 遍歷每行,獲取每個單元格
			for (int i = 1; i < rows.size(); i++) {
				XWPFTableRow row = rows.get(i);
				List<XWPFTableCell> cells = row.getTableCells();
				// 3.3.4 獲取每個單元格里面的文字
				for(int j = 0;j<cells.size();j++){
					String text = cells.get(j).getText()
				}
				// 3.3.5 獲取單元格里面的第一段內容
				// 如果想要獲取所有段的內容 用ArrayList接收一下哈 這里不演示了
				for(int k = 0;k<cells.getParagraphs().size();k++){
					String text = "";
					// 遍歷第一段里面所有的run 注意這里只get了0的段落
					for(int p = 0;p<cells.getParagraphs().get(0).getRuns().size();p++){
						text = text + cells.getParagraphs().get(0).getRuns().get(p);
					}
					System.out.prrintln("單元格第一排的內容是:"+text);
				}
			}
		}

是很簡單的一個遍歷啦,很容易適配,就寫到這里了噢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM