java - 将表添加到 itext 7 pdf 时出现 IndexOutOfBoundsException

标签 java pdf itext7

我尝试创建一个包含多个表格(大小未知)的 PDF。 在一定数量的表(本例中:18)之后,抛出以下异常:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
   at java.util.ArrayList$SubList.rangeCheck(Unknown Source)
   at java.util.ArrayList$SubList.get(Unknown Source)
   at com.itextpdf.layout.renderer.CollapsedTableBorders.collapseAllBordersAndEmptyRows(CollapsedTableBorders.java:77)
   at com.itextpdf.layout.renderer.CollapsedTableBorders.updateBordersOnNewPage(CollapsedTableBorders.java:617)
   at com.itextpdf.layout.renderer.TableRenderer.layout(TableRenderer.java:248)
   at com.itextpdf.layout.renderer.RootRenderer.addChild(RootRenderer.java:111)
   at com.itextpdf.layout.RootElement.add(RootElement.java:108)
   at com.itextpdf.layout.Document.add(Document.java:143)
   at com.test.MinimalITextTest.createPdf(MinimalITextTest.java:83)
   at com.test.MinimalITextTest.main(MinimalITextTest.java:66)

我使用的是 iText 7 的快照版本(3 月 24 日起的 7.0.3-SNAPSHOT)。

是否有任何解决方法,或者我只是做错了什么?

触发错误的示例代码:

package com.test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.itextpdf.kernel.color.Color;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.border.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;

public class MinimalITextTest {

    private static final int numberOfColumns=8;
    private static final UnitValue[] columnWeight;
    private static final int NUMBER_OF_TABLES = 18; //Does work with 17

    static {
        float[] percentArray = new float[numberOfColumns];
        for(int i=0; i<percentArray.length;i++)
        {
            percentArray[i] = 100.0f/numberOfColumns;
        }
        columnWeight=UnitValue.createPercentArray(percentArray);
    }


    private final List<Table> tables=new ArrayList<>();
    private Table currentTable;


    public MinimalITextTest()
    {
        currentTable=new Table(columnWeight)
            .setWidthPercent(100)
            .setTextAlignment(TextAlignment.CENTER)
            .setHorizontalAlignment(HorizontalAlignment.CENTER);
        tables.add(currentTable);
    }

    public static void main(String[] args) throws IOException
    {
        final char[] charArray="Minimal Example".toCharArray();
        final MinimalITextTest test = new MinimalITextTest();
        for(int k=0;k<NUMBER_OF_TABLES;k++)
        {
            for(int i=0;i<10;i++)
            {
                CellElement[] cellElement=new CellElement[charArray.length];
                for(int j=0;j<charArray.length;j++)
                {
                    cellElement[j] = new CellElement(String.valueOf(charArray[j]));
                }
                test.createRow(cellElement);
            }
            test.createNewTable();
        }
        test.createPdf("Minimal_test.pdf");
    }

    private void createNewTable() {
        currentTable=new Table(columnWeight)
            .setWidthPercent(100)
            .setTextAlignment(TextAlignment.CENTER)
            .setHorizontalAlignment(HorizontalAlignment.CENTER);
        tables.add(currentTable);
    }

    public void createPdf(String destinationFile) throws IOException {
        PdfWriter pw = new PdfWriter(new FileOutputStream(destinationFile));

        Document document = new Document(new PdfDocument(pw));
        for(Table t : tables)
        {
            document.add(t);
        }
        document.close();
    }

    public void createRow(CellElement... cells)
    {
        boolean addedACell=false;
        for(CellElement currentCell : cells)
        {
            if(currentCell==null)
            {
                continue;
            }
            addedACell = true;
            Cell cell = new Cell();
            cell.add(new Paragraph(currentCell.getText()))
                .setBorder(new SolidBorder(Color.BLACK, 0.5f))
                .setBackgroundColor(currentCell.getBackgroundColor());
            currentTable.addCell(cell);
        }
        if(addedACell)
        {
            currentTable.startNewRow();
        }
    }

    public static class CellElement
    {
        private final String text;
        private final Color color;

        public CellElement()
        {
            this.text = "";
            this.color = Color.WHITE;
        }


        public CellElement(String text)
        {
            this.text = text;
            this.color = Color.WHITE;
        }

        public CellElement(String text, Color color)
        {
            this.text = text;
            this.color = color;
        }

        public String getText() {
            return text;
        }

        public Color getBackgroundColor() {
            return color;
        }

    }
}

最佳答案

这确实是当前快照中的一个错误。作为解决方法,如果您知道不会再有行,请不要调用 startNewRow()

对于您的示例,可以通过以下方式应用解决方法:

public void createRow(boolean lastRow, CellElement... cells)
{
    for(CellElement currentCell : cells)
    {
        if(currentCell==null)
        {
            continue;
        }
        Cell cell = new Cell();
        cell.add(new Paragraph(currentCell.getText()))
                .setBorder(new SolidBorder(Color.BLACK, 0.5f))
                .setBackgroundColor(currentCell.getBackgroundColor());
        currentTable.addCell(cell);
    }
    if (!lastRow) {
        currentTable.startNewRow();
    }
}

传递一个参数来指示这是否是createRow的最后一行。在您的示例中,调用将是 createRow(i == 9, cellElement);

关于java - 将表添加到 itext 7 pdf 时出现 IndexOutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43052433/

相关文章:

java - `parseInt()` 和 `parseDouble()` 抛出 `NumberFormatExeption`

java - 在 java 中从 arraylist 中查找丢失的项目

java - 将字符串拆分为没有分隔符的三个部分 (Java)

Symfony2 使用 FPDF 输出 pdf

android - 为什么 Intent 的 Android resolveactivity 返回 null?

r - 在 R 中创建 PDF 时 plot.new() 出错

java - iText7 setRotation() 无法正常工作

java - 使用 DOM4J 将 XML 子元素添加到 ArrayList

Itext7 - 裁剪图像

java - 使用 iText7 将多个表格打印到 pdf 上