将SVG转换为PDF

如何将一个SVG文件转换为PDF编程? (我需要在生成PDF之前在某些方面改变SVG,所以只需使用工具预转换它就不够了。)

理想情况下使用Java,但Perl或PHP也可以。

显然我基本上是考虑Apache的FOP和Batik与Java。 不过无论我search多长时间,我都找不到一个简单的介绍。 像SVGConverter这样的描述,例如“定义可以转换部分或全部GraphicContext的类的接口”,但我不知道这意味着什么。

我有这种感觉,必须有一个API可以很简单地做到这一点,由FOP或Batik提供,但目前我还找不到它(或者实际上它不存在)。

就我所需要的支持的SVGfunction而言,该文件有一些path,它们被一些线性渐变填充。

理想情况下,如果我可以通过SVG作为一个DOM文档,这将是理想的; 那么我会加载我的模板SVG文件,改变它的用户指定,然后生成PDF。

感谢Adrian展示了Batik光栅器API应该如何使用。 但是,我需要一个更轻量级的解决scheme—我不能写入临时文件,而且我想减less依赖关系。 所以,从他指出的方法开始,我find了一种方法来访问较低级别的代码来进行转换,而不是别的。

import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import org.apache.batik.transcoder.Transcoder; import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.fop.svg.PDFTranscoder; public class Test { public static void main(String[] argv) throws TranscoderException, FileNotFoundException { Transcoder transcoder = new PDFTranscoder(); TranscoderInput transcoderInput = new TranscoderInput(new FileInputStream(new File("/tmp/test.svg"))); TranscoderOutput transcoderOutput = new TranscoderOutput(new FileOutputStream(new File("/tmp/test.pdf"))); transcoder.transcode(transcoderInput, transcoderOutput); } } 

编译和运行命令是

 javac -cp batik-rasterizer.jar -d build Test.java java -cp build:batik-rasterizer.jar Test 

重要的一点是, TranscoderInputTranscoderOutput可以处理任何InputStreamOutputStream ,而不仅仅是文件stream。 请注意,其中一个构造函数需要一个org.w3c.dom.Document ,这意味着您甚至不需要将SVG DOM序列化为SVGstring,从而节省了额外的步骤。

与高级API不同,此版本也不会向stdout / stderr写入任何内容。

对于JPEG,PNG或TIFF输出,请将org.apache.fop.svg.PDFTranscoderreplace为org.apache.batik.transcoder.image.JPEGTranscoderPNGTranscoderTIFFTranscoder (请注意,这些光栅格式位于不同的包中)。

(我不太清楚Java是如何findorg.apache.batk.transcoder.*org.apache.fop.svg.PDFTranscoder类的,因为我没有在batik-rasterizer.jar看到它们。

编辑:

虽然简单的命令行编译只适用于batik-rasterizer.jar ,但它正在做某种类加载器的魔术来find所有必要的类。 在更现实的情况下(使用Ant构build项目),您必须手动find类。 可以从Batik项目的 fop-1.1.zip和FOP项目的 fop-1.1.zipfind它们。 从蜡染,你需要与batik-transcoder.jar编译和运行

  • batik-transcoder.jar
  • batik-anim.jar
  • batik-awt-util.jar
  • batik-bridge.jar
  • batik-css.jar
  • batik-dom.jar
  • batik-ext.jar
  • batik-gvt.jar
  • batik-parser.jar
  • batik-script.jar
  • batik-svg-dom.jar
  • batik-util.jar
  • batik-xml.jar
  • xml-apis-ext.jar

从FOP开始,你需要用fop.jar编译并运行

  • fop.jar
  • avalon-framework-4.2.0.jar
  • xmlgraphics-commons-1.5.jar

我终于设法find适当的代码行来解决这个使用蜡染 。

你需要有SVG文件和PDF格式的文件作为磁盘上的文件,也就是说,我找不到在内存中执行它的方法(我正在写一个HTTP Servlet,所以我没有内在的需要写任何东西作为一个文件,理想情况下,我会stream结果到HTTP客户端)。 我使用File.createTemporaryFile来创build一个文件,将我的SVG转储到一个文件,并将结果PDF写入。

所以我使用的线路如下:

 import org.apache.batik.apps.rasterizer.DestinationType; import org.apache.batik.apps.rasterizer.SVGConverter; import ... // SVG available as a DOM object (created programatically by my program) Document svgXmlDoc = ... // Save this SVG into a file (required by SVG -> PDF transformation process) File svgFile = File.createTempFile("graphic-", ".svg"); Transformer transformer = TransformerFactory.newInstance().newTransformer(); DOMSource source2 = new DOMSource(svgXmlDoc); FileOutputStream fOut = new FileOutputStream(svgFile); try { transformer.transform(source2, new StreamResult(fOut)); } finally { fOut.close(); } // Convert the SVG into PDF File outputFile = File.createTempFile("result-", ".pdf"); SVGConverter converter = new SVGConverter(); converter.setDestinationType(DestinationType.PDF); converter.setSources(new String[] { svgFile.toString() }); converter.setDst(outputFile); converter.execute(); 

我有以下JAR(使用Googlesearch以查找项目并下载它们):

  • 阿瓦隆框架-4.2.0.jar
  • 蜡染全1.7.jar
  • 公地IO-1.3.1.jar
  • 共享logging-1.0.4.jar
  • FOP-0.95.jar
  • log4j的-1.2.15.jar
  • XML的API-ext.jar
  • xmlgraphics公地-1.3.1.jar

你需要一个用于渲染svg和pdf的libray。 我build议前者为SVG蝾螈 ,后者为iText 。 使用svg salamander,您可以读取svg并创build图像对象,使用itext可以将该图像写入pdf。

我使用Altsoft Xml2PDF。 如果我正确理解你的所有需求和要求,你最好试试他们的服务器版本的Xml2PDF。

所有你需要的是phantomjs。 你根本不需要笨重的蜡染; 只要到了可以运行phantomjs的地步,调用rasterize.js,使用pdf的url作为源代码,并将位置作为输出。 根据你想要用.pdf做什么,你甚至不需要Java。

http://phantomjs.org/screen-capture.html

看看“除PNG格式外,PhantomJS支持JPEG,GIF和PDF”。