使用Docx4j和PdfBox将Docx转换为图像会导致OutOfMemoryError

时间:2012-10-12 00:49:51

标签: out-of-memory pdfbox docx4j

我正在使用dox4j和pdfbox将docx文件的第一页转换为两个步骤中的图像,但我每次都会获得OutOfMemoryError

我已经能够确定在此过程的最后一步抛出异常,同时调用了convertToImage方法,但是我一直在使用第二步这种方法现在转换pdf一段时间没有问题,所以我不知道可能是什么原因,除非dox4j编码pdf是一种我尚未测试或损坏的方式。

我尝试用ByteArrayOutputStream替换FileOutputStream并且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。

2 个答案:

答案 0 :(得分:3)

终于获得了辉煌的成功!我用XDocReport替换了docx4j,文档立即转换为PDF。但是,某些文档似乎存在一些问题,但我希望这是因为它们是在创建的操作系统上创建的,可以使用以下方法解决:

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

使用批准的操作系统而不仅仅是:

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;

答案 1 :(得分:2)

我是XDocreport团队的一员。

我们最近开发了一个部署在cloudbees上的小型webapp(http://xdocreport-converter.opensagres.cloudbees.net/),它显示了行为转换器。

您可以轻松地比较docx4j和xdocreport在PDF和Html转换中的行为和性能。

源代码可以在这里找到:

https://github.com/pascalleclercq/xdocreport-demo(REST-Service-Converter-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倍。

欢迎反馈。