Как решить исключение в потоке «основной» 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
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
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 добавляет абзац в ячейку таблицы, но не добавляет этот абзац в ArrayListbodyElements. Поэтому при попытке добавить новую таблицу в ArrayListbodyElements (bodyElements.add(i, newT); в строке кода 328 в XWPFTableCell.java) происходит сбой, поскольку в ArrayListbodyElements отсутствуют все абзацы, добавленные с помощью XWPFTableCell.addParagraph.

Эта ошибка была исправлена ​​в Apache POI версии 5.

Решение. Всегда используйте текущую версию Apache POI. Никогда не используйте старые версии Apache POI.

Какой отличный анализ @Axel! Снимаю шляпу! Большое спасибо!

Jeet 15.02.2023 21:37

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