Java实现PDF转SVG并保留可编辑文本的方法咨询
Java实现PDF转SVG并保留文本内容的方法
你可以通过调整工具使用方式或换用更直接的PDF解析方案实现,以下是具体方法:
方法一:使用Apache PDFBox的SVGConverter类(推荐)
PDFBox提供了专门的SVG转换工具,能直接解析PDF中的文本元素并生成保留文本的SVG,无需依赖打印流程。示例代码如下:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.tools.SVGConverter; import java.io.File; import java.io.IOException; public class PdfToSvgWithText { public static void main(String[] args) throws IOException { try (PDDocument document = PDDocument.load(new File("input.pdf"))) { SVGConverter converter = new SVGConverter(); // 设置输出目录,每个页面生成单独的SVG文件 converter.setOutputDir(new File("output_svgs")); // 显式关闭文本转路径,确保保留文本元素 converter.setRenderTextAsPath(false); converter.convert(document); } } }
需确保使用PDFBox 2.0及以上版本,该工具会直接解析PDF的文本对象,将其转换为SVG的<text>元素,而非路径。
方法二:自定义PDF文本提取+Batik生成SVG
如果需要更精细的控制,可以手动提取PDF中的文本及其位置、字体信息,再用Batik的SVGGraphics2D直接绘制文本:
- 继承PDFBox的
PDFTextStripper,重写方法提取文本的坐标、内容、字体大小等信息 - 初始化
SVGGraphics2D,根据提取的信息调用drawString()绘制文本 - 导出SVG文件
示例简化代码:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import org.apache.pdfbox.text.TextPosition; import org.apache.batik.svggen.SVGGraphics2D; import org.w3c.dom.svg.SVGDocument; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.svg.SVGFactory; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class CustomPdfToSvg { static class TextInfo { String content; float x; float y; float fontSize; String fontName; public TextInfo(String content, float x, float y, float fontSize, String fontName) { this.content = content; this.x = x; this.y = y; this.fontSize = fontSize; this.fontName = fontName; } } public static void main(String[] args) throws Exception { List<TextInfo> textInfos = new ArrayList<>(); try (PDDocument document = PDDocument.load(new File("input.pdf"))) { PDFTextStripper stripper = new PDFTextStripper() { @Override protected void writeString(String text, List<TextPosition> textPositions) throws IOException { for (TextPosition tp : textPositions) { textInfos.add(new TextInfo( tp.getUnicode(), tp.getX(), document.getPage(0).getMediaBox().getHeight() - tp.getY(), tp.getFontSizeInPt(), tp.getFont().getName() )); } } }; stripper.setStartPage(1); stripper.setEndPage(1); stripper.getText(document); // 初始化SVG生成器 DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); SVGFactory factory = ((org.w3c.dom.svg.SVGDOMImplementation) registry.getDOMImplementation("SVG")) .createSVGFactory(); SVGDocument svgDoc = factory.createSVGDocument("http://www.w3.org/2000/svg"); SVGGraphics2D svgGenerator = new SVGGraphics2D(svgDoc); // 绘制文本 for (TextInfo info : textInfos) { svgGenerator.setFont(new java.awt.Font(info.fontName, java.awt.Font.PLAIN, (int) info.fontSize)); svgGenerator.drawString(info.content, info.x, info.y); } // 导出SVG try (FileWriter writer = new FileWriter("output.svg")) { svgGenerator.stream(writer, true); } } } }
这种方式需要处理字体映射、坐标转换等细节,适合需要自定义文本样式的场景。
内容的提问来源于stack exchange,提问作者Chiaki
相关产品推荐
相关产品推荐

