关于JAVA POI解析WPS docx文档中的table(复杂表格包含单元格横向,纵向的合并)
首先,关于poi解析表格先阅读一篇他人的博客
使用poi读取word2007(.docx)中的复杂表格.
这篇博客提到了,如何用poi将单元格合并。
static void mergeCellHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
for(int colIndex = fromCol; colIndex <= toCol; colIndex++){
CTHMerge hmerge = CTHMerge.Factory.newInstance();
if(colIndex == fromCol){
// The first merged cell is set with RESTART merge value
hmerge.setVal(STMerge.RESTART);
} else {
// Cells which join (merge) the first one, are set with CONTINUE
hmerge.setVal(STMerge.CONTINUE);
}
XWPFTableCell cell = table.getRow(row).getCell(colIndex);
// Try getting the TcPr. Not simply setting an new one every time.
CTTcPr tcPr = cell.getCTTc().getTcPr();
if (tcPr != null) {
tcPr.setHMerge(hmerge);
} else {
// only set an new TcPr if there is not one already
tcPr = CTTcPr.Factory.newInstance();
tcPr.setHMerge(hmerge);
cell.getCTTc().setTcPr(tcPr);
}
}
}
记住CTTcPr 这个类,他包装了单元格的格式信息
CTTcPr tcPr = cell.getCTTc().getTcPr();
但是,当我开始解析wps的docx后发现横向合并的单元格信息根本拿不到。就是HMerge这个对象。一直为空。VMerge倒是没问题。
打开docx文件的xml文件一看发现了问题
<w:tc>
<w:tcPr>
<w:tcW w:w="1000" w:type="dxa"/>
<w:hMerge w:val="restart"/>
</w:tcPr>
<w:p>
<w:r>
<w:t>row 1, col 2</w:t>
</w:r>
</w:p>
</w:tc>
这是我们期望的格式
<w:tc>
<w:tcPr>
<w:tcW w:w="1000" w:type="dxa"/>
<w:gridSpan w:val="2"/>
</w:tcPr>
<w:p>
<w:r>
<w:t>row 1, col 2</w:t>
</w:r>
</w:p>
</w:tc>
wps docx打开是这样的。区别在于hMerge 和gridSpan
hMerge不释放td对象。比如一行5列。1-2合并
那么在poi里得到5个cell对象。1的hMerge枚举为started。2为continue。
gridSpan反之。1-2合并,只能拿到4个cell。
虽然费了一般波折,总算可以解析出来了。废话不多
说。先看效果,再上代码
这是docx文档中的表格
这是解析,并用html生成的table
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.junit.Test;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas