From ff398190ec9be0407ea7701fd8de7fde9c38da00 Mon Sep 17 00:00:00 2001 From: Jakob Silbereisen Date: Wed, 26 Nov 2025 16:31:24 +0100 Subject: [PATCH 1/4] Support SVG Pictures in XSSFWorkbook --- .../apache/poi/xssf/usermodel/XSSFPictureData.java | 3 ++- .../org/apache/poi/xssf/usermodel/XSSFRelation.java | 7 +++++++ .../poi/xssf/usermodel/XSSFSignatureLine.java | 2 ++ .../org/apache/poi/xssf/usermodel/XSSFWorkbook.java | 13 +++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java index 3683f033ae2..0e6c2d65396 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java @@ -57,7 +57,7 @@ public static int getMaxImageSize() { */ protected static final POIXMLRelation[] RELATIONS; static { - RELATIONS = new POIXMLRelation[13]; + RELATIONS = new POIXMLRelation[15]; RELATIONS[Workbook.PICTURE_TYPE_EMF] = XSSFRelation.IMAGE_EMF; RELATIONS[Workbook.PICTURE_TYPE_WMF] = XSSFRelation.IMAGE_WMF; RELATIONS[Workbook.PICTURE_TYPE_PICT] = XSSFRelation.IMAGE_PICT; @@ -69,6 +69,7 @@ public static int getMaxImageSize() { RELATIONS[XSSFWorkbook.PICTURE_TYPE_EPS] = XSSFRelation.IMAGE_EPS; RELATIONS[XSSFWorkbook.PICTURE_TYPE_BMP] = XSSFRelation.IMAGE_BMP; RELATIONS[XSSFWorkbook.PICTURE_TYPE_WPG] = XSSFRelation.IMAGE_WPG; + RELATIONS[XSSFWorkbook.PICTURE_TYPE_SVG] = XSSFRelation.IMAGE_SVG; } /** diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRelation.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRelation.java index 5012767b598..c827143e959 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRelation.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRelation.java @@ -239,6 +239,13 @@ public final class XSSFRelation extends POIXMLRelation { XSSFPictureData::new, XSSFPictureData::new ); + public static final XSSFRelation IMAGE_SVG = new XSSFRelation( + PictureData.PictureType.SVG.contentType, + PackageRelationshipTypes.IMAGE_PART, + "/xl/media/image#.svg", + XSSFPictureData::new, XSSFPictureData::new + ); + public static final XSSFRelation HDPHOTO_WDP = new XSSFRelation( PictureData.PictureType.WDP.contentType, PackageRelationshipTypes.HDPHOTO_PART, diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSignatureLine.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSignatureLine.java index 99a6ddd58b2..da81eb9bf1d 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSignatureLine.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSignatureLine.java @@ -126,6 +126,8 @@ private static POIXMLRelation mapType(PictureType type) throws InvalidFormatExce return XSSFRelation.IMAGE_WMF; case WPG: return XSSFRelation.IMAGE_WPG; + case SVG: + return XSSFRelation.IMAGE_SVG; default: throw new InvalidFormatException("Unsupported picture format "+type); } diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index b1c63c6a983..e045a8cd269 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -122,6 +122,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Date1904Su public static final int PICTURE_TYPE_EPS = 10; public static final int PICTURE_TYPE_BMP = 11; public static final int PICTURE_TYPE_WPG = 12; + public static final int PICTURE_TYPE_SVG = 14; /** * The underlying XML bean @@ -592,6 +593,12 @@ public CTWorkbook getCTWorkbook() { * @see Workbook#PICTURE_TYPE_JPEG * @see Workbook#PICTURE_TYPE_PNG * @see Workbook#PICTURE_TYPE_DIB + * @see #PICTURE_TYPE_GIF + * @see #PICTURE_TYPE_TIFF + * @see #PICTURE_TYPE_EPS + * @see #PICTURE_TYPE_BMP + * @see #PICTURE_TYPE_WPG + * @see #PICTURE_TYPE_SVG * @see #getAllPictures() */ @Override @@ -620,6 +627,12 @@ public int addPicture(byte[] pictureData, int format) { * @see Workbook#PICTURE_TYPE_JPEG * @see Workbook#PICTURE_TYPE_PNG * @see Workbook#PICTURE_TYPE_DIB + * @see #PICTURE_TYPE_GIF + * @see #PICTURE_TYPE_TIFF + * @see #PICTURE_TYPE_EPS + * @see #PICTURE_TYPE_BMP + * @see #PICTURE_TYPE_WPG + * @see #PICTURE_TYPE_SVG * @see #getAllPictures() */ public int addPicture(InputStream is, int format) throws IOException { From ac50df67844d592361f8881ec53075a0a0d54a86 Mon Sep 17 00:00:00 2001 From: Jakob Silbereisen Date: Wed, 26 Nov 2025 16:41:23 +0100 Subject: [PATCH 2/4] Add Testcase for adding a Picture with PICTURE_TYPE_SVG --- .../xssf/usermodel/TestXSSFPictureData.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java index fa1cb561369..db575ffa9a2 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java @@ -143,6 +143,37 @@ void testNewPictFormat() throws IOException { } } + @Test + void testNewSvgFormat() throws IOException { + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sheet = wb.createSheet(); + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + + byte[] data = "test svg data".getBytes(LocaleUtil.CHARSET_1252); + + List pictures = wb.getAllPictures(); + assertEquals(0, pictures.size()); + + int idx = wb.addPicture(data, XSSFWorkbook.PICTURE_TYPE_SVG); + assertEquals(1, pictures.size()); + assertEquals("svg", pictures.get(idx).suggestFileExtension()); + assertArrayEquals(data, pictures.get(idx).getData()); + + //TODO finish usermodel API for XSSFPicture + XSSFPicture p1 = drawing.createPicture(new XSSFClientAnchor(), idx); + assertNotNull(p1); + + //check that the added pictures are accessible after write + try (XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(wb)) { + List pictures2 = wbBack.getAllPictures(); + assertEquals(1, pictures2.size()); + + assertEquals("svg", pictures2.get(idx).suggestFileExtension()); + assertArrayEquals(data, pictures2.get(idx).getData()); + } + } + } + /** * Bug 53568: XSSFPicture.getPictureData() can return null. */ From f6de40465c777923fdb1181f046d48bd351ef806 Mon Sep 17 00:00:00 2001 From: Jakob Silbereisen Date: Thu, 27 Nov 2025 16:12:15 +0100 Subject: [PATCH 3/4] Change test data to actual SVG sample data --- .../org/apache/poi/xssf/usermodel/TestXSSFPictureData.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java index db575ffa9a2..8b1e68e6df4 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFPictureData.java @@ -148,8 +148,10 @@ void testNewSvgFormat() throws IOException { try (XSSFWorkbook wb = new XSSFWorkbook()) { XSSFSheet sheet = wb.createSheet(); XSSFDrawing drawing = sheet.createDrawingPatriarch(); - - byte[] data = "test svg data".getBytes(LocaleUtil.CHARSET_1252); + String svg = "" + + "10" + + ""; + byte[] data = svg.getBytes(LocaleUtil.CHARSET_1252); List pictures = wb.getAllPictures(); assertEquals(0, pictures.size()); From 52c2589ccd7476d21ed92bf7ebbe7555d348c10a Mon Sep 17 00:00:00 2001 From: Jakob Silbereisen Date: Fri, 5 Dec 2025 08:08:21 +0100 Subject: [PATCH 4/4] Placeholder for WDP --- .../main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java | 1 + 1 file changed, 1 insertion(+) diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index e045a8cd269..f92b055b264 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -122,6 +122,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Date1904Su public static final int PICTURE_TYPE_EPS = 10; public static final int PICTURE_TYPE_BMP = 11; public static final int PICTURE_TYPE_WPG = 12; + // Picture Type WDP has ooxmlId 13 but is currently not implemented public static final int PICTURE_TYPE_SVG = 14; /**