问题
HI I would like to insert a XWPFTable in between some contents. The file is content is fixed and file is taken as input. I need the table to be inserted in the specific field.
like this:
Stack Overflow is a privately held website, the flagship site of the Stack Exchange Network, created in 2008 by Jeff Atwood and Joel Spolsky. Here is the table.
The contents continue.It was created to be a more open alternative to earlier question and answer sites such as Experts-Exchange.
Thanks
The code i have written
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
I am getting null pointer exception on creating the row.
回答1:
Have tested now. My suspicion was right. The cursor was on the wrong place in your code after XWPFParagraph p = document.insertNewParagraph(cursor);
. So the XWPFTable table = p.getBody().insertNewTbl(cursor);
could not be inserted and was null
then.
But there are further problems. If the text was found, we are in the paragraph after which the table shall be placed. So we need moving the cursor to the next paragraph. But what if there is not a next paragraph? Then a new paragraph needs to be created. Fortunately the XmlCursor.toNextSibling flags if it was successful.
Example:
Template:
Code:
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);
paragraph = cell.getParagraphs().get(0);
run = paragraph.createRun();
run.setText("Table Cell " + i);
}
}
FileOutputStream out = new FileOutputStream("WordTableExampleNew.docx");
document.write(out);
out.close();
document.close();
}
}
Result:
回答2:
I am not certain that either of the XWPFDocument.insertTable()
methods work correctly. One thing I noticed is that you have:
XWPFParagraph p = document.insertNewParagraph(cursor);
XWPFTable table = p.getBody().insertNewTbl(cursor);
which is equivalent to:
XWPFParagraph p = document.insertNewParagraph(cursor);
XWPFTable table = document.insertNewTbl(cursor);
This leaves me wondering if you have some confusion concerning where a table fits inside a document. Paragraphs and Tables are proper siblings. Paragraphs do not contain tables, though Tables can contain Paragraphs (and other tables) in table cells.
The paragraph body is actually the part that contains the paragraph. This can be a document part, or a header/footer part, or a comment part, etc. But, XWPFParagraph.getBody()
does not refer to the contents of the paragraph. Rather, it refers to the paragraph's parent part.
来源:https://stackoverflow.com/questions/49254987/inserting-xwpftable-in-between-contents