From cbb80e2943a1fdcf22ca8c969efd0e93b048f1e7 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Wed, 20 Jul 2011 07:38:01 +0000 Subject: [PATCH] Support for appending images to existing drawings in HSSF git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1148637 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../poi/hssf/model/InternalWorkbook.java | 7 +- .../record/AbstractEscherHolderRecord.java | 1 + .../poi/hssf/record/EscherAggregate.java | 29 +++-- .../poi/hssf/usermodel/HSSFPatriarch.java | 30 ++++-- .../poi/hssf/usermodel/HSSFPicture.java | 14 ++- .../apache/poi/hssf/usermodel/HSSFShape.java | 1 + .../apache/poi/hssf/usermodel/HSSFSheet.java | 16 +-- .../poi/hssf/usermodel/HSSFSimpleShape.java | 2 +- .../poi/hssf/usermodel/HSSFWorkbook.java | 23 ++-- .../org/apache/poi/ss/usermodel/Picture.java | 7 ++ .../poi/hssf/usermodel/TestHSSFPicture.java | 100 ++++++++++++++++++ 12 files changed, 193 insertions(+), 38 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 23fe366889..2452027a51 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + Support for appending images to existing drawings in HSSF Added initial support for bookmarks in HWFP 46250 - Fixed cloning worksheets with images 51524 - PapBinTable constructor is slow (regression) diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java index 2dbd877ab7..93d37acc4d 100644 --- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java +++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java @@ -2055,10 +2055,10 @@ public final class InternalWorkbook { /** * Finds the primary drawing group, if one already exists */ - public void findDrawingGroup() { + public DrawingManager2 findDrawingGroup() { if(drawingManager != null) { // We already have it! - return; + return drawingManager; } // Need to find a DrawingGroupRecord that @@ -2092,7 +2092,7 @@ public final class InternalWorkbook { if(bs instanceof EscherBSERecord) escherBSERecords.add((EscherBSERecord)bs); } } - return; + return drawingManager; } } } @@ -2122,6 +2122,7 @@ public final class InternalWorkbook { } } } + return drawingManager; } /** diff --git a/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java b/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java index 64ef36eafa..78893e1aa7 100644 --- a/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java +++ b/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java @@ -74,6 +74,7 @@ public abstract class AbstractEscherHolderRecord extends Record { } private void convertToEscherRecords( int offset, int size, byte[] data ) { + escherRecords.clear(); EscherRecordFactory recordFactory = new DefaultEscherRecordFactory(); int pos = offset; while ( pos < offset + size ) diff --git a/src/java/org/apache/poi/hssf/record/EscherAggregate.java b/src/java/org/apache/poi/hssf/record/EscherAggregate.java index 577e4c6743..50d5e5d3f3 100644 --- a/src/java/org/apache/poi/hssf/record/EscherAggregate.java +++ b/src/java/org/apache/poi/hssf/record/EscherAggregate.java @@ -53,6 +53,7 @@ import org.apache.poi.hssf.usermodel.HSSFShape; import org.apache.poi.hssf.usermodel.HSSFShapeContainer; import org.apache.poi.hssf.usermodel.HSSFShapeGroup; import org.apache.poi.hssf.usermodel.HSSFTextbox; +import org.apache.poi.hssf.usermodel.HSSFSimpleShape; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -622,7 +623,7 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { case ST_TEXTBOX: HSSFTextbox box = new HSSFTextbox( null, new HSSFClientAnchor() ); - patriarch.getChildren().add( box ); + patriarch.addShape( box ); convertRecordsToUserModel( shapeContainer, box ); break; @@ -644,19 +645,11 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { EscherClientAnchorRecord anchorRecord = (EscherClientAnchorRecord) getEscherChild( shapeContainer, EscherClientAnchorRecord.RECORD_ID ); - HSSFClientAnchor anchor = new HSSFClientAnchor(); - anchor.setCol1( anchorRecord.getCol1() ); - anchor.setCol2( anchorRecord.getCol2() ); - anchor.setDx1( anchorRecord.getDx1() ); - anchor.setDx2( anchorRecord.getDx2() ); - anchor.setDy1( anchorRecord.getDy1() ); - anchor.setDy2( anchorRecord.getDy2() ); - anchor.setRow1( anchorRecord.getRow1() ); - anchor.setRow2( anchorRecord.getRow2() ); + HSSFClientAnchor anchor = toClientAnchor(anchorRecord); HSSFPicture picture = new HSSFPicture( null, anchor ); picture.setPictureIndex( pictureIndex ); - patriarch.getChildren().add( picture ); + patriarch.addShape( picture ); } break; default: @@ -683,6 +676,20 @@ public final class EscherAggregate extends AbstractEscherHolderRecord { // log.log(POILogger.WARN, "Not processing objects into Patriarch!"); } + private HSSFClientAnchor toClientAnchor(EscherClientAnchorRecord anchorRecord){ + HSSFClientAnchor anchor = new HSSFClientAnchor(); + anchor.setAnchorType(anchorRecord.getFlag()); + anchor.setCol1( anchorRecord.getCol1() ); + anchor.setCol2( anchorRecord.getCol2() ); + anchor.setDx1( anchorRecord.getDx1() ); + anchor.setDx2( anchorRecord.getDx2() ); + anchor.setDy1( anchorRecord.getDy1() ); + anchor.setDy2( anchorRecord.getDy2() ); + anchor.setRow1( anchorRecord.getRow1() ); + anchor.setRow2( anchorRecord.getRow2() ); + return anchor; + } + private void convertRecordsToUserModel(EscherContainerRecord shapeContainer, Object model) { for(Iterator it = shapeContainer.getChildIterator(); it.hasNext();) { EscherRecord r = it.next(); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java index 201b1c6d99..672f82cc73 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java @@ -24,9 +24,11 @@ import java.util.List; import org.apache.poi.ddf.EscherComplexProperty; import org.apache.poi.ddf.EscherOptRecord; import org.apache.poi.ddf.EscherProperty; +import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.hssf.record.EscherAggregate; import org.apache.poi.ss.usermodel.Chart; import org.apache.poi.util.StringUtil; +import org.apache.poi.util.Internal; import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.ClientAnchor; @@ -72,7 +74,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { { HSSFShapeGroup group = new HSSFShapeGroup(null, anchor); group.anchor = anchor; - _shapes.add(group); + addShape(group); return group; } @@ -88,7 +90,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { { HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor); shape.anchor = anchor; - _shapes.add(shape); + addShape(shape); return shape; } @@ -104,10 +106,13 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { HSSFPicture shape = new HSSFPicture(null, anchor); shape.setPictureIndex( pictureIndex ); shape.anchor = anchor; - shape._patriarch = this; - _shapes.add(shape); + addShape(shape); + + EscherBSERecord bse = _sheet.getWorkbook().getWorkbook().getBSERecord(pictureIndex); + bse.setRef(bse.getRef() + 1); return shape; } + public HSSFPicture createPicture(ClientAnchor anchor, int pictureIndex) { return createPicture((HSSFClientAnchor)anchor, pictureIndex); @@ -124,7 +129,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { { HSSFPolygon shape = new HSSFPolygon(null, anchor); shape.anchor = anchor; - _shapes.add(shape); + addShape(shape); return shape; } @@ -139,7 +144,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { { HSSFTextbox shape = new HSSFTextbox(null, anchor); shape.anchor = anchor; - _shapes.add(shape); + addShape(shape); return shape; } @@ -154,7 +159,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { { HSSFComment shape = new HSSFComment(null, anchor); shape.anchor = anchor; - _shapes.add(shape); + addShape(shape); return shape; } @@ -168,7 +173,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor); shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_COMBO_BOX); shape.anchor = anchor; - _shapes.add(shape); + addShape(shape); return shape; } @@ -184,6 +189,15 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { return _shapes; } + /** + * add a shape to this drawing + */ + @Internal + public void addShape(HSSFShape shape){ + shape._patriarch = this; + _shapes.add(shape); + } + /** * Total count of all children and their children's children. */ diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java index 668acf4c79..e89579fdbd 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java @@ -21,10 +21,12 @@ import java.awt.Dimension; import java.io.ByteArrayInputStream; import org.apache.poi.ddf.EscherBSERecord; +import org.apache.poi.ddf.EscherBlipRecord; import org.apache.poi.ss.usermodel.Picture; import org.apache.poi.ss.util.ImageUtils; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.poi.hssf.model.InternalWorkbook; /** * Represents a escher picture. Eg. A GIF, JPEG etc... @@ -55,7 +57,6 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture { private static final int PX_ROW = 15; private int _pictureIndex; - HSSFPatriarch _patriarch; // TODO make private /** * Constructs a picture object. @@ -221,4 +222,15 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture { int type = bse.getBlipTypeWin32(); return ImageUtils.getImageDimension(new ByteArrayInputStream(data), type); } + + /** + * Return picture data for this shape + * + * @return picture data for this shape + */ + public HSSFPictureData getPictureData(){ + InternalWorkbook iwb = _patriarch._sheet.getWorkbook().getWorkbook(); + EscherBlipRecord blipRecord = iwb.getBSERecord(_pictureIndex).getBlipRecord(); + return new HSSFPictureData(blipRecord); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java index 62e7152fb8..3c586340fe 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java @@ -42,6 +42,7 @@ public abstract class HSSFShape { // TODO - make all these fields private final HSSFShape parent; HSSFAnchor anchor; + HSSFPatriarch _patriarch; private int _lineStyleColor = 0x08000040; int _fillColor = 0x08000009; private int _lineWidth = LINEWIDTH_DEFAULT; // 12700 = 1pt diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index 03d3374932..7a821b7886 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -1660,14 +1660,14 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { public HSSFPatriarch createDrawingPatriarch() { if(_patriarch == null){ // Create the drawing group if it doesn't already exist. - _book.createDrawingGroup(); - - _sheet.aggregateDrawingRecords(_book.getDrawingManager(), true); - EscherAggregate agg = (EscherAggregate) _sheet.findFirstRecordBySid(EscherAggregate.sid); - _patriarch = new HSSFPatriarch(this, agg); - agg.clear(); // Initially the behaviour will be to clear out any existing shapes in the sheet when - // creating a new patriarch. - agg.setPatriarch(_patriarch); + _workbook.initDrawings(); + + if(_patriarch == null){ + _sheet.aggregateDrawingRecords(_book.getDrawingManager(), true); + EscherAggregate agg = (EscherAggregate) _sheet.findFirstRecordBySid(EscherAggregate.sid); + _patriarch = new HSSFPatriarch(this, agg); + agg.setPatriarch(_patriarch); + } } return _patriarch; } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java index 0e4df40672..ee8522929d 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java @@ -52,7 +52,7 @@ public class HSSFSimpleShape int shapeType = OBJECT_TYPE_LINE; - HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor ) + public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor ) { super( parent, anchor ); } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index cb963ed33f..c0af3dda54 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -39,6 +39,7 @@ import org.apache.poi.hssf.model.HSSFFormulaParser; import org.apache.poi.hssf.model.InternalSheet; import org.apache.poi.hssf.model.InternalWorkbook; import org.apache.poi.hssf.model.RecordStream; +import org.apache.poi.hssf.model.DrawingManager2; import org.apache.poi.hssf.record.*; import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; import org.apache.poi.hssf.record.common.UnicodeString; @@ -60,6 +61,7 @@ import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; import org.apache.poi.ss.util.WorkbookUtil; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.commons.codec.digest.DigestUtils; /** @@ -542,7 +544,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss /** * Set the sheet name. * - * @param sheet number (0 based) + * @param sheetIx number (0 based) * @throws IllegalArgumentException if the name is null or invalid * or workbook already contains a sheet with this name * @see {@link #createSheet(String)} @@ -1556,6 +1558,17 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss w.flush(); } + void initDrawings(){ + DrawingManager2 mgr = workbook.findDrawingGroup(); + if(mgr != null) { + for(int i=0; i < getNumberOfSheets(); i++) { + getSheetAt(i).getDrawingPatriarch(); + } + } else { + workbook.createDrawingGroup(); + } + } + /** * Adds a picture to the workbook. * @@ -1566,7 +1579,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss */ public int addPicture(byte[] pictureData, int format) { - byte[] uid = newUID(); + initDrawings(); + + byte[] uid = DigestUtils.md5(pictureData); EscherBitmapBlip blipRecord = new EscherBitmapBlip(); blipRecord.setRecordId( (short) ( EscherBitmapBlip.RECORD_ID_START + format ) ); switch (format) @@ -1730,10 +1745,6 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss return new HSSFCreationHelper(this); } - private static byte[] newUID() { - return new byte[16]; - } - /** * * Returns the locator of user-defined functions. diff --git a/src/java/org/apache/poi/ss/usermodel/Picture.java b/src/java/org/apache/poi/ss/usermodel/Picture.java index 1959cad0ce..c79260c6ee 100644 --- a/src/java/org/apache/poi/ss/usermodel/Picture.java +++ b/src/java/org/apache/poi/ss/usermodel/Picture.java @@ -50,5 +50,12 @@ public interface Picture { void resize(double scale); ClientAnchor getPreferredSize(); + + /** + * Return picture data for this picture + * + * @return picture data for this picture + */ + PictureData getPictureData(); } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java index 9e51917a5f..6c08a167a1 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPicture.java @@ -20,6 +20,11 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.HSSFITestDataProvider; import org.apache.poi.ss.usermodel.BaseTestPicture; +import org.apache.poi.ss.usermodel.PictureData; +import org.apache.poi.ss.usermodel.Workbook; + +import java.util.Arrays; +import java.util.List; /** * Test HSSFPicture. @@ -49,4 +54,99 @@ public final class TestHSSFPicture extends BaseTestPicture { HSSFPicture pic = p1.createPicture(new HSSFClientAnchor(), idx1); pic.resize(); } + + + public void testAddPictures(){ + HSSFWorkbook wb = new HSSFWorkbook(); + + HSSFSheet sh = wb.createSheet("Pictures"); + HSSFPatriarch dr = sh.createDrawingPatriarch(); + assertEquals(0, dr.getChildren().size()); + HSSFClientAnchor anchor = wb.getCreationHelper().createClientAnchor(); + + //register a picture + byte[] data1 = new byte[]{1, 2, 3}; + int idx1 = wb.addPicture(data1, Workbook.PICTURE_TYPE_JPEG); + assertEquals(1, idx1); + HSSFPicture p1 = dr.createPicture(anchor, idx1); + assertTrue(Arrays.equals(data1, p1.getPictureData().getData())); + + // register another one + byte[] data2 = new byte[]{4, 5, 6}; + int idx2 = wb.addPicture(data2, Workbook.PICTURE_TYPE_JPEG); + assertEquals(2, idx2); + HSSFPicture p2 = dr.createPicture(anchor, idx2); + assertEquals(2, dr.getChildren().size()); + assertTrue(Arrays.equals(data2, p2.getPictureData().getData())); + + // confirm that HSSFPatriarch.getChildren() returns two picture shapes + assertTrue(Arrays.equals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData())); + assertTrue(Arrays.equals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData())); + + // write, read back and verify that our pictures are there + wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + List lst2 = wb.getAllPictures(); + assertEquals(2, lst2.size()); + assertTrue(Arrays.equals(data1, lst2.get(0).getData())); + assertTrue(Arrays.equals(data2, lst2.get(1).getData())); + + // confirm that the pictures are in the Sheet's drawing + sh = wb.getSheet("Pictures"); + dr = sh.createDrawingPatriarch(); + assertEquals(2, dr.getChildren().size()); + assertTrue(Arrays.equals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData())); + assertTrue(Arrays.equals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData())); + + // add a third picture + byte[] data3 = new byte[]{7, 8, 9}; + // picture index must increment across write-read + int idx3 = wb.addPicture(data3, Workbook.PICTURE_TYPE_JPEG); + assertEquals(3, idx3); + HSSFPicture p3 = dr.createPicture(anchor, idx3); + assertTrue(Arrays.equals(data3, p3.getPictureData().getData())); + assertEquals(3, dr.getChildren().size()); + assertTrue(Arrays.equals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData())); + assertTrue(Arrays.equals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData())); + assertTrue(Arrays.equals(data3, ((HSSFPicture)dr.getChildren().get(2)).getPictureData().getData())); + + // write and read again + wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + List lst3 = wb.getAllPictures(); + // all three should be there + assertEquals(3, lst3.size()); + assertTrue(Arrays.equals(data1, lst3.get(0).getData())); + assertTrue(Arrays.equals(data2, lst3.get(1).getData())); + assertTrue(Arrays.equals(data3, lst3.get(2).getData())); + + sh = wb.getSheet("Pictures"); + dr = sh.createDrawingPatriarch(); + assertEquals(3, dr.getChildren().size()); + + // forth picture + byte[] data4 = new byte[]{10, 11, 12}; + int idx4 = wb.addPicture(data4, Workbook.PICTURE_TYPE_JPEG); + assertEquals(4, idx4); + dr.createPicture(anchor, idx4); + assertEquals(4, dr.getChildren().size()); + assertTrue(Arrays.equals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData())); + assertTrue(Arrays.equals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData())); + assertTrue(Arrays.equals(data3, ((HSSFPicture)dr.getChildren().get(2)).getPictureData().getData())); + assertTrue(Arrays.equals(data4, ((HSSFPicture)dr.getChildren().get(3)).getPictureData().getData())); + + wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + List lst4 = wb.getAllPictures(); + assertEquals(4, lst4.size()); + assertTrue(Arrays.equals(data1, lst4.get(0).getData())); + assertTrue(Arrays.equals(data2, lst4.get(1).getData())); + assertTrue(Arrays.equals(data3, lst4.get(2).getData())); + assertTrue(Arrays.equals(data4, lst4.get(3).getData())); + sh = wb.getSheet("Pictures"); + dr = sh.createDrawingPatriarch(); + assertEquals(4, dr.getChildren().size()); + assertTrue(Arrays.equals(data1, ((HSSFPicture)dr.getChildren().get(0)).getPictureData().getData())); + assertTrue(Arrays.equals(data2, ((HSSFPicture)dr.getChildren().get(1)).getPictureData().getData())); + assertTrue(Arrays.equals(data3, ((HSSFPicture)dr.getChildren().get(2)).getPictureData().getData())); + assertTrue(Arrays.equals(data4, ((HSSFPicture)dr.getChildren().get(3)).getPictureData().getData())); + } + } -- 2.39.5