我正在使用Flying Saucer with IText從HTML文件生成PDF,特別是使用org.xhtmlrenderer.pdf.ITextRenderer
類。我的代碼很簡單。生成代碼封裝在一個方法,如下所示:FlyingSaucer ITextRenderer完成錯誤(非平衡保存/恢復和空白PDF)
/* 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管理作爲一個單獨的對象。我有一個管理員類,有一個ExecutorService充當PDF生成任務的隊列。這位經理使用單身生成器來生成對象。因此,我只是一次性實例化ITextRenderer並重用它。現在我設置我的隊列同時操作多達2個線程。我只是意識到,如果這可能是由於我遇到了兩個線程正在使用我的ONE渲染器渲染兩組獨立PDF的情況。
現在,我只是意識到,我實際上每次渲染調用兩次「完成」!一個在createPDF()
錯誤中調用(作爲第二個參數傳遞true),另一個顯式調用finishPDF()
。
這已經運行了相當長一段時間了,它成功地生成了PDF文件大多數的時間。我已經遇到了兩種不同類型的錯誤偶爾:
運行時由於不平衡例外保存/恢復狀態運營。示例堆棧跟蹤如下:
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]
生成的PDF包含缺失/變形的部分或最差的空白頁。
對於問題2,我相當確信這是由於調用finishPDF()兩次。但是,對於問題1,在之前會發生對finishPDF()的調用被執行,所以我實際上不知道是否是導致問題的原因。
有沒有人在使用飛碟和iText一起處理這兩個問題的經驗?
請問您可以發佈完整的FS碼嗎?例如。您在哪裏設置文檔。對於2:你使用CSS,pagebreaktags等?這有時會導致空白頁面,也可能是文件末尾有空行或沒有足夠空間存放圖片。 – ollo
順便說一句。如果你刪除'finishPDF()'調用會發生什麼?'createPDF'參數'finish = true'(就像你設置的那樣)不需要第二次完成(但它不應該以負面的方式影響你的pdf)。 – ollo
嗨@ollo,在問題中增加了更多細節。我也意識到也許我實際上同時訪問了渲染器的一個實例,這可能是我遇到上述問題的原因。我原本是這樣設計的,因爲我認爲渲染器的初始化時間太昂貴了......我想知道是否對我創建新的渲染器實例會更好,因此我可以操作併發的PDF生成隊列...並且您去吧,我沿着一條切線去了。無論如何,你能否證實我的發現? :) –