5

I need to have a table with the cells on the first and second row merged.

Something like this:

Image of table (I can't post pics) https://i.stack.imgur.com/dAO6j.png

I have been reviewing all the questions related to this topic and I have found some answers for applying grid span to the cells, but I couldn't find a real solution.

Here is the code I have from examples obtained from google and from this site:

    XWPFDocument document = new XWPFDocument();
    XWPFTable table = document.createTable(7, 2);

    fillTable(table);

    XWPFTableCell cellRow1 = table.getRow(0).getCell(0);
    XWPFTableCell cellRow2 = table.getRow(1).getCell(0);

    cellRow1.getCTTc().addNewTcPr();
    cellRow1.getCTTc().getTcPr().addNewGridSpan();
    cellRow1.getCTTc().getTcPr().getGridSpan().setVal(BigInteger.valueOf(2L));

    cellRow2.getCTTc().addNewTcPr();
    cellRow2.getCTTc().getTcPr().addNewGridSpan();
    cellRow2.getCTTc().getTcPr().getGridSpan().setVal(BigInteger.valueOf(2L));

    FileOutputStream out = new FileOutputStream("Table.docx");
    doc.write(out);
    out.close();

What I get from this code is the following:

enter image description here

I tried to remove the "extra" cells with table.getRow(0).removeCell(1); but it didn't work, am I doing something wrong?

Mike
  • 706
  • 7
  • 16
JuanDeLaMora
  • 61
  • 1
  • 1
  • 7

3 Answers3

4

It seems xml has to be removed as well:

 XWPFTableCell removed = tableRow.getCell(idx);
 removed.getCTTc().newCursor().removeXml();
 tableRow.removeCell(idx);
  • it did work, thank you very much I just needed to removed like this: `cellRow = table3.getRow(0).getCell(2); cellRow.getCTTc().newCursor().removeXml(); cellRow = table3.getRow(0).getCell(1); cellRow.getCTTc().newCursor().removeXml();` – JuanDeLaMora Apr 27 '15 at 22:33
  • Need to remove the cell from the table before removing the XML..else NPE happens – java-addict301 Feb 21 '18 at 17:01
4

To merge horizontally/vertically you need to create 2 CTHMerge and use the setVal:

  • one for the cells that you will remain (STMerge.RESTART);
  • a second one for the merged cells (STMerge.CONTINUE);

a) example of a horizontal merge for a 2x2 table:

|___________|___________| --> |___________ ___________|
|___________|___________| --> |___________ ___________|

// First Row
CTHMerge hMerge = CTHMerge.Factory.newInstance();
vmerge.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();
hMerge.setVal(STMerge.CONTINUE);
table.getRow(0).getCell(1).getCTTc().getTcPr().setHMerge(hMerge1);
table.getRow(1).getCell(1).getCTTc().getTcPr().setHMerge(hMerge1);

b) example of a vertical merge:

 // 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();
vmerge.setVal(STMerge.CONTINUE);
table.getRow(1).getCell(0).getCTTc().getTcPr().setVMerge(vmerge1);
table.getRow(1).getCell(1).getCTTc().getTcPr().setVMerge(vmerge1);
Jose1755
  • 378
  • 3
  • 10
  • That's a neat solution. However, if you are planning to convert docx to other formats later, keep in mind, that many libaries do not support this tag – Ermintar Jan 13 '21 at 15:37
0

You can also avoid creating the extra cells, instead of removing cells after the merge. It requires adding rows and cells sequentially (instead of using document.createTable())

For your example it would be:

  1. Create first rows with 1 cell, set text
  2. Create next row, and in it create new cell, set text
  3. Create next rows and set text
  4. Merge
golimar
  • 2,419
  • 1
  • 22
  • 33