How to add a paragraph or text between Tables in .

2019-08-17 20:29发布

问题:

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:

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();
 }
}