Excel automatically converts SVG to PNG and saves both the copies.
When we use apache poi v5.0.0
to fetch the picture data,
XSSFPicture picture = (XSSFPicture) shape;
System.out.println(picture.getPictureData().suggestFileExtension()); // output: png
we get the PNG
format of the picture.
If we want to get the original SVG
picture data, we can make use of the following method(Traversal taken from here):
private void traverseShapeContainer(ShapeContainer<XSSFShape> container) {
for (XSSFShape shape : container) {
if (shape instanceof XSSFConnector) {
} else if (shape instanceof XSSFGraphicFrame) {
} else if (shape instanceof XSSFPicture) {
XSSFPicture picture = (XSSFPicture) shape;
System.out.println(picture.getPictureData().suggestFileExtension());
if (picture.getPictureData().suggestFileExtension().equals("png")) {
XSSFPictureData svgPictureData = getSVGPicture(picture);
if (Objects.nonNull(svgPictureData)) {
byte[] svgData = svgPictureData.getData();
}
}
} else if (shape instanceof XSSFShapeGroup) { // we have a shape group
XSSFShapeGroup shapeGroup = (XSSFShapeGroup) shape;
System.out.println(shapeGroup);
traverseShapeContainer(shapeGroup);
} else if (shape instanceof XSSFSimpleShape) {
}
}
}
private XSSFPictureData getSVGPicture(XSSFPicture picture) {
CTOfficeArtExtensionList extLst = picture.getCTPicture().getBlipFill().getBlip().getExtLst();
if (Objects.nonNull(extLst)) {
List<CTOfficeArtExtension> extList = extLst.getExtList();
for (var ext : extList) {
var extNodes = ext.getDomNode().getChildNodes();
for (int i = 0; i < extNodes.getLength(); i++) {
var extNode = extNodes.item(i);
if (extNode.getNodeName().equals("asvg:svgBlip")) {
var attr = extNode.getAttributes().getNamedItem("r:embed");
if (Objects.nonNull(attr)) {
String relationId = attr.getNodeValue();
// accesses the drawings.xml.rels to get the data corresponding to the relationId
XSSFPictureData svgPictureData = (XSSFPictureData) picture.getDrawing()
.getRelationById(relationId);
System.out.println(svgPictureData.suggestFileExtension()); // output: svg
return svgPictureData;
}
}
}
}
}
return null;
}
This definitely solves the problem, however is there a better approach to geting the SVG
picture data?