如何在Java的POI中使用XWPFTable合并单元格(或应用colspan)?

如何在Java的POI中使用XWPFTable合并单元格(或应用colspan)?,java,apache-poi,xwpf,Java,Apache Poi,Xwpf,在poi中创建一个表非常简单,但它的教程非常有限,我找不到一个可以在生成docx文件时在表中创建简单合并单元格的教程。如果您创建了表、表中的行和行中的单元格,您可以将gridSpan添加到单元格属性: if (cell.getCTTc().getTcPr() == null) cell.getCTTc().addNewTcPr(); if (cell.getCTTc().getTcPr().getGridSpan() == null) cell.getCTTc().getTcPr().addNe

在poi中创建一个表非常简单,但它的教程非常有限,我找不到一个可以在生成docx文件时在表中创建简单合并单元格的教程。

如果您创建了表、表中的行和行中的单元格,您可以将gridSpan添加到单元格属性:

if (cell.getCTTc().getTcPr() == null) cell.getCTTc().addNewTcPr();
if (cell.getCTTc().getTcPr().getGridSpan() == null) cell.getCTTc().getTcPr().addNewGridSpan();
cell.getCTTc().getTcPr().getGridSpan().setVal(2);

注意:单元格是org.apache.poi.xwpf.usermodel.XWPFTableCell。

为每个表行创建一个单独的
XWPFTable
,这样可以工作,应该很好。所有表在后台合并到最终word文档中的一个表中。您将需要所有这些jar,
poi-3.9.jar
poi-ooxml-3.9.jar
poi-ooxml-schemas-3.9.jar

XWPFTable table1 = document.createTable(1,1); // This is your row 1
XWPFTable table2 = document.createTable(1,3); // This is your row 2

// Now it's time to span each column of table1 and table2 to a span of your choice
// lets say 6 is the total span required assuming there's some row with 6 columns.

spanCellsAcrossRow(table1, 0, 0, 6);
spanCellsAcrossRow(table2, 0, 0, 2);
spanCellsAcrossRow(table2, 0, 1, 2);
spanCellsAcrossRow(table2, 0, 2, 2);

private void spanCellsAcrossRow(XWPFTable table, int rowNum, int colNum, int span) {
    XWPFTableCell  cell = table.getRow(rowNum).getCell(colNum);
    cell.getCTTc().getTcPr().addNewGridSpan();
    cell.getCTTc().getTcPr().getGridSpan().setVal(BigInteger.valueOf((long)span));
}

要水平/垂直合并,您需要创建2个CTHMerge并使用setVal:

  • 一个用于您将保留的单元格(STMerge.RESTART)
  • 第二个用于合并单元格(STMerge.CONTINUE)
a) 2x2表格的水平合并示例:

|
|
___________|

 // First Row
CTHMerge hMerge = CTHMerge.Factory.newInstance();
hMerge.setVal(STMerge.RESTART);
table.getRow(0).getCell(0).getCTTc().getTcPr().setHMerge(hMerge);
table.getRow(1).getCell(0).getCTTc().getTcPr().setHMerge(hMerge);

 // Secound Row cell will be merged/"deleted"
CTHMerge hMerge1 = CTHMerge.Factory.newInstance();
hMerge1.setVal(STMerge.CONTINUE);
table.getRow(0).getCell(1).getCTTc().getTcPr().setHMerge(hMerge1);
table.getRow(1).getCell(1).getCTTc().getTcPr().setHMerge(hMerge1);
b) 垂直合并的示例


当然,我对这个答案投了赞成票。我不认为有一种方式可以接受作为答案,因为我没有问最初的问题。让我知道这是否可行。嗨,我尝试过使用它,它确实正确地设置了单元格的跨度,但我在表外(右侧)保留了与跨度大小相等的单元格。我试图通过使用XWPFTableRow.removeCell(pos)删除它们来修剪它们。我确认它们已在java行对象中删除,但当表呈现并在Word中查看时,它们仍然存在。你知道如何去除这些多余的细胞吗?我不太清楚,但对于每个表,总跨度必须是相同的。如果它不相等,您将看到额外的列,首先通过确定最大的行来固定总跨度,例如一行有15列,然后在我的回答中,第一个表的第一列有15个跨度,第二个表的3列中每列可以有5个跨度。谢谢。这完全有道理。非常感谢您的帮助。您的解决方案对我很有效,但我添加了:
if(cell.getCTTc().getcpr()==null)cell.getCTTc().addnewtcr()为什么supegroupRow.getCell(0.getCTTc().GetCpr()为空?
 // First Row
CTVMerge vmerge = CTVMerge.Factory.newInstance();
vmerge.setVal(STMerge.RESTART);
table.getRow(0).getCell(0).getCTTc().getTcPr().setVMerge(vmerge);
table.getRow(0).getCell(1).getCTTc().getTcPr().setVMerge(vmerge);
 
 // Secound Row cell will be merged 
CTVMerge vmerge1 = CTVMerge.Factory.newInstance();
vmerge1.setVal(STMerge.CONTINUE);
table.getRow(1).getCell(0).getCTTc().getTcPr().setVMerge(vmerge1);
table.getRow(1).getCell(1).getCTTc().getTcPr().setVMerge(vmerge1);