我打算根据我从另一个文件中读取的值为每个开始页设置不同的字符串。我已将其放置在我的onStartPage方法中,如下所示:
@Override
public void onStartPage(PdfWriter writer, Document output) {
try {
File finish = new File("C:/Statements final/");
File[] finf = finish.listFiles();
Font f1 = new Font(Font.NORMAL, 12);
f1.setColor(Color.BLACK);
String firstline = "";
for (int k = 0; k < filenames1.length; k++) {
FileInputStream fs = new FileInputStream("C:/Statements final/" + filenames1[k]);
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
for (int i = 0; i < 0; i++) {
br.readLine();
}
firstline = br.readLine();
System.out.println(firstline);
output.add(new Paragraph(new Phrase(new Chunk(firstline, f1))));
}
} catch (Exception ex) {
System.out.println(ex);
}
}
我收到这个StackOverflow错误:
Exception in thread "main" java.lang.StackOverflowError
at java.lang.String.toLowerCase(String.java:2524)
at com.lowagie.text.pdf.PdfEncodings.convertToBytes(PdfEncodings.java:149)
at com.lowagie.text.pdf.BaseFont.convertToBytes(BaseFont.java:795)
at com.lowagie.text.pdf.FontDetails.convertToBytes(FontDetails.java:160)
at com.lowagie.text.pdf.PdfContentByte.showText2(PdfContentByte.java:1386)
at com.lowagie.text.pdf.PdfContentByte.showText(PdfContentByte.java:1396)
at com.lowagie.text.pdf.PdfDocument.writeLineToContent(PdfDocument.java:1587)
at com.lowagie.text.pdf.ColumnText.go(ColumnText.java:841)
at com.lowagie.text.pdf.ColumnText.go(ColumnText.java:752)
at com.lowagie.text.pdf.PdfPRow.writeCells(PdfPRow.java:513)
at com.lowagie.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:511)
at com.lowagie.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:587)
at com.lowagie.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:543)
at com.lowagie.text.pdf.PdfDocument.newPage(PdfDocument.java:830)
at com.lowagie.text.pdf.PdfDocument.carriageReturn(PdfDocument.java:1192)
at com.lowagie.text.pdf.PdfDocument.add(PdfDocument.java:482)
at estatement.Border.onStartPage(Border.java:112)
任何知道我应该做什么的人。
onStartPage
如果您尝试更改其中的文档内容,则非常脆弱,参见。PdfPageEvent. onStartPage
的JavaDoc注释警告无限循环:
/**
* Called when a page is initialized.
* <P>
* Note that if even if a page is not written this method is still
* called. It is preferable to use <CODE>onEndPage</CODE> to avoid
* infinite loops.
*
* @param writer the <CODE>PdfWriter</CODE> for this document
* @param document the document
*/
public void onStartPage(PdfWriter writer, Document document);
原因是在页面初始化期间调用了onStartPage
,但对文档的添加需要页面初始化已经完成。
因此,@VigneshVino的提议(如果实施得当)将阻止无限循环,但仍可能导致页面初始化的某些部分执行两次。这可能是无害的(两次将相同的变量设置为相同的值似乎是无害的),但它也可能有不希望的副作用(两次递增相同的变量并非无害)。特别是如果多个页面事件侦听器处于活动状态,效果可能会令人恼火。
因此,我建议您通过边距在页面顶部留下一些额外的空间,并将该空间填充到onEndPage
中。
PS:此外,在iText in Action-第2版的第150页上有一个关于使用onStartPage()
的FAQ:
FAQ为什么不建议在onStartPage()
方法中添加内容?从第5.2.4节中您会记得,当当前页面为空时,iText会忽略newPage()
调用。当您从代码中显式调用它时,此方法会被执行或忽略,但它也会在多个场合从iText中隐式调用。对于空页面忽略它很重要;否则您最终会得到大量不需要的新页面,这些页面无意中留空。如果您在onStartPage()
方法中添加内容,总是有不需要页面的风险。考虑保留onEndPage()
方法来添加内容更安全。
您需要在调用onStartPage(作家,输出)
时添加一些条件(例如if
)。如果没有,那么每次onStartPage
调用时,它都会调用recursively.No无论堆栈的最大大小如何,它都会给你无限循环。这会导致StackOverflow
错误。
如果事先有一些条件,你显然会陷入这样一种情况,即它不断地评估为真(或者任何导致递归调用的东西)。