我试图用几个表(大小未知)创建一个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);
。