如何以编程方式将SVG文件转换为PDF? (我需要在生成PDF之前在某些方面更改SVG,因此使用工具进行预转换是不够的。)
理想情况下使用Java,但Perl或PHP也可以。
显然我基本上在考虑使用Java FOP和Batik。然而,无论我搜索多久,我都找不到如何做到的简单介绍。像SVGConverter这样的描述有“定义能够转换部分或全部GraphicContext的类的接口”的描述,但我真的不知道这意味着什么。
我有这种感觉必须有一个API来完成这个,非常简单,由FOP或Batik提供,但我现在无法找到它(或者它可能真的不存在。)
就我所需的支持的SVG功能而言,该文件有一些路径填充了一些线性渐变。
理想情况下,如果我可以将SVG作为理想的DOM文档传递;然后我会加载我的模板SVG文件,按照用户的指定进行更改,然后生成PDF。
答案 0 :(得分:17)
感谢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);
}
}
编译运行命令
javac -cp batik-rasterizer.jar -d build Test.java
java -cp build:batik-rasterizer.jar Test
重点是,TranscoderInput
和TranscoderOutput
可以与任何InputStream
和OutputStream
一起使用,而不仅仅是文件流。请注意,其中一个构造函数需要org.w3c.dom.Document
,这意味着您甚至不需要将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
和the FOP project的fop-1.1.zip
找到它们。从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
答案 1 :(得分: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();
我有以下JAR(使用Google搜索以查找项目并下载它们):
答案 2 :(得分:4)
你需要一个libray来渲染svg和pdf。 我建议前者SVG salamander,后者iText。使用svg salamander,您可以读取svg并创建一个图像对象,使用itext可以将该图像写入pdf。
答案 3 :(得分:1)
我使用的是Altsoft Xml2PDF。如果我正确理解了您的所有需求和要求,您最好尝试他们的服务器版Xml2PDF。
答案 4 :(得分:1)
你需要的只是幻影。你根本不需要笨重的蜡染布;只需要运行phantomjs,调用rasterize.js,使用pdf的url作为源,并将位置作为输出。根据您对.pdf的要求,您甚至不需要Java。
http://phantomjs.org/screen-capture.html
查看以&#34开头的部分;除了PNG格式外,PhantomJS还支持JPEG,GIF和PDF。"