java Apache POI Word existing table insert row wit

2019-03-01 00:14发布

问题:

I'am a biginer in Apache POI and want to extend with some row an exist table in the word tamplate file. If I use that code below, the table will be extended with row bit the new row's cells created normal style.

My goal is the cells have the same table cells style etc (font, with, height...)

    XWPFDocument doc = new XWPFDocument(openFile(fileName));
    XWPFTable tbl = doc.getTableArray(tableIndex);
    XWPFTableRow lastRow = tbl.getRows().get(tbl.getNumberOfRows() - 1);
    cellCounter = lastRow.getTableICells().size(); 
    XWPFTableRow newRow = tbl.createRow(); 
    for (int i = 0; i < data.size() && cellCounter <= data.size(); i++) {         
    String text = data.get(i);
        XWPFTableCell cell = newRow.getCell(i);
        if (cell != null) {
            cell.setText(text);
        }
    }

Thanks for your answer. R.

回答1:

The following code gets an exact copy of the second row in first table contained in document. Then it changes the text contents of the cells in this row. And then inserts this copied row between row 2 and 3 of this table.

The changing the content must be done before table.addRow since the row must be complete before inserting it in List tableRows and adding it to the TrArray of the CTTbl ctTbl. Later changings will not be written into the XML. I've not really got the reason why this is the case.

Then the code gets a copy of the last row and adds this copy at the end of the table. Here also the changing the content must be done before table.addRow.

import java.io.*;
import org.apache.poi.xwpf.usermodel.*;

import  org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;

public class WordInsertTableRow {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc = new XWPFDocument(new FileInputStream("source.docx"));

  XWPFTable table = doc.getTableArray(0);

//insert new row, which is a copy of row 2, as new row 3:
  XWPFTableRow oldRow = table.getRow(1);
  CTRow ctrow = CTRow.Factory.parse(oldRow.getCtRow().newInputStream());
  XWPFTableRow newRow = new XWPFTableRow(ctrow, table);

  int i = 1;
  for (XWPFTableCell cell : newRow.getTableCells()) {
   for (XWPFParagraph paragraph : cell.getParagraphs()) {
    for (XWPFRun run : paragraph.getRuns()) {
     run.setText("New row 3 cell " + i++, 0);
    }
   }
  }

  table.addRow(newRow, 2);

//insert new last row, which is a copy previous last row:
  XWPFTableRow lastRow = table.getRows().get(table.getNumberOfRows() - 1);
  ctrow = CTRow.Factory.parse(lastRow.getCtRow().newInputStream());
  newRow = new XWPFTableRow(ctrow, table);

  i = 1;
  for (XWPFTableCell cell : newRow.getTableCells()) {
   for (XWPFParagraph paragraph : cell.getParagraphs()) {
    for (XWPFRun run : paragraph.getRuns()) {
     run.setText("New last row cell " + i++, 0);
    }
   }
  }

  table.addRow(newRow);

  doc.write(new FileOutputStream("result.docx"));
  doc.close();

 }
}


回答2:

I had the similar situation and I got it to work in a smarter way.

let's say we have table template(as shown in below image) in a word file(template) and we want to populate the table row data dynamically. For this method to work, we have to create a template row which already has the formatting we need for the new rows. You will be using the template row to create the new row and delete the template row after adding all the desired number of rows of same formatting.

    XWPFTable table; //this is the table to be populated..needs to be initialized  as per your need.

   //the row ID of the empty row, which is our template row with all the formatting in it
    int tempateRowId = 1;

    // the empty row
    XWPFTableRow rowTemplate = table.getRow(tempateRowId);

    // iterate over the reportData
     Arrays.stream(reportData).forEach(data -> {
    // create a new row from the template, which would copy the format of previous row
     XWPFTableRow oldRow = rowTemplate;
     CTRow ctrow = null;
       try {
            ctrow = CTRow.Factory.parse(oldRow.getCtRow().newInputStream());
           } catch (XmlException e) {e.printStackTrace();
           } catch (IOException e) { e.printStackTrace();
           }

    XWPFTableRow newRow = new XWPFTableRow(ctrow, table);
         newRow.getCell(0).setText(data.getDataForColumn1());
         newRow.getCell(1).setText(data.getDataForColumn2());

   // adding the newly created row tot he table   
    table.addRow(newRow);
});

table.removeRow(tempateRowId); // removing the template row

}