将SVG转换为PDF

Adr*_*ith 27 java pdf svg

如何以编程方式将SVG文件转换为PDF?(在生成PDF之前,我需要在某些方面更改SVG,因此仅使用工具预转换它是不够的.)

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

显然我基本上考虑Apache FOP和Batik与Java.但无论我搜索多久,我都找不到如何做到的简单介绍.像SVGConverter这样的描述有​​"定义能够转换部分或全部GraphicContext的类的接口"的描述,但我真的不知道这意味着什么.

我有这种感觉必须有一个API来完成这个,非常简单,由FOP或Batik提供,但我现在无法找到它(或者它可能真的不存在.)

就我所需的支持的SVG功能而言,该文件有一些填充了一些线性渐变的路径.

理想情况下,如果我可以将SVG作为理想的DOM文档传递; 然后我将加载我的模板SVG文件,根据用户的指定进行更改,然后生成PDF.

Jim*_*ski 18

感谢Adrian展示了如何使用Batik光栅化器API.但是,我需要一个更轻量级的解决方案---我不能写入临时文件,我想要更少的依赖项.因此,从他指出的方法开始,我找到了一种方法来访问较低级别的代码来进行转换,而不是其他任何东西.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译运行命令是

javac -cp batik-rasterizer.jar -d build Test.java
java -cp build:batik-rasterizer.jar Test
Run Code Online (Sandbox Code Playgroud)

最重要的一点是,TranscoderInputTranscoderOutput可以与任何工作InputStreamOutputStream,而不仅仅是文件流.请注意,其中一个构造函数采用a org.w3c.dom.Document,这意味着您甚至不需要将SVG DOM序列化为SVG字符串,从而节省了额外的步骤.

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

对于JPEG,PNG或TIFF输出,请替换org.apache.fop.svg.PDFTranscoderorg.apache.batik.transcoder.image.JPEGTranscoder,PNGTranscoderTIFFTranscoder(请注意,这些光栅格式位于不同的包中).

(我不太确定Java如何找到org.apache.batk.transcoder.*org.apache.fop.svg.PDFTranscoder类,因为我没有看到它们batik-rasterizer.jar.)

编辑:

虽然简单的命令行编译batik-rasterizer.jar仅适用于它,但它正在做一些类加载器魔术来查找所有必需的类.在更现实的情况下(使用Ant构建项目),您必须手动查找类.他们可以发现batik-1.7.zip蜡染项目,并fop-1.1.zip该项目的FOP.从Batik,你需要编译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


Adr*_*ith 5

我终于设法找到适当的代码行来使用Batik来解决这个问题.

您需要将SVG文件和生成的PDF作为磁盘上的文件,即我找不到在内存中执行此操作的方法(我正在编写HTTP Servlet,因此我没有内在的需要将任何内容写为文件,理想情况下,我会将结果流式传输到HTTP客户端).我使用File.createTemporaryFile来创建一个文件,将我的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();
Run Code Online (Sandbox Code Playgroud)

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

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