0
votes

I'm trying to set some paragraph or text in .docx file using Apache POI, I'm reading a .docx file used as template from WEB-INF/resources/templates folder inside my war file, once read, I want to create dynamically more tables starting after 9th table used as template, I'm able to add more tables but other type of content (paragraphs) are arranged in other section of the document ¿is there a required form to do this thing?

XWPFDocument doc = null;
try {
    doc = new XWPFDocument(OPCPackage.open(request.getSession().getServletContext().getResourceAsStream("/resources/templates/twd.docx")));
} catch (Exception e) {
    e.printStackTrace();
} 

XWPFParagraph parrafo = null;
XWPFTable table=null;
org.apache.xmlbeans.XmlCursor cursor = null;
XWPFParagraph newParagraph = null;
XWPFRun run = null;

for(int j=0; j < 3; j++) { //create 3 more tables
    table = doc.getTables().get(9);
    cursor = table.getCTTbl().newCursor();
    cursor.toEndToken();

    if (cursor.toNextToken() != org.apache.xmlbeans.XmlCursor.TokenType.START);
    {
        table = doc.insertNewTbl(cursor);               

        table.getRow(0).getCell(0).addParagraph().createRun()
        .setText("Name");
        table.createRow().getCell(0).addParagraph().createRun().setText("Version");
        table.createRow().getCell(0).addParagraph().createRun().setText("Description");
        table.createRow().getCell(0).addParagraph().createRun().setText("Comments");
        table.createRow().getCell(0).addParagraph().createRun().addCarriageReturn();        

        table.getRow(0).createCell().addParagraph().createRun().setText("some text");
        table.getRow(1).createCell().addParagraph().createRun().setText("some text");
        table.getRow(2).createCell().addParagraph().createRun().setText("some text");
        table.getRow(3).createCell().addParagraph().createRun().setText("some text");

        table.getRows().get(0).getCell(0).setColor("183154");
        table.getRows().get(1).getCell(0).setColor("183154");
        table.getRows().get(2).getCell(0).setColor("183154");
        table.getRows().get(3).getCell(0).setColor("183154");           
        table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(4000));
        table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(4000));
    }

    //OTHER CONTENT BETWEEN CREATED TABLES (PARAGRAPHS, BREAK LINES,ETC)
    doc.createParagraph().createRun().setText("text after table");
}
1
What do you think the code line if (cursor.toNextToken() != org.apache.xmlbeans.XmlCursor.TokenType.START); is doing? Hint: It moves the cursor to the next token and then it does nothing, independent of the token type. It is the same as cursor.toNextToken();. Also your code does not show how you "add ... other type of content (paragraphs)" which "are arranged in other section of the document" then. So your problem is not reproducible.Axel Richter

1 Answers

4
votes

If you once uses a cursor, then you must using that cursor for further inserting content if you wants to be in the document part where the cursor is also. Don't believe, the document automatically will take note of the cursor you created.

So for example:

import java.io.FileOutputStream;
import java.io.FileInputStream;

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

public class WordTextAfterTable {

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

  XWPFDocument document = new XWPFDocument(new FileInputStream("WordTextAfterTable.docx"));

  XWPFTable table = document.getTables().get(9);

  org.apache.xmlbeans.XmlCursor cursor = table.getCTTbl().newCursor();
  cursor.toEndToken(); //now we are at end of the CTTbl
  //there always must be a next start token after the table. Either a p or at least sectPr.
  while(cursor.toNextToken() != org.apache.xmlbeans.XmlCursor.TokenType.START); //we loop over the tokens until next TokenType.START
  //now we are at next TokenType.START and insert the new table
  //note: This is immediately after the table. So both tables touch each other.
  table = document.insertNewTbl(cursor);     
  table.getRow(0).getCell(0).addParagraph().createRun().setText("Name");
  table.createRow().getCell(0).addParagraph().createRun().setText("Version");
  table.createRow().getCell(0).addParagraph().createRun().setText("Description");
  table.createRow().getCell(0).addParagraph().createRun().setText("Comments");
  table.createRow().getCell(0).addParagraph().createRun().addCarriageReturn();        
  //...
System.out.println(cursor.isEnd()); //cursor is now at the end of the new table
  //there always must be a next start token after the table. Either a p or at least sectPr.
  while(cursor.toNextToken() != org.apache.xmlbeans.XmlCursor.TokenType.START); //we loop over the tokens until next TokenType.START
  XWPFParagraph newParagraph = document.insertNewParagraph(cursor);
  XWPFRun run = newParagraph.createRun(); 
  run.setText("text after table");

  document.write(new FileOutputStream("WordTextAfterTableNew.docx"));
  document.close();
 }
}