2

別のファイルから読み取った値に応じて、ページの開始ごとに異なる文字列を使用する予定です。これを 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)

私が何をすべきか知っている人なら誰でも。

4

2 に答える 2

5

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 の提案 (適切に実装されている場合) は、無限ループを防ぎますが、ページの初期化の一部が 2 回実行される可能性があります。これは無害かもしれません (同じ変数を同じ値に 2 回設定しても無害に見えます) が、望ましくない副作用もある可能性があります (同じ変数を 2 回インクリメントしても無害ではありません)。特に、複数のページ イベント リスナーがアクティブになっている場合、その影響は苛立たしいものになる可能性があります。

したがって、余白を使用してページの上部に追加のスペースを残し、onEndPage代わりにそのスペースを埋めることをお勧めします。

PS:さらに、 iText in Action — 2nd Editionの 150 ページの使用に関する FAQがあります。onStartPage()

FAQ メソッドにコンテンツを追加することが推奨されないのはなぜですか? セクション 5.2.4 で、現在のページが空の場合、iText は呼び出しを無視することを思い出してください。このメソッドは、コードから明示的に呼び出すと実行 (または無視) されますが、複数の場合に iText 内から暗黙的に呼び出されることもあります。空のページでは無視されることが重要です。そうしないと、意図せずに空白のままになっている不要な新しいページが大量に作成されることになります。メソッドにコンテンツを追加すると、不要なページが作成されるリスクが常にあります。コンテンツを追加するメソッドを予約する方が安全だと考えてください。onStartPage() newPage()onStartPage()onEndPage()

于 2013-05-08T11:08:29.390 に答える
0

ifへの呼び出しに条件付き (例: )を付ける必要がありますonStartPage(writer,output)。そうでない場合onStartPageは、呼び出すたびに再帰的に呼び出されます。スタックの最大サイズに関係なく、無限ループが発生しStackOverflowます。エラーが発生します。

また、事前に条件がある場合は、一貫して true と評価される (または再帰呼び出しが行われる原因となるもの) という状況に陥っていることは明らかです。

于 2013-05-08T10:34:55.097 に答える