在内容之间插入 XWPFTable

Inserting XWPFTable in between contents

嗨,我想在一些内容之间插入一个 XWPFTable。文件内容固定,文件作为输入。我需要在特定字段中插入 table。

像这样:

Stack Overflow 是一个私人网站,是 Stack Exchange Network 的旗舰网站,由 Jeff Atwood 和 Joel Spolsky 于 2008 年创建。这是 table.

创建内容 continue.It 是为了更开放地替代早期的问答网站,例如 Experts-Exchange。

谢谢

我写的代码

public static void main(String[] args) throws IOException {
        XWPFDocument document = new XWPFDocument(new FileInputStream(new File("input.docx")));
        FileOutputStream out = new FileOutputStream(new File("output.docx"));
        XmlCursor cursor = null;
         List<IBodyElement> elements = document.getBodyElements();
         for (int n = 0; n < elements.size(); n++) {
             IBodyElement element = elements.get(n);
             if (element instanceof XWPFParagraph) {
                 XWPFParagraph p1 = (XWPFParagraph) element;
                 List<XWPFRun> runList = p1.getRuns();
                 StringBuilder sb = new StringBuilder();
                 for (XWPFRun run : runList)
                     sb.append(run.getText(0));
                 if (sb.toString().contains("Text after which table should be created")) {
                      cursor= p1.getCTP().newCursor();
                      break;
             }
         }
    } 
         XWPFParagraph p = document.insertNewParagraph(cursor);
         XWPFTable table = p.getBody().insertNewTbl(cursor);
         XWPFTableRow tableRowOne = table.createRow();

        //other codes for generating the table  

我在创建行时遇到空指针异常。

我不确定 XWPFDocument.insertTable() 中的任何一种方法是否都能正常工作。我注意到的一件事是你有:

XWPFParagraph p = document.insertNewParagraph(cursor);
XWPFTable table = p.getBody().insertNewTbl(cursor);

相当于:

XWPFParagraph p = document.insertNewParagraph(cursor);
XWPFTable table = document.insertNewTbl(cursor);

这让我想知道您是否对 table 在文档中的位置感到困惑。段落和表格是适当的兄弟姐妹。段落不包含 table,但表格可以在 table 个单元格中包含段落(和其他 table)。

段落主体实际上是包含段落的部分。可以是文档部分,也可以是header/footer部分,也可以是评论部分等。但是,XWPFParagraph.getBody()不是指段落的内容。相反,它指的是段落的父部分。

已测试。我的怀疑是对的。在 XWPFParagraph p = document.insertNewParagraph(cursor); 之后,光标在代码中的错误位置。所以XWPFTable table = p.getBody().insertNewTbl(cursor);无法插入,然后是null

但是还有更多的问题。如果找到文本,我们将在 之后 的段落中放置 table。所以我们需要将光标移动到下一段。但是,如果没有下一段怎么办?然后需要创建一个新段落。幸运的是 XmlCursor.toNextSibling 标记是否成功。

示例:

模板:

代码:

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

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

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;

import org.apache.xmlbeans.XmlCursor;
import java.math.BigInteger;


public class WordInsertTableInBody {

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

  XWPFDocument document = new XWPFDocument(new FileInputStream("WordTableExample.docx"));
  XmlCursor cursor = null;
  XWPFParagraph paragraph = null; 
  XWPFRun run = null; 

  boolean foundTablePosition = false;
  boolean thereWasParagraphAfter = false;
  for (IBodyElement element : document.getBodyElements()) {
   if (element instanceof XWPFParagraph) {
    paragraph = (XWPFParagraph) element;
    StringBuilder sb = new StringBuilder();
    for (XWPFRun irun : paragraph.getRuns()) {
     sb.append(irun.getText(0));
System.out.println(sb);
     if (sb.toString().contains("Text after which table should be created")) {
      cursor= paragraph.getCTP().newCursor();
      thereWasParagraphAfter = cursor.toNextSibling(); // move cursor to next paragraph 
       //because the table shall be **after** that paragraph
       //thereWasParagraphAfter is true if there is a next paragraph, else false
      foundTablePosition = true;
     }
    }
   }
   if (foundTablePosition) break;
  } 

  if (cursor != null) {
   if (thereWasParagraphAfter) {
    paragraph = document.insertNewParagraph(cursor);
   } else {
    paragraph = document.createParagraph();
   }
   cursor = paragraph.getCTP().newCursor();
   XWPFTable table = document.insertNewTbl(cursor);
   XWPFTableRow row = table.getRow(0); if (row == null) row = table.createRow();
   int twipsPerInch =  1440;
   table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(1*1440));
   for (int col = 1 ; col < 4; col++) {
    table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1*1440));
   }
   for (int i = 0; i < 4; i++) {
    XWPFTableCell cell = row.getCell(i); if (cell == null) cell = row.createCell();
    CTTblWidth tblWidth = cell.getCTTc().addNewTcPr().addNewTcW();
    tblWidth.setW(BigInteger.valueOf(1 * twipsPerInch));
    tblWidth.setType(STTblWidth.DXA);
    if (cell.getParagraphs().size() > 0 ) paragraph = cell.getParagraphs().get(0); else paragraph = cell.addParagraph();
    run = paragraph.createRun();
    run.setText("Table Cell " + i);
   }
  }

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

结果: