将 SVG 转换为 PDF
如何以编程方式将 SVG 文件转换为 PDF? (在生成 PDF 之前,我需要在某些方面更改 SVG,因此仅使用工具对其进行预转换是不够的。)
理想情况下,使用 Java,但 Perl 或 PHP 也可以。
显然,我基本上正在考虑 Apache FOP 和 Batik 与 Java。然而,无论我搜索多久,我都找不到关于如何操作的简单介绍。像 SVGConverter 这样的描述有“定义能够转换部分或全部 GraphicContext 的类的接口”,但我真的不知道这意味着什么。
一定有一个 API 可以非常简单地做到这一点,由 FOP 或 Batik 提供,但我现在找不到它(或者也许它真的不存在)。
我有这种感觉, 我需要的 SVG 功能,该文件有一些路径,其中填充了一些线性渐变。
理想情况下,如果我可以将 SVG 作为 DOM 文档传递,那就太理想了;然后我会加载我的模板 SVG 文件,按照用户指定的方式更改它,然后生成 PDF。
How would one go about converting a SVG file to a PDF programatically? (I need to alter the SVG in certain respects before generating the PDF so simply pre-converting it using a tool won't be sufficient.)
Ideally using Java but Perl or PHP would be fine too.
Obviously I am basically considering Apache FOP and Batik with Java. However no matter how long I search I cannot find a simple introduction on how to do it. Things like SVGConverter have descriptions like "Defines the interface for classes that are able to convert part or all of a GraphicContext", but I don't really know what that means.
I have this feeling there must be an API to do this quite simply, provided by FOP or Batik, but I'm just not able to find it at the moment (or perhaps it really doesn't exist.)
In terms of the supported SVG features I need, the file has some paths which are filled with some linear gradients.
Ideally if I could pass the SVG in as a DOM Document that would be ideal; then I would load my template SVG file, change it as specified by the user, and then generate the PDF.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
感谢 Adrian 展示了应该如何使用 Batik 光栅化器 API。但是,我需要一个更轻量级的解决方案——我无法写入临时文件,并且我想要更少的依赖项。因此,从他指出的方法开始,我找到了一种访问较低级别代码来进行转换的方法,仅此而已。
编译和运行命令是
重要的一点是
TranscoderInput< /code>
和
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 构建项目),您必须手动查找类。它们可以在 Batik 项目 的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
蜡染-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
Thanks to Adrian for showing how the Batik rasterizer API is supposed to be used. However, I needed a more lightweight solution--- I can't write to temporary files, and I want fewer dependencies. So, starting from the methods he pointed to, I found a way to access the lower-level code to do the conversion and nothing else.
The compile-and-run commands are
The important point is that
TranscoderInput
andTranscoderOutput
can work with anyInputStream
andOutputStream
, not just file streams. Note that one of the constructors takes aorg.w3c.dom.Document
, which means that you don't even need to serialize an SVG DOM into an SVG string, saving an additional step.This version also doesn't write anything to stdout/stderr, unlike the high-level API.
For JPEG, PNG, or TIFF output, replace
org.apache.fop.svg.PDFTranscoder
withorg.apache.batik.transcoder.image.JPEGTranscoder
,PNGTranscoder
, orTIFFTranscoder
(note that these raster formats are in a different package).(I'm not quite sure how Java finds the
org.apache.batk.transcoder.*
andorg.apache.fop.svg.PDFTranscoder
classes, since I don't see them in thebatik-rasterizer.jar
.)Edit:
Although the simple commandline-compilation works with the
batik-rasterizer.jar
only, it's doing some sort of classloader magic to find all the necessary classes. In a more realistic case (building a project with Ant), you have to find the classes by hand. They can be found inbatik-1.7.zip
from the Batik project andfop-1.1.zip
from the FOP project. From Batik, you need to compile withbatik-transcoder.jar
and run withbatik-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
From FOP, you need to compile with
fop.jar
and run withfop.jar
avalon-framework-4.2.0.jar
xmlgraphics-commons-1.5.jar
我终于设法找到适当的代码行来使用 Batik 解决这个问题。
您需要将 SVG 文件和生成的 PDF 作为磁盘上的文件,即我找不到在内存中执行此操作的方法(我正在编写 HTTP Servlet,因此我没有内在需要将任何内容写入文件,理想情况下我会将结果流式传输到 HTTP 客户端)。我使用了 File.createTemporaryFile 创建一个文件,将我的 SVG 转储到文件中,并将生成的 PDF 写入其中。
所以我使用的行如下:
我有以下 JAR(使用 Google 搜索来查找项目并下载它们):
I finally managed to find the appropriate lines of code to solve this using the Batik.
You need to have the SVG file and the resulting PDF as files on the disk, i.e. I couldn't find a way to do it in-memory (I am writing a HTTP Servlet so I have no intrinsic need to write anything as a file, ideally I would stream the result to the HTTP client). I used File.createTemporaryFile to create a file to dump out my SVG to a file, and for the resulting PDF to be written to.
So the lines I used are the following:
And I have the following JARs (search using Google to find the projects and download them):
你需要一个库来渲染 svg 和 pdf。
对于前者,我推荐 SVG salamander ,而 iText 适用于后者。使用 svg salamander,您可以读取 svg 并创建图像对象,使用 itext,您可以将该图像写入 pdf。
you will need a libray for rendering svg's and pdf's.
I recommend SVG salamander for the former, and iText for the latter. With svg salamander you can to read the svg and create an image object, and with itext you can write that image to a pdf.
我使用 Altsoft Xml2PDF。如果我正确理解您的所有需求和要求,您最好尝试他们的服务器版本的 Xml2PDF。
I use Altsoft Xml2PDF. If I understood correctly all your needs and requirement, you'd better try their Server version of Xml2PDF.
你所需要的只是 phantomjs。你根本不需要笨重的蜡染布来做这件事;只需到达可以运行 phantomjs、调用 rasterize.js、使用 pdf 的 url 作为源、位置作为输出的程度即可。根据您想要对 .pdf 执行的操作,您甚至不需要 Java。
http://phantomjs.org/screen-capture.html
看一下以“Beside”开头的部分PNG 格式,PhantomJS 支持 JPEG、GIF 和 PDF。”
All you need is phantomjs. You don't need the unwieldy Batik for this at all; just get to a point where you can run phantomjs, calling rasterize.js, using the url of the pdf as a source, and a location as the output. Depending on what you want to do with the .pdf, you don't even need Java.
http://phantomjs.org/screen-capture.html
Look at the part starting with "Beside PNG format, PhantomJS supports JPEG, GIF, and PDF."