2012-10-12 86 views
1

我正在使用dox4j和pdfbox將兩個步驟中的docx文件的第一頁轉換爲圖像,但我目前每次都得到OutOfMemoryError使用Docx4j和PdfBox將Docx轉換爲圖像會導致OutOfMemoryError

我已經能夠確定在這個過程的最後一步拋出異常,而convertToImage方法被調用,但是我一直在使用這種方法的第二步來轉換PDF現在沒有問題了,所以我不知道什麼可能是原因,除非dox4j編碼PDF是一種我尚未測試或者已經損壞的方法。

我試過用FileOutputStream替換ByteArrayOutputStream,並且pdf似乎能正確渲染並不比我預想的大。

這是我使用的代碼:

WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(file); 
org.docx4j.convert.out.pdf.PdfConversion c = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(wordMLPackage); 

((org.docx4j.convert.out.pdf.viaXSLFO.Conversion)c).setSaveFO(File.createTempFile("fonts", ".fo")); 
ByteArrayOutputStream os = new ByteArrayOutputStream(); 
c.output(os, new PdfSettings()); 

byte[] bytes = os.toByteArray(); 
os.close(); 

ByteArrayInputStream is = new ByteArrayInputStream(bytes); 

PDDocument document = PDDocument.load(is); 

PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(0); 
BufferedImage image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 96); 

is.close(); 
document.close(); 

編輯 要查看關於這種情況更多的情況下,該代碼被在一個Grails web的應用程序運行。我已經嘗試了幾種不同的代碼,包括將不再需要的所有東西都清空,使用FileInputStream和FileOutputStream來保存更多的物理內存,並檢查docx4j和pdfbox的輸出,這些輸出似乎都能正常工作。

我使用的是docx4j 2.8.1和pdfbox 0.7.3,我也嘗試過pdf-renderer,但是我仍然得到一個OutOfMemoryError。我的懷疑是,docx4j使用太多的內存,但不產生錯誤,直到PDF到圖像轉換。

我很樂意除了將docx文件轉換爲pdf或直接轉換爲圖像作爲答案的替代方式,但是我目前正在嘗試替換已在服務器上運行的問題的jodconverter。

+0

聽起來就像是docx4j部分是OK,那你需要配置文件convertToImage。字節數組有多大? PDF中有多少頁面?你給java多少內存?一旦你有你的PDPage,是否有助於清空其他對象? – JasonPlutext

+0

@JasonPlutext:我不得不得出結論,這不只是'convertToImage',因爲我可以從docx4j失敗後採取的渲染PDF文件,並只用PDF重試,它工作正常。 – Godwin

+0

我用作我的主要測試的Doc文件是52KB,它生成的PDF是38.5KB。我已經將我的java內存設置爲3GB,但仍然失敗。 – Godwin

回答

2

我XDocreport團隊的一部分。

我們最近開發了一個部署在cloudbees(http://xdocreport-converter.opensagres.cloudbees.net/)上的小webapp,用於顯示行爲轉換器。

您可以輕鬆比較docx4j和xdocreport對PDF和Html轉換的行爲和性能。

的源代碼可以在這裏找到:

https://github.com/pascalleclercq/xdocreport-demo(REST的服務 - 轉換 - WebApplication的子文件夾)。 和這裏: https://github.com/pascalleclercq/xdocreport/blob/master/remoting/fr.opensagres.xdocreport.remoting.converter.server/src/main/java/fr/opensagres/xdocreport/remoting/converter/server/ConverterResourceImpl.java

我得到的第一個數字是,Xdocreport生成PDF的速度比Docx4J快10倍。

反饋是值得歡迎的。

+0

謝謝@Pascal!我的ID發現XDocReport沒有轉化含頁眉,頁腳,表格和其它任何東西,這不是直線上升文本正常。我更新到XDocReport 1.0-SNAPSHOT docx文件,雖然我沒能讓我的代碼正常工作,當我修改我的代碼時,我現在可以將大多數DocX文件轉換爲PDF格式,而且沒有問題。 – Godwin

+0

xdocreport 1.0.0-SNAPSHOT的maven存儲庫,網址爲https://oss.sonatype.org/content/repositories/snapshots/似乎導致我們建立了一些問題(主要超時)。是否有計劃來更新它或將它移動到另一個回購? – Godwin

+0

我不知道這個超時問題,我有點吃驚。我不知道任何賭注ter免費的在線資源庫管理器,所以它不可能很快改變。我建議你自己使用repo管理器(如Nexus),以便可以緩存其他人的快照。我們計劃以幾周的時間發佈1.0.0,這個版本將會像其他人一樣在中央Maven回購中提供。 –

3

終於光榮成功!我用XDocReport替換了docx4j,文檔立即轉換爲PDF格式。不過似乎有一些問題與一些文件,但我希望這是由於他們在創建,並且可以通過使用要解決的OS:

PDFViaITextOptions options = PDFViaITextOptions.create().fontEncoding("windows-1250"); 

使用approiate OS,而不是隻:

PDFViaITextOptions options = PDFViaITextOptions.create(); 

默認爲當前操作系統。

這是代碼我現在使用的轉換從DOCX到PDF:

FileInputStream in = new FileInputStream(file); 
XWPFDocument document = new XWPFDocument(in); 

PDFViaITextOptions options = PDFViaITextOptions.create(); 

ByteArrayOutputStream out = new ByteArrayOutputStream(); 
XWPF2PDFViaITextConverter.getInstance().convert(document, out, options); 

byte[] bytes = out.toByteArray(); 
out.close(); 

ByteArrayInputStream is = new ByteArrayInputStream(bytes); 
PDDocument document = PDDocument.load(is); 

PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(0); 
BufferedImage image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 96); 

is.close(); 
document.close(); 

return image; 
+0

非常有趣,謝謝。最近用docx4j的PDF轉換遇到了很多麻煩,這可能正是需要的。 – Ben

+0

(通過更新的方式,我恢復了我自己的代碼到docx4j FOP實現。XDocReport顯示諾言,但在如何格式的內容太多的差距(即保真度不夠好尚)。情況因人而異。 – Ben