如何以编程方式将 SVG 文件转换为 PDF?(在生成 PDF 之前,我需要在某些方面更改 SVG,因此使用工具进行预转换是不够的。)
理想情况下使用 Java,但 Perl 或 PHP 也可以。
显然,我基本上正在考虑使用 Java 的 Apache FOP 和 Batik。但是,无论我搜索多长时间,我都找不到关于如何做到这一点的简单介绍。像SVGConverter这样的描述是“为能够转换部分或全部 GraphicContext 的类定义接口”,但我真的不知道这意味着什么。
我有这种感觉,必须有一个 API 来做到这一点很简单,由 FOP 或蜡染提供,但我只是无法找到它的时刻(或者也许它真的不存在。)
在我需要的支持 SVG 功能方面,该文件有一些填充了一些线性梯度的路径。
理想情况下,如果我可以将 SVG 作为理想的 DOM 文档传递;然后我将加载我的模板 SVG 文件,按照用户指定的方式更改它,然后生成 PDF。
感谢 Adrian 展示了 Batik rasterizer 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 cl 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
重要的一点是,TranscoderInput
和TranscoderOutput
可以处理任何InputStream
和OutputStream
,而不仅仅是文件流。请注意,其中一个构造函数采用org.w3c.dom.Doent
,这意味着您甚至不需要将 SVG DOM 序列化为 SVG 字符串,从而节省了额外的步骤。
与高级 API 不同,此版本也不会向 stdout / stderr 写入任何内容。
对于 JPEG 、 PNG 或 TIFF 输出,请将org.apache.fop.svg.PDFTranscoder
替换为org.apache.batik.transcoder.image.JPEGTranscoder
、PNGTranscoder
或TIFFTranscoder
(请注意,这些光栅格式位于不同的包中)。
(我不太清楚 Java 如何找到org.apache.batk.transcoder.*
和org.apache.fop.svg.PDFTranscoder
类,因为我没有在batik-rasterizer.jar
中看到它们。)
虽然简单的命令行编译仅适用于batik-rasterizer.jar
,但它正在执行某种类加载器魔术来查找所有必要的类。在更实际的情况下(使用 Ant 构建项目),您必须手动查找类。它们可以在the Batik project的batik-1.7.zip
和fop-1.1.zip
中找到,与the FOP project一起运行
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-pr.jar
batik-script.jar
batik-svg-dom.jar
batik-util.jar
batik-xml.jar
xml-a-ext.jar
从 FOP,您需要使用fop.jar
编译并运行
fop.jar
avalon-framework-4.2.0.jar
xmlgraphics-commons-1.5.jar
我终于设法找到适当的代码行来解决这个问题使用Batik。
您需要将 SVG 文件和生成的 PDF 作为磁盘上的文件,即我找不到在内存中执行此操作的方法(我正在编写 HTTP Servlet,因此我没有内在需要将任何内容作为文件写入,理想情况下,我会将结果流式传输到 HTTP 客户端)。
所以我使用的行如下:
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)
Doent 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(使用谷歌搜索找到项目并下载它们):
avalon-framework-4.2.0.jar
蜡染-所有-1.7.jar
commons-io-1.3.1.jar
commons-logging-1.0.4.jar
fop-0.95.jar
log4j-1.2.15.jar
xml-a-ext.jar
xmlgraphics-commons-1.3.1.jar
你需要一个 libray 来渲染 svg 和 pdf。我建议前者SVG sander,后者iText。使用 svg sander,您可以读取 svg 并创建一个图像对象,使用 itext,您可以将该图像写入 pdf。
我使用 Altsoft Xml2PDF。如果我正确理解您的所有需求和要求,您最好尝试他们的服务器版本 Xml2PDF。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(74条)