[英]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.