Java中如何将SVG字符串转PNG并插入HSSFWorkbook生成的Excel?
解决SVG字符串转PNG字节数组并插入Excel的问题
我来帮你搞定这个需求——不用把PNG存到本地文件,直接在内存里把SVG字符串转成PNG字节数组,再插入到你的HSSFWorkbook里就行。核心是用Apache Batik库来处理SVG到PNG的内存转换,下面是详细步骤和代码:
1. 引入必要依赖
首先需要引入Apache Batik的相关依赖,如果你用Maven,把下面的依赖加到pom.xml里:
<dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>batik-transcoder</artifactId> <version>1.17</version> </dependency> <dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>batik-codec</artifactId> <version>1.17</version> </dependency>
Gradle用户可以对应添加:
implementation 'org.apache.xmlgraphics:batik-transcoder:1.17' implementation 'org.apache.xmlgraphics:batik-codec:1.17'
2. 编写SVG转PNG字节数组的工具方法
这个方法会把SVG字符串直接在内存里转换成PNG的字节数组,完全不需要落地文件:
import org.apache.batik.transcoder.TranscoderException; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.PNGTranscoder; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public byte[] svgToPngBytes(String svgString) throws IOException, TranscoderException { // 创建PNG转换器 PNGTranscoder transcoder = new PNGTranscoder(); // 可选:设置输出图片的尺寸,不设置则用SVG本身的尺寸 // transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, new Float(600)); // transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, new Float(400)); // 把SVG字符串转成输入流 ByteArrayInputStream svgInputStream = new ByteArrayInputStream(svgString.getBytes()); TranscoderInput input = new TranscoderInput(svgInputStream); // 用ByteArrayOutputStream接收转换后的PNG数据 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); TranscoderOutput output = new TranscoderOutput(outputStream); // 执行转换 transcoder.transcode(input, output); // 转成字节数组返回 return outputStream.toByteArray(); }
3. 整合到你的Excel插入逻辑里
现在把这个工具方法和你的HSSFWorkbook代码结合起来,完整示例如下:
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Workbook; import java.io.FileOutputStream; import java.io.IOException; public void insertSvgIntoExcel(String svgString) throws Exception { // 1. 把SVG转成PNG字节数组 byte[] pngBytes = svgToPngBytes(svgString); // 2. 创建HSSFWorkbook Workbook wb = new HSSFWorkbook(); var sheet = wb.createSheet("Chart Sheet"); // 3. 添加图片到工作簿 int pictureIdx = wb.addPicture(pngBytes, Workbook.PICTURE_TYPE_PNG); // 4. 创建绘图对象,把图片放到指定单元格位置 Drawing drawing = sheet.createDrawingPatriarch(); ClientAnchor anchor = wb.createClientAnchor(); // 设置图片左上角在A1单元格,右下角在D5单元格(可根据需求调整) anchor.setCol1(0); anchor.setRow1(0); anchor.setCol2(3); anchor.setRow2(4); drawing.createPicture(anchor, pictureIdx); // 5. 保存Excel文件 try (FileOutputStream fos = new FileOutputStream("chart_excel.xls")) { wb.write(fos); } finally { wb.close(); } }
注意事项
- 如果你的SVG里有外部资源(比如图片),可能需要额外处理资源加载,纯矢量SVG直接用上面的代码就没问题。
- 可以通过
transcodingHint调整输出PNG的尺寸、分辨率等参数,适配你的Excel布局需求。 - 记得根据业务场景,合理捕获或向上抛出方法中可能出现的异常。
内容的提问来源于stack exchange,提问作者amkz
相关产品推荐
相关产品推荐

