art*_*doe 5 java pdf svg batik apache-fop
我有两个简单的SVG文档,我想将其转换为PDF,以便每个文档都位于PDF的一页上。
我的第一个SVG文档有两个矩形,如下所示:

第二个是黑圈。
该代码如下所示:
import java.io.*;
import org.apache.batik.anim.dom.*;
import org.apache.batik.transcoder.*;
import org.w3c.dom.*;
public class MultiPagePdf {
public static void main(String[] args) {
MultiPagePDFTranscoder transcoder = new MultiPagePDFTranscoder();
try {
final DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
SVGOMDocument doc1 = (SVGOMDocument) impl.createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", null);
// 1st rectangle in doc1
Element el = doc1.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "rect");
el.setAttributeNS(null, "width", "60");
el.setAttributeNS(null, "height", "60");
el.setAttributeNS(null, "fill", "none");
el.setAttributeNS(null, "stroke", "blue");
SVGOMSVGElement docEl = (SVGOMSVGElement) doc1.getDocumentElement();
docEl.appendChild(el);
// 2nd rectangle in doc1
Element ell = doc1.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "rect");
ell.setAttributeNS(null, "x", "50");
ell.setAttributeNS(null, "y", "50");
ell.setAttributeNS(null, "width", "25");
ell.setAttributeNS(null, "height", "25");
ell.setAttributeNS(null, "fill", "green");
docEl.appendChild(ell);
final DOMImplementation impl2 = SVGDOMImplementation.getDOMImplementation();
SVGOMDocument doc2 = (SVGOMDocument) impl2.createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", null);
// circle in doc2
Element el2 = doc2.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "circle");
el2.setAttributeNS(null, "cx", "130");
el2.setAttributeNS(null, "cy", "100");
el2.setAttributeNS(null, "r", "50");
SVGOMSVGElement docEl2 = (SVGOMSVGElement) doc2.getDocumentElement();
docEl2.appendChild(el2);
OutputStream outputStream = new FileOutputStream(new File("/C:/Users/ah/Documents/simpleMulti.pdf"));
TranscoderOutput transcoderOutput = new TranscoderOutput(outputStream);
Document[] doccs = { doc1, doc2 };
transcoder.transcode(doccs, null, transcoderOutput); // generate PDF doc
} catch (Exception e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经打印了这两个SVG文档,它们看起来应该像这样:
第一份SVG文件:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="text/ecmascript" zoomAndPan="magnify" contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" version="1.0">
<rect fill="none" width="60" height="60" stroke="blue"/>
<rect fill="green" x="50" width="25" height="25" y="50"/>
</svg>
Run Code Online (Sandbox Code Playgroud)
第二份SVG文件:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="text/ecmascript" zoomAndPan="magnify" contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" version="1.0">
<circle r="50" cx="130" cy="100"/>
</svg>
Run Code Online (Sandbox Code Playgroud)
我发现使用Apache FOP 之后应该执行的代码;我有以下代码来生成PDF:
import java.io.*;
import java.util.*;
import org.apache.batik.transcoder.*;
import org.apache.fop.*;
import org.apache.fop.svg.*;
import org.w3c.dom.*;
public class MultiPagePDFTranscoder extends AbstractFOPTranscoder {
protected PDFDocumentGraphics2D graphics = null;
protected Map<String, Object> params = null;
public MultiPagePDFTranscoder() {
super();
}
protected void transcode(Document[] documents, String uri, TranscoderOutput output) throws TranscoderException {
graphics = new PDFDocumentGraphics2D(isTextStroked());
graphics.getPDFDocument().getInfo().setProducer("Apache FOP Version " + Version.getVersion() + ": PDF Transcoder for Batik");
try {
OutputStream out = output.getOutputStream();
if (!(out instanceof BufferedOutputStream)) {
out = new BufferedOutputStream(out);
}
for (int i = 0; i < documents.length; i++) {
Document document = documents[i];
super.transcode(document, uri, null);
int tmpWidth = 300;
int tmpHeight = 300;
if (i == 0) {
graphics.setupDocument(out, tmpWidth, tmpHeight);
} else {
graphics.nextPage(tmpWidth, tmpHeight);
}
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
graphics.transform(curTxf);
this.root.paint(graphics);
}
graphics.finish();
} catch (IOException ex) {
throw new TranscoderException(ex);
}
}
}
Run Code Online (Sandbox Code Playgroud)
PDF文件已生成,但是我有两个问题。
SVG元素的翻译和比例不正确。
在第二页上,存在第一个文档(我尝试了多个页面,并且所有先前的文档都在当前页面上)。

我将Apache FOP 2.1与Apache Batik 1.8一起使用。
任何一个问题的帮助将不胜感激。我也愿意接受其他解决方案来完成我的整体任务(将SVG转换为多页PDF)。
小智 2
我有类似的问题。我的方法是使用 Batik 中的 SVGConverter 应用程序 (org.apache.batik.apps.rasterizer.SVGConverter) 将单个 SVG 转换为 PDF,然后使用PDFBox (org.apache.pdfbox.pdf) 将它们粘贴到一个文件中。 multipdf.PDFMergerUtility)。
将 SVG 转换为单页 PDF:
File outputFile = new File(pdfPath);
SVGConverter converter = new SVGConverter();
converter.setDestinationType(DestinationType.PDF);
converter.setSources(new String[] { svgPath });
converter.setDst(outputFile);
converter.execute();
Run Code Online (Sandbox Code Playgroud)
将 PDF 连接在一起:
File pdffile = new File(multipagepdfPath);
PDFMergerUtility pdf = new PDFMergerUtility();
pdf.setDestinationFileName(pdffile.getPath());
pdf.addSource(page1pdffile);
pdf.addSource(page2pdffile);
pdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
//The memory settings depend on if you want to use RAM or Temp files.
Run Code Online (Sandbox Code Playgroud)
如果您找到更好的解决方案,请告诉我。我遇到的主要问题是转换器应用程序是 Batik 中唯一可以转换为 pdf 并保持正确尺寸的应用程序。