Martin Kehrholff
Martin Kehrholff

Reputation: 83

How to Concatinate 2 Cells in a XWPFTableRow

I would like to build a Table with a Cell span in one Row. The span over two Cells works fine, but the Span Command doesn't concatenates the two Cells to one, like Word in would do.

The Span Command moves the right Border of the first Cell to the right Border of the second cell.

The result is, that in the Row with the Span is now one more Cell as in the other Rows.

The additional Cell is empty but visible.

I could not remove the needless Cell. The removeCell Command to the needless Cell seems to work, because a Test with a following setText Command in this Cell results in a java.lang.IndexOutOfBoundsException, but in the Word File ist the needless Cell already visible.

Has any one an Idea to resolve this Problem?

My Setup: Win7-64 dom4j-1.6.1.jar ooxml-schemas-1.1.jar poi-3.12-20150511.jar poi-excelant-3.12-20150511.jar poi-ooxml-3.12-20150511.jar poi-ooxml-schemas-3.12-20150511.jar poi-scratchpad-3.12-20150511.jar xmlbeans-2.6.0.jar

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
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;

public class MainCreateTable {

    public static void setCellSpan(XWPFTableCell cell, int span) {
        if (cell.getCTTc().getTcPr() == null) {
            cell.getCTTc().addNewTcPr();
        }
        if (cell.getCTTc().getTcPr().getGridSpan() == null) {
            cell.getCTTc().getTcPr().addNewGridSpan();
        }
        cell.getCTTc().getTcPr().getGridSpan().setVal(BigInteger.valueOf((long) span));
    }

    /**
     *
     * expected Table
     * 
     * ---------------------------------------------|<br>
     * | row 1 cell 1 | row 1 cell 2 | row 1 cell 3 |<br>
     * ---------------------------------------------|<br>
     * | row 2 cell 1                | row 2 cell 2 |<br>
     * ---------------------------------------------|<br>
     * | row 3 cell 1 | row 3 cell 2 | row 3 cell 3 |<br>
     * ---------------------------------------------|<br>
     *
     * generated Table: with an additional empty Cell in Row 2
     * 
     * ---------------------------------------------|<br>
     * | row 1 cell 1 | row 1 cell 2 | row 1 cell 3 |<br>
     * ---------------------------------------------|-|<br>
     * | row 2 cell 1                | row 2 cell 2 | |<br>
     * ---------------------------------------------|-|<br>
     * | row 3 cell 1 | row 3 cell 2 | row 3 cell 3 |<br>
     * ---------------------------------------------|<br>
     *
     */
    public void makeTable() throws IOException {
        String docName = MainCreateTable.class.getSimpleName();
        XWPFDocument document = new XWPFDocument();

        XWPFTable table = document.createTable();
        XWPFTableRow tableRowOne = table.getRow(0);
        tableRowOne.getCell(0).setText("   row 1 cell 1   ");
        tableRowOne.addNewTableCell().setText("   row 1 cell 2   ");
        tableRowOne.addNewTableCell().setText("   row 1 cell 3   ");

        XWPFTableRow tableRowTwo = table.createRow();
        tableRowTwo.getCell(0).setText("   row 2 cell 1   ");
        tableRowTwo.getCell(1).setText("   row 2 cell 2   ");
        setCellSpan(tableRowTwo.getCell(0), 2);
        //tableRowTwo.removeCell(2);
        //tableRowTwo.getCell(2).setText("   row 2 cell 3   ");

        XWPFTableRow tableRowThree = table.createRow();
        tableRowThree.getCell(0).setText("   row 3 cell 1   ");
        tableRowThree.getCell(1).setText("   row 3 cell 2   ");
        tableRowThree.getCell(2).setText("   row 3 cell 3   ");

        FileOutputStream out = new FileOutputStream(new File(docName + ".docx"));
        document.write(out);
        out.close();
    }

    public static void main(String[] args) throws Exception {
        MainCreateTable mainCreateTable = new MainCreateTable();
        mainCreateTable.makeTable();
    }
}

Upvotes: 1

Views: 799

Answers (1)

powepig
powepig

Reputation: 21

Apparently XWPFTableRow only removes the reference from the wrapper object but leaves the XML Nodes inside of the document. To remove them you have to remove the elements from the CTRow CTTc Array like this:

CTRow ctRow = row.getCtRow(); //row being a XWPFTableRow
CTTc[] ctTcs = new CTTc[2]; //the column count of the remaining elements 
//Fill the elements leaving out the third element
for(int i = 0; i < ctRow.sizeOfTcArray(); i++) { 
    if(i != 2) {
        ctTcs[i] = ctRow.getTcArray(i);
    }
}
ctRow.setTcArray(ctTcs);

I think it's not a bad idea to still use XWPFTableRow.remove(int) to keep the wrappers up to date, but this solution works for me. Since you are only leaving out elements at the end this test shouldn't be neccessary as you could simply use ctTcs.length

Upvotes: 2

Related Questions