簡體   English   中英

使用 apache poi 插入不同數量的標題和表格

[英]Insert varying amount of headings and tables with apache poi

我想在 word 文檔中插入不同數量的文本。 例如

Heading 1
  Subheading 1
    Table 1
  Subheading 2
    Table 2

在 word 文檔中找到正確位置后,我使用了 cursor,但不知道如何在該 position 上創建多個內容。 我讓它與帶有文本的單個段落一起工作。 我還嘗試在 while 語句之后使用 for 循環,但 createRun 方法引用了 null 的段落,因此引發了錯誤。

XmlCursor cursor = table.getCTTbl().newCursor();
cursor.toEndToken();
while (cursor.toNextToken() != org.apache.xmlbeans.XmlCursor.TokenType.START);
    XWPFParagraph newParagraph = document.insertNewParagraph(cursor);
    XWPFRun run = newParagraph.createRun();
    run.setText("inserted new text " + "\n");

XmlCursor需要在文檔中正確的 position 上創建。 那一定不是 position,它不在開始令牌之前。 並且不能是不能包含段落或表格的任何其他正文元素內的 position。

要在啟動令牌之前正確調整 cursor,請使用以下方法:

 /*modifiers*/ XmlCursor setCursorToNextStartToken(XmlObject object) {
  XmlCursor cursor = object.newCursor();
  cursor.toEndToken(); //Now we are at end of the XmlObject.
  //There always must be a next start token.
  while(cursor.hasNextToken() && cursor.toNextToken() != org.apache.xmlbeans.XmlCursor.TokenType.START);
  //Now we are at the next start token and can insert new things here.
  return cursor;
 }

但是XmlObject object需要是一個正文元素,它位於文本正文的 position 處,允許添加段落或表格。

讓我們再舉一個完整的例子:

如果 WordTemplate.docx 看起來像...

在此處輸入圖像描述

...然后下面的代碼

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

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

import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;

public class WordCopyTableAfterTable {

 static XmlCursor setCursorToNextStartToken(XmlObject object) {
  XmlCursor cursor = object.newCursor();
  cursor.toEndToken(); //Now we are at end of the XmlObject.
  //There always must be a next start token.
  while(cursor.hasNextToken() && cursor.toNextToken() != org.apache.xmlbeans.XmlCursor.TokenType.START);
  //Now we are at the next start token and can insert new things here.
  return cursor;
 }

 static void removeCellValues(XWPFTableCell cell) {
  for (XWPFParagraph paragraph : cell.getParagraphs()) {
   for (int i = paragraph.getRuns().size()-1; i >= 0; i--) {
    paragraph.removeRun(i);
   }  
  }
 }

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

  //The data. Each row a new table.
  String[][] data= new String[][] {
   new String[] {"John Doe", "5/23/2019", "1234.56"},
   new String[] {"Jane Doe", "12/2/2019", "34.56"},
   new String[] {"Marie Template", "9/20/2019", "4.56"},
   new String[] {"Hans Template", "10/2/2019", "4567.89"}
  };

  String value;
  XWPFDocument document = new XWPFDocument(new FileInputStream("WordTemplate.docx"));
  XWPFTable tableTemplate;
  CTTbl cTTblTemplate;
  XWPFTable tableCopy;
  XWPFTable table;
  XWPFTableRow row;
  XWPFTableCell cell;
  XmlCursor cursor;
  XWPFParagraph paragraph;
  XWPFRun run;
  
  // get Heading 2 style
  XWPFStyles styles = document.getStyles();
  XWPFStyle style = styles.getStyleWithName("Heading 2"); if (style == null) style = styles.getStyleWithName("heading 2");
  String heading2StyleId = (style != null)?style.getStyleId():"";
  
  //get first table (the template)
  tableTemplate = document.getTableArray(0);
  cTTblTemplate = tableTemplate.getCTTbl();
  cursor = setCursorToNextStartToken(cTTblTemplate);

  //fill in first data in first table (the template)
  for (int c = 0; c < data[0].length; c++) {
   value = data[0][c];
   row = tableTemplate.getRow(1);
   cell = row.getCell(c);
   removeCellValues(cell);
   cell.setText(value);
  }

  paragraph = document.insertNewParagraph(cursor); //insert new empty paragraph
  cursor = setCursorToNextStartToken(paragraph.getCTP());

  //fill in next data, each data row in one table
  for (int t = 1; t < data.length; t++) {
   paragraph = document.insertNewParagraph(cursor); //insert new empty paragraph
   paragraph.setStyle(heading2StyleId); //style it Heading 2
   run = paragraph.createRun(); 
   run.setText("Subheading " + (t+1));
   cursor = setCursorToNextStartToken(paragraph.getCTP());
     
   table = document.insertNewTbl(cursor); //insert new empty table at position t
   cursor = setCursorToNextStartToken(table.getCTTbl());

   tableCopy = new XWPFTable((CTTbl)cTTblTemplate.copy(), document); //copy the template table

   //fill in data in tableCopy
   for (int c = 0; c < data[t].length; c++) {
    value = data[t][c];
    row = tableCopy.getRow(1);
    cell = row.getCell(c);
    removeCellValues(cell);
    cell.setText(value);
   }
   document.setTable(t, tableCopy); //set tableCopy at position t instead of table

   paragraph = document.insertNewParagraph(cursor); //insert new empty paragraph
   cursor = setCursorToNextStartToken(paragraph.getCTP());
  }

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

...產生以下WordResult.docx

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM