POI指定位置插入表格发生XmlValueDisconnectedException异常

异常情况

在docx文档表格里指定位置再插入表格,具体示例请看POI指定位置插入表格,发生如下异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Caused by: org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1258)
at org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTTcImpl.getTcPr(Unknown Source)
at fr.opensagres.poi.xwpf.converter.core.utils.XWPFTableUtil.getGridSpan(XWPFTableUtil.java:266)
at fr.opensagres.poi.xwpf.converter.core.utils.XWPFTableUtil.getNumberOfColumns(XWPFTableUtil.java:241)
at fr.opensagres.poi.xwpf.converter.core.utils.XWPFTableUtil.computeColWidths(XWPFTableUtil.java:113)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.visitTable(XWPFDocumentVisitor.java:898)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.visitBodyElements(XWPFDocumentVisitor.java:235)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.visitTableCellBody(XWPFDocumentVisitor.java:1141)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.visitCell(XWPFDocumentVisitor.java:1076)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.visitTableRow(XWPFDocumentVisitor.java:978)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.visitTableBody(XWPFDocumentVisitor.java:918)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.visitTable(XWPFDocumentVisitor.java:900)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.visitBodyElements(XWPFDocumentVisitor.java:235)
at fr.opensagres.poi.xwpf.converter.core.XWPFDocumentVisitor.start(XWPFDocumentVisitor.java:183)
at fr.opensagres.poi.xwpf.converter.pdf.PdfConverter.doConvert(PdfConverter.java:57)
... 62 more

在指定位置插入表格的关键代码如下:

1
2
3
4
// 得到这个指定位置的游标
XmlCursor cursor = paragraph.getCTP().newCursor();
// 在cursor插入表格
XWPFTable tableOne = cell.insertNewTbl(cursor);// ---这个是关键

debug很久找到原因是在执行上面代码出现后,插入的表格自动生成了一行,刚好这一行就是一个String的错误。所以在转PDF时,当在循环处理此表格的每一行时,读到第一行就报这个异常。如果是直接输出Word文档就没有问题。

处理方法

处理办法就是在执行插入表格后,删除第一行,就行了。

1
2
3
4
5
6
7
// 得到这个指定位置的游标
XmlCursor cursor = paragraph.getCTP().newCursor();
// 在cursor插入表格
XWPFTable tableOne = cell.insertNewTbl(cursor);// ---这个是关键

// 删除第一行
boolean a = tableOne.removeRow(0);