Как решить исключение в потоке «основной» java.lang.IndexOutOfBoundsException: индекс: 6, размер: 1 с созданием таблицы apache poi?

Я создаю таблицу в ячейке таблицы. В ячейке таблицы + много абзацев. В нескольких абзацах есть текст, и таблица будет создана в определенном абзаце. Код, который я написал, выглядит следующим образом. Я отладил код и увидел, что индекс 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)

Пожалуйста, поделитесь полной трассировкой стека

Jens 15.02.2023 15:41

Трассировка стека была предоставлена ​​выше.

Jeet 15.02.2023 16:31

Просто для подтверждения: вы говорите, что полная трассировка стека состоит всего из 4 строк?

andrewJames 15.02.2023 18:03
Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
Лучшая компания по разработке спортивных приложений
Лучшая компания по разработке спортивных приложений
Ищете лучшую компанию по разработке спортивных приложений? Этот список, несомненно, облегчит вашу работу!
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Если вы являетесь веб-разработчиком или тестировщиком, вы можете быть знакомы с Selenium, популярным инструментом для автоматизации работы...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
Деревья поиска (Алгоритм4 Заметки к учебнику)
Деревья поиска (Алгоритм4 Заметки к учебнику)
(1) Двоичные деревья поиска: среднее lgN, наихудшее N для вставки и поиска.
1
3
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не удалось воспроизвести проблему. Предоставленный код является неполным. Также предоставленная трассировка стека является неполной. Но строка кода 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! Снимаю шляпу! Большое спасибо!

Jeet 15.02.2023 21:37

Другие вопросы по теме