Я создаю таблицу в ячейке таблицы. В ячейке таблицы + много абзацев. В нескольких абзацах есть текст, и таблица будет создана в определенном абзаце. Код, который я написал, выглядит следующим образом. Я отладил код и увидел, что индекс 6 присутствует и все значения существуют. Нигде нет значения Null.
XWPFTableRow mainTableRowThree = tableitem.getRow(2);
mainTableRowThree.getCell(0).removeParagraph(0);
XWPFParagraph p000 = mainTableRowThree.getCell(0).addParagraph();
XWPFRun run20=p000.createRun();
run20.setText("Beschreibung:");
XWPFRun run21=p000.createRun();
run21.setText(item.getDescription());
XWPFParagraph p001 = mainTableRowThree.getCell(0).addParagraph();
XWPFRun run22=p001.createRun();
run22.setText("Ansprechpartner:");
XWPFRun run23=p001.createRun();
run23.setText(item.getperson());
XWPFParagraph p002 = mainTableRowThree.getCell(0).addParagraph();
XWPFRun run24=p002.createRun();
run24.setText("Lösung:");
XWPFRun run25=p002.createRun();
run25.setText(item.getSolution());
.........
.........//Similarly for Paragraph p003,p004
XWPFParagraph p005 = mainTableRowThree.getCell(0).addParagraph();
XWPFRun run32=p005.createRun();
run32.setText("Produkte:"); //Below this the innertable has to be created
XWPFParagraph p0001 = mainTableRowThree.getCell(0).addParagraph(); //created a new paragraph for the nested table
generateNestedtable(item.getProducts(),document,p0001,mainTableRowThree); // A seperate method for the nested table creation
private void generateNestedtable(String towrite,XWPFDocument document,XWPFParagraph paragraph,XWPFTableRow tablerow)
throws XmlException {
XWPFTable tableTwo = tablerow.getCell(0).insertNewTbl(paragraph.getCTP().newCursor()); //In this line there is the exception
//The paragraph object here is not null and that I have already debugged.
tableTwo.getCTTbl().addNewTblPr().addNewTblBorders().addNewLeft().setVal(
org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder.SINGLE);
tableTwo.getCTTbl().getTblPr().getTblBorders().addNewRight().setVal(
org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder.SINGLE);
tableTwo.getCTTbl().getTblPr().getTblBorders().addNewTop().setVal(
org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder.SINGLE);
tableTwo.getCTTbl().getTblPr().getTblBorders().addNewBottom().setVal(
org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder.SINGLE);
tableTwo.getCTTbl().getTblPr().getTblBorders().addNewInsideH().setVal(
org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder.SINGLE);
tableTwo.getCTTbl().getTblPr().getTblBorders().addNewInsideV().setVal(
org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder.SINGLE);
}
Я считаю, что исключение связано с *insertNewTble(paragraph.getCTP().newCursor())*
. Это потому, что после стольких абзацев перед созданием этой таблицы вложенная таблица не создается из-за нехватки места?
Трассировка стека выглядит следующим образом
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 6, Size: 1
at java.base/java.util.ArrayList.rangeCheckForAdd(ArrayList.java:756)
at java.base/java.util.ArrayList.add(ArrayList.java:481)
at org.apache.poi.xwpf.usermodel.XWPFTableCell.insertNewTbl(XWPFTableCell.java:328)
Трассировка стека была предоставлена выше.
Просто для подтверждения: вы говорите, что полная трассировка стека состоит всего из 4 строк?
Не удалось воспроизвести проблему. Предоставленный код является неполным. Также предоставленная трассировка стека является неполной. Но строка кода at org.apache.poi.xwpf.usermodel.XWPFTableCell.insertNewTbl(XWPFTableCell.java:328)
должна указывать на оператор ArrayList.add
. Это верно для Apache POI 4.0.0. И это не текущая версия Apache POI.
Следующий полный пример работает для меня с использованием текущей версии Apache POI 5.2.3:
import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
public class CreateWordTableInTable1 {
static void setAllBorders(XWPFTable table, XWPFTable.XWPFBorderType borderType, int size, int space, java.lang.String rgbColor) {
table.setTopBorder(borderType, size, space, rgbColor);
table.setRightBorder(borderType, size, space, rgbColor);
table.setBottomBorder(borderType, size, space, rgbColor);
table.setLeftBorder(borderType, size, space, rgbColor);
table.setInsideHBorder(borderType, size, space, rgbColor);
table.setInsideVBorder(borderType, size, space, rgbColor);
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFTable tableOne = document.createTable(2,2);
tableOne.setWidth("100%");
XWPFTableRow tablerow = tableOne.getRow(0);
tablerow.getCell(0).setWidth("40%");
tablerow.getCell(1).setWidth("60%");
tablerow.getCell(0).setText("Test");
tablerow.getCell(1).setText("Test");
tablerow = tableOne.getRow(1);
tablerow.getCell(0).setText("Test");
//XWPFParagraph paragraph = tablerow.getCell(1).getParagraphArray(0);
XWPFParagraph paragraph;
XWPFRun run;
//first paragraph is already present in table cell
paragraph = tablerow.getCell(1).getParagraphArray(0);
run = paragraph.createRun();
run.setText("Paragraph 0");
//create some more paragraphs in table cell
for (int i = 1; i <= 5; i++) {
paragraph = tablerow.getCell(1).addParagraph();
run = paragraph.createRun();
run.setText("Paragraph " + i);
}
paragraph = tablerow.getCell(1).addParagraph();
run = paragraph.createRun();
run.setText("Produkte:"); //below this the inner table has to be created
//need an empty paragraph to start the table
paragraph = tablerow.getCell(1).addParagraph();
XWPFTable tableTwo = tablerow.getCell(1).insertNewTbl(paragraph.getCTP().newCursor());
tableTwo.setWidth(0); // This is necessary because a XWPFTable created by insertNewTbl seems not to have full internally structure. It lacks the cell width field in this case.
tableTwo.setWidth("100%");
setAllBorders(tableTwo, XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
tablerow = tableTwo.createRow();
tablerow.createCell().setText("aaaaaaaaaa");
tablerow.createCell().setText("jjjjjjjj");
tablerow = tableTwo.createRow();
tablerow.getCell(0).setText("bbbbbbbbbb");
tablerow.getCell(1).setText("gggggggggg");
try (FileOutputStream out = new FileOutputStream("./CreateWordTableInTable.docx")) {
document.write(out);
}
document.close();
}
}
Возможно, ваша проблема связана с XmlCursor
. Используя ваш код, он указывает на начало абзаца, содержащего текст «Produkte:». Но он должен указывать на позицию после этого текста, не так ли? Сам Microsoft Word всегда будет использовать собственный пустой абзац для начала таблицы после него.
Мой код производит:
Только что протестировано. Это ошибка в Apache POI версии 4. И это потому, что XWPFTableCell.addParagraph
добавляет абзац в ячейку таблицы, но не добавляет этот абзац в ArrayList
bodyElements
. Поэтому при попытке добавить новую таблицу в ArrayList
bodyElements
(bodyElements.add(i, newT);
в строке кода 328 в XWPFTableCell.java) происходит сбой, поскольку в ArrayList
bodyElements
отсутствуют все абзацы, добавленные с помощью XWPFTableCell.addParagraph
.
Эта ошибка была исправлена в Apache POI версии 5.
Решение. Всегда используйте текущую версию Apache POI. Никогда не используйте старые версии Apache POI.
Какой отличный анализ @Axel! Снимаю шляпу! Большое спасибо!
Пожалуйста, поделитесь полной трассировкой стека