1

org.xhtmlrenderer.pdf.ITextRenderer特にクラスを利用して、HTMLファイルからPDFを生成するために、ITextでFlyingSaucerを使用しています。私のコードは単純です。生成コードは、次のようなメソッドにカプセル化されます。

/* PDfGenerator class only has ONE instance */
public PdfGenerator() {
    this.renderer = new ITextRenderer(); //This is a class variable that only gets instantiated ONCE
}

public void generatePDF(String outputFilePath, String htmlContent) {
    renderer.setDocumentFromString(htmlContent);
    renderer.layout();
    renderer.createPDF(new BufferedOutputStream(
          new FileOutputStream(new File(outputFilePath)), BUFFER_SIZE), true);
    renderer.finishPDF();
}

編集:

私のジェネレータークラスは、実際にはSpringによってシングルトンオブジェクトとして管理されています。PDF生成タスクのキューとして機能するExecutorServiceを持つマネージャークラスがあります。このマネージャーは、シングルトンジェネレーターを使用してオブジェクトを生成します。したがって、ITextRendererを一度だけインスタンス化して再利用します。ここで、最大2つのスレッドを同時に操作するようにキューを設定しました。2つのスレッドが1つのレンダラーを使用して2つの別々のPDFセットをレンダリングしている状況に遭遇したため、これが原因である可能性があることに気づきました。

今、私は実際にレンダリングごとに2回「終了」と呼んでいることに気づきました。1つはcreatePDF()エラー呼び出し(2番目のパラメーターとしてtrueを渡す)で、もう1つは。への明示的な呼び出しfinishPDF()です。

これはかなり前から実行されており、ほとんどの場合、PDFを正常に生成することができました。私は散発的に2つの異なるタイプのエラーに遭遇しています:

  1. 状態の保存/復元演算子の不均衡による実行時例外。次のようにスタックトレースをサンプリングします。

    java.lang.RuntimeException: Unbalanced save/restore state operators.
    at com.lowagie.text.pdf.PdfContentByte.restoreState(Unknown Source) ~[itext-2.0.8.jar:na]
    at org.xhtmlrenderer.pdf.ITextOutputDevice.setClip(ITextOutputDevice.java:737) ~[core-renderer-R8.jar:na]
    at org.xhtmlrenderer.pdf.ITextRenderer.paintPage(ITextRenderer.java:387) ~[core-renderer-R8.jar:na]
    at org.xhtmlrenderer.pdf.ITextRenderer.writePDF(ITextRenderer.java:348) ~[core-renderer-R8.jar:na]
    at org.xhtmlrenderer.pdf.ITextRenderer.createPDF(ITextRenderer.java:315) ~[core-renderer-R8.jar:na]
    at org.xhtmlrenderer.pdf.ITextRenderer.createPDF(ITextRenderer.java:280) ~[core-renderer-R8.jar:na]
    
  2. 生成されたPDFには、欠落/変形したセクション、または最悪の場合、空白のページがあります。

問題2については、finishPDF()を2回呼び出したことが原因であると確信しています。ただし、Issue 1の場合、 finishPDF()の呼び出しが実行されるに発生するため、それが問題の原因であるかどうかは実際にはわかりません。

Flying SaucerをiTextと一緒に使用しているときに、これら2つの問題に対処した経験のある人はいますか?

4

1 に答える 1

1

私が遭遇した問題は、基本的に、異なるスレッドで同じITextRendererインスタンスに同時にアクセスするため、現在実行中のPDF生成ジョブの処理が混乱することです。

私はExecutorサービスに1つのスレッドのみを使用させ、生成ジョブをシーケンシャルに作成しました。私の観察によれば、一度に1つずつ処理する限り、同じITextRendererを再利用できます。

Flying Saucer libの開発者にこれを確認するためのクエリを送信しました。返信があったときに、この投稿を更新します。

余談ですが、1つのスレッドと1つの事前にインスタンス化されたITextRendererインスタンスを使用して生成する方が効率的か、複数のスレッドを使用してスレッドごとにITextRendererをインスタンス化する方が効率的かを判断する必要があります。

于 2012-09-27T02:34:33.860 に答える