有没有办法提高FlyingSaucer的性能?

我已经按照这篇文章使用FlyingSaucer将XHTML转换为PDF,它很棒,但有一个主要的垮台……它的速度非常慢!

我发现从XHTML渲染PDF需要1到2分钟,无论该页面有多简单。

基本代码:

import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.xhtmlrenderer.pdf.ITextRenderer; import com.lowagie.text.DocumentException; public class FirstDoc { public static void main(String[] args) throws IOException, DocumentException { String inputFile = "firstdoc.xhtml"; String url = new File(inputFile).toURI().toURL().toString(); String outputFile = "firstdoc.pdf"; OutputStream os = new FileOutputStream(outputFile); ITextRenderer renderer = new ITextRenderer(); renderer.setDocument(url); renderer.layout(); renderer.createPDF(os); os.close(); } } 

示例XHTML:

     My First Document  b { color: green; }    

Greetings Earthlings! We've come for your Java.

有谁知道如何提高FlyingSaucer的性能?

如果不这样做,是否有人能够推荐一个替代的Java库,它有效地将URL从URL渲染到带有外部CSS的(X)HTML文档和从URL生成的图像?

首先我要说的是,我使用了您的示例代码和示例xhtml,并且它“在2675ms内运行”。

我下载了flyingsaucer R8。 并将三个jar放入我的类路径中。

core-renderer.jar,iText-2.0.8.jar,xml-apis-xerces-2.9.1.jar

我通过使用仪器修改代码来测量运行时间…

 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.xhtmlrenderer.pdf.ITextRenderer; import com.lowagie.text.DocumentException; public class FirstDoc { public static void main(String[] args) throws IOException, DocumentException { long start = System.currentTimeMillis(); String inputFile = "firstdoc.xhtml"; String url = new File(inputFile).toURI().toURL().toString(); String outputFile = "firstdoc.pdf"; OutputStream os = new FileOutputStream(outputFile); ITextRenderer renderer = new ITextRenderer(); renderer.setDocument(url); renderer.layout(); renderer.createPDF(os); os.close(); long end = System.currentTimeMillis(); System.out.println("Ran in " + (end-start) + "ms"); } } 

现在这个库并不是很快,但它似乎也没需要1-2分钟。 所以现在我们需要弄清楚为什么它的运行速度如此之慢。 您能告诉我们您使用的JDK以及使用的平台吗? 你还使用哪个版本的flyingsaucer?

我和Edd面临同样的问题。

遗憾的是,接下来的方法不适用于Java DocumentBuilder:xml解析速度很慢? 由Marek Piechut完全为我 – 我的HTML实体在途中迷路了。

 DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance(); fac.setNamespaceAware(false); fac.setValidating(false); fac.setFeature("http://xml.org/sax/features/namespaces", false); fac.setFeature("http://xml.org/sax/features/validation", false); fac.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); fac.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); DocumentBuilder builder = fac.newDocumentBuilder(); 

最终诀窍是这些线:

 DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = fac.newDocumentBuilder(); builder.setEntityResolver(FSEntityResolver.instance()); 

通过使用内置的Java EntityResolver来解析DTD,它获得了更快的速度。

问题是,您可能正在使用链接文章中的此代码:

 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = builder.parse(new StringBufferInputStream(buf.toString())); 

这样构建器将尝试加载引用的DTD。

   

加载和解析DTD需要花费大量时间。

如果你正在使用

 ITextRenderer renderer = new ITextRenderer(); renderer.setDocument(url); // not setDocument(document) 

飞碟不会解决DTD问题。 如果要加载Document ,而不是设置url,请参阅

  • 如何在Java中读取格式良好的XML,但是跳过架构?
  • 我对此的回答: xhtmlrenderer创建长度为0的PDF

我会提出2条建议:

  1. 简介它。

  2. OutputStream包装在BufferedOutputStream

  3. 简介它。 (哎呀……我在重复自己。好吧,你得到了照片。)