我发现了 iText 作者的几个示例,它们使用 Graphics2D API 和 Apache Batik 库在 PDF 中绘制 SVG。
http://itextpdf.com/examples/iia.php?id=269
http://itextpdf.com/examples/iia.php?id=263
出于我的目的,我需要获取一串 SVG 并在 PDF 中以特定大小和位置绘制它,同时保持图像的矢量性质(无光栅化)。
我想绕过 SAXSVGDocumentFactory.createSVGDocument() 函数中流行的 SVG 文件。我发现以下帖子有助于使用 SVG 文本字符串而不是平面文件。
http://batik.2283329.n4.nabble.com/Parse-SVG-from-String-td3539080.html
您必须从您的 String 创建一个 StringReader 并将其传递给 SAXSVGDocumentFactory#createDocument(String, Reader) 方法。作为字符串的第一个参数传递的 URI 将是 SVG 文档的基本文档 URI。仅当您的 SVG 引用任何外部文件时,这才重要。
最好的祝福,
丹尼尔
源自 iText 示例的 Java 源代码:
// SVG as a text string.
String svg = "<svg>...</svg>";
// Create the PDF document.
// rootPath is the present working directory path.
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(new File(rootPath + "svg.pdf")));
document.open();
// Add paragraphs to the document...
document.add(new Paragraph("Paragraph 1"));
document.add(new Paragraph(" "));
// Boilerplate for drawing the SVG to the PDF.
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(userAgent);
BridgeContext ctx = new BridgeContext(userAgent, loader);
ctx.setDynamicState(BridgeContext.DYNAMIC);
GVTBuilder builder = new GVTBuilder();
PdfContentByte cb = writer.getDirectContent();
// Parse the SVG and draw it to the PDF.
Graphics2D g2d = new PdfGraphics2D(cb, 725, 400);
SVGDocument chart = factory.createSVGDocument(rootPath, new StringReader(svg));
GraphicsNode chartGfx = builder.build(ctx, chart);
chartGfx.paint(g2d);
g2d.dispose();
// Add paragraphs to the document...
document.add(new Paragraph("Paragraph 2"));
document.add(new Paragraph(" "));
document.close();
请注意,这会将 SVG 绘制到您正在处理的 PDF 中。SVG 显示为文本上方的浮动层。我仍在努力移动/缩放它并让它与文本内联,但希望这超出了问题的直接范围。
希望这能有所帮助。
干杯
编辑:我能够使用以下方法将我的 svg 实现为内联对象。注释行用于添加快速边框以检查定位。
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(userAgent);
BridgeContext ctx = new BridgeContext(userAgent, loader);
ctx.setDynamicState(BridgeContext.DYNAMIC);
GVTBuilder builder = new GVTBuilder();
SVGDocument svgDoc = factory.createSVGDocument(rootPath, new StringReader(svg));
PdfTemplate svgTempl = PdfTemplate.createTemplate(writer, Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width")), Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height")));
Graphics2D g2d = new PdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight());
GraphicsNode chartGfx = builder.build(ctx, svgDoc);
chartGfx.paint(g2d);
g2d.dispose();
Image svgImg = new ImgTemplate(svgTempl);
svgImg.setAlignment(Image.ALIGN_CENTER);
//svgImg.setBorder(Image.BOX);
//svgImg.setBorderColor(new BaseColor(0xff, 0x00, 0x00));
//svgImg.setBorderWidth(1);
document.add(svgImg);