Preetam
Preetam

Reputation: 49

Avoid dynamic table rows with different number of rows to flow to different pages in an XWPFDocument(Apache POI)

I have created a code to create a word document on the fly using Apache POI API. The document is expected to have some tables with varying number of rows(number of columns are fixed). Currently I have placed each table onto different pages. I need to know or is there any way to start placing tables one below another, if a page break is found, shift that table on next page and then subsequent table continues below? I tried the below(where document is XWPFDocument), but it didn't worked

XWPFTable table1 = document.createTable();
XWPFTableRow tableRow1 = table1.createRow();
tableRow1.setCantSplitRow(true);

Upvotes: 2

Views: 1956

Answers (1)

Axel Richter
Axel Richter

Reputation: 61945

The XWPFTableRow.setCantSplitRow does only control whether the table row itself may be divided by a page break.

But what you wants is Keep text together. So we need to use CTPPrBase.addNewKeepNext. If this is set ON or true, then this paragraph should not be divided from the next paragraph. Also we schould set CTPPrBase.addNewKeepLines to ON or true. This means: Don't split the paragraph itself.

Example:

import java.io.FileOutputStream;

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

//import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; // up to Apache POI 4

import java.util.Random;

public class CreateWordTableKeepTogether {

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

  int numtables = 5;
  int numrows;
  Random random = new Random();
  int numcols = 5;

  XWPFDocument document = new XWPFDocument();

  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("The tables:");

  for (int t = 0; t < numtables; t++) {

   numrows = random.nextInt(10) + 3;

   paragraph = document.createParagraph();
   run = paragraph.createRun();
   run.setText("Table " + (t+1));

   //don't split the paragraph itself
   //paragraph.getCTP().addNewPPr().addNewKeepLines().setVal(STOnOff.ON); // up to Apache POI 4
   paragraph.getCTP().addNewPPr().addNewKeepLines().setVal(true); // since Apache POI 5
   //keep this paragraph together with the next paragraph
   //paragraph.getCTP().getPPr().addNewKeepNext().setVal(STOnOff.ON); // up to Apache POI 4
   paragraph.getCTP().getPPr().addNewKeepNext().setVal(true); // since Apache POI 5

   XWPFTable table = document.createTable();

   for (int r = 0; r < numrows; r++) {
    XWPFTableRow row = table.getRow(r);
    if (row == null) row = table.createRow();

    //don't divide this row
    row.setCantSplitRow(true);

    for (int c = 0; c < numcols; c++) {
     XWPFTableCell cell = row.getCell(c);
     if (cell == null) cell = row.createCell();
     paragraph = cell.getParagraphArray(0);
     if (paragraph == null) paragraph = cell.addParagraph();
     run = paragraph.createRun();
     run.setText("T" + (t+1) + "R" + (r+1) + "C" + (c+1));

     if (c == 0) { //only necessary for column one, since further columns in this row are protected by setCantSplitRow
      //paragraph.getCTP().addNewPPr().addNewKeepLines().setVal(STOnOff.ON); // up to Apache POI 4
      //paragraph.getCTP().getPPr().addNewKeepNext().setVal(STOnOff.ON); // up to Apache POI 4
      paragraph.getCTP().addNewPPr().addNewKeepLines().setVal(true); // since Apache POI 5
      paragraph.getCTP().getPPr().addNewKeepNext().setVal(true); // since Apache POI 5
     }

    }  
   }

   //this is necessary, since it is the only paragraph which allows page breaks
   paragraph = document.createParagraph();

  }
  
  FileOutputStream out = new FileOutputStream("./CreateWordTableKeepTogether.docx");
  document.write(out);
  out.close();
  document.close();

 }
}

Upvotes: 3

Related Questions