Finally, I am able to copy images between Excel file (preserve size and
location), but for some Excel files it prompts data lost during open, I am
still investigating it.

My codes are not well designed, the modification to POI just only serve for
its purpose, it should have a better way to implement.

Really thanks for MSB helps.

--
Copy image function (reuse some MSB contributed codes):

       public void copyImages(HSSFSheet sourceSheet, HSSFSheet targetSheet)
       {
               List lst = sourceSheet.getWorkbook().getAllPictures();
               Hashtable<String, HSSFPicture> picTbl = new Hashtable<String,
HSSFPicture>();
               findShapeInfo(sourceSheet);
               CreationHelper helper =
targetSheet.getWorkbook().getCreationHelper();
               HSSFPatriarch drawing = null;
               try
               {
                       drawing = targetSheet.getDrawingPatriarch();
               }
               catch (Exception ex)
               {
                       logger.warn("targetSheet.getDrawingPatriarch()
failed. ", ex);
               }
               if (drawing == null)
                       drawing = targetSheet.createDrawingPatriarch();

               for (ShapeInfo shape : shapes.values())
               {
                       if (shape.getPictureFilename() == null)
                               continue;

                       HSSFPictureData picData = (HSSFPictureData)
lst.get(shape.getPicIndex());
                       shape.setPictureData(picData);

                       byte[] data = shape.getPictureData().getData();

                       HSSFClientAnchor anchor = (HSSFClientAnchor)
helper.createClientAnchor();
                       anchor.setCol1(shape.getCol1());
                       anchor.setCol2(shape.getCol2());
                       anchor.setRow1(shape.getRow1());
                       anchor.setRow2(shape.getRow2());
                       anchor.setDx1(shape.getOffsetCol1());
                       anchor.setDx2(shape.getOffsetCol2());
                       anchor.setDy1(shape.getOffsetRow1());
                       anchor.setDy2(shape.getOffsetRow2());

                       // The pictureIdx is wrong
                       int pictureIdx =
targetSheet.getWorkbook().addPicture(String.valueOf(anchor.hashCode()),
data, shape.getPictureData().getFormat());
                       HSSFPicture pic = drawing.createPicture(anchor,
pictureIdx);
                       picTbl.put(String.valueOf(anchor.hashCode()), pic);
               }

               int index = 1;
               lst = targetSheet.getWorkbook().getAllPictures();
               for (int i = 0; i < lst.size(); i++)
               {
                       index++;
                       HSSFPictureData picData = (HSSFPictureData)
lst.get(i);

                       if (picData.getCustomId() == null)
                               continue;

                       HSSFPicture pic = picTbl.get(picData.getCustomId());
                       if (pic == null)
                               continue;

                       pic.setPictureIndex(index);
               }
       }
           
                private void findShapeInfo(HSSFSheet sheet)
                {
                        try
                        {
                                EscherAggregate escherAggregate = 
sheet.getDrawingEscherAggregate();
                                if (escherAggregate != null)
                                {
                                        EscherContainerRecord escherContainer =
escherAggregate.getEscherContainer();
                                        iterateContainer(escherContainer, 1);
                                }
                        }
                        catch (Exception ex)
                        {
                                logger.error(ex, ex);
                        }
                } 
                
                private void iterateContainer(EscherContainerRecord 
escherContainer, int
level)
                {
                        if (escherContainer == null)
                                return;

                        List childRecords = escherContainer.getChildRecords();
                        Iterator listIterator = null;
                        org.apache.poi.ddf.EscherSpgrRecord sprgRecord = null;
                        org.apache.poi.ddf.EscherSpRecord spRecord = null;
                        org.apache.poi.ddf.EscherOptRecord optRecord = null;
                        org.apache.poi.ddf.EscherClientAnchorRecord anchrRecord 
= null;
                        org.apache.poi.ddf.EscherClientDataRecord dataRecord = 
null;
                        org.apache.poi.ddf.EscherDgRecord dgRecord = null;
                        Object next = null;

                        listIterator = childRecords.iterator();
                        while (listIterator.hasNext())
                        {
                                next = listIterator.next();
                                
                                // logger.debug("next: " + next);
                                
                                if (next instanceof 
org.apache.poi.ddf.EscherContainerRecord)
                                        
iterateContainer((org.apache.poi.ddf.EscherContainerRecord) next,
++level);
                                else if (next instanceof 
org.apache.poi.ddf.EscherSpgrRecord)
                                        sprgRecord = 
(org.apache.poi.ddf.EscherSpgrRecord) next;
                                else if (next instanceof 
org.apache.poi.ddf.EscherSpRecord)
                                        spRecord = 
(org.apache.poi.ddf.EscherSpRecord) next;
                                else if (next instanceof 
org.apache.poi.ddf.EscherOptRecord)
                                {
                                        optRecord = 
(org.apache.poi.ddf.EscherOptRecord) next;
                                        String key = String.valueOf(level);
                                        if (shapes.containsKey(key))
                                                
shapes.get(key).setOptRecord(optRecord);
                                        else
                                        {
                                                ShapeInfo shape = new 
ShapeInfo(level);
                                                shape.setOptRecord(optRecord);
                                                shapes.put(key, shape);
                                        }
                                }
                                else if (next instanceof 
org.apache.poi.ddf.EscherClientAnchorRecord)
                                {
                                        anchrRecord = 
(org.apache.poi.ddf.EscherClientAnchorRecord) next;
                                        String key = String.valueOf(level);
                                        if (shapes.containsKey(key))
                                                
shapes.get(key).setAnchorRecord(anchrRecord);
                                        else
                                        {
                                                ShapeInfo shape = new 
ShapeInfo(level);
                                                
shape.setAnchorRecord(anchrRecord);
                                                shapes.put(key, shape);
                                        }
                                }
                                else if (next instanceof 
org.apache.poi.ddf.EscherClientDataRecord)
                                        dataRecord = 
(org.apache.poi.ddf.EscherClientDataRecord) next;
                                else if (next instanceof 
org.apache.poi.ddf.EscherDgRecord)
                                        dgRecord = 
(org.apache.poi.ddf.EscherDgRecord) next;
                        }
                }       
--
Modification of POI source codes (add CustomId field in HSSFPictureData to
link with HSSFPicture):

Index: src/java/org/apache/poi/ddf/EscherBitmapBlip.java
===================================================================
--- src/java/org/apache/poi/ddf/EscherBitmapBlip.java   (revision 773443)
+++ src/java/org/apache/poi/ddf/EscherBitmapBlip.java   (working copy)
@@ -141,5 +141,17 @@
                "  Marker: 0x" + HexDump.toHex( field_2_marker ) + nl +
                "  Extra Data:" + nl + extraData;
    }
+
+    private String customId = null;

+       public void setCustomId(String value)
+       {
+               this.customId = value;
+       }
+
+       public String getCustomId()
+       {
+               return this.customId;
+       }
+
 }
Index: src/java/org/apache/poi/hssf/model/DrawingManager2.java
===================================================================
--- src/java/org/apache/poi/hssf/model/DrawingManager2.java     (revision
773443)
+++ src/java/org/apache/poi/hssf/model/DrawingManager2.java     (working
copy)
@@ -122,7 +122,10 @@

    EscherDgRecord getDrawingGroup(int drawingGroupId)
    {
-        return (EscherDgRecord) drawingGroups.get(drawingGroupId-1);
+       if(drawingGroupId > drawingGroups.size())
+               return (EscherDgRecord)
drawingGroups.get(drawingGroups.size() - 1);
+       else
+               return (EscherDgRecord) drawingGroups.get(drawingGroupId-1);
    }

    boolean drawingGroupExists( short dgId )
Index: src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java
===================================================================
--- src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java (revision
773443)
+++ src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java (working
copy)
@@ -100,5 +100,13 @@
                return "";
        }
    }
+
+    public String getCustomId()
+    {
+       if(blip instanceof EscherBitmapBlip)
+               return ((EscherBitmapBlip)blip).getCustomId();
+       else
+               return null;
+    }
 }

Index: src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
===================================================================
--- src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java    (revision
773443)
+++ src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java    (working
copy)
@@ -1562,7 +1562,54 @@

        return workbook.addBSERecord( r );
    }
+
+    public int addPicture(String customId, byte[] pictureData, int format)
+    {
+        byte[] uid = newUID();
+        EscherBitmapBlip blipRecord = new EscherBitmapBlip();
+        blipRecord.setRecordId( (short) ( EscherBitmapBlip.RECORD_ID_START
+ format ) );
+        switch (format)
+        {
+            case PICTURE_TYPE_EMF:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_EMF);
+                break;
+            case PICTURE_TYPE_WMF:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_WMF);
+                break;
+            case PICTURE_TYPE_PICT:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_PICT);
+                break;
+            case PICTURE_TYPE_PNG:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_PNG);
+                break;
+            case HSSFWorkbook.PICTURE_TYPE_JPEG:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_JPEG);
+                break;
+            case HSSFWorkbook.PICTURE_TYPE_DIB:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_DIB);
+                break;
+        }

+        blipRecord.setUID( uid );
+        blipRecord.setMarker( (byte) 0xFF );
+        blipRecord.setPictureData( pictureData );
+        blipRecord.setCustomId(customId);
+
+        EscherBSERecord r = new EscherBSERecord();
+        r.setRecordId( EscherBSERecord.RECORD_ID );
+        r.setOptions( (short) ( 0x0002 | ( format << 4 ) ) );
+        r.setBlipTypeMacOS( (byte) format );
+        r.setBlipTypeWin32( (byte) format );
+        r.setUid( uid );
+        r.setTag( (short) 0xFF );
+        r.setSize( pictureData.length + 25 );
+        r.setRef( 1 );
+        r.setOffset( 0 );
+        r.setBlipRecord( blipRecord );
+
+        return workbook.addBSERecord( r );
+    }
+
    /**
     * Gets all pictures from the Workbook.
     *
--

-- 
View this message in context: 
http://www.nabble.com/Copy-images-from-Workbook-to-Workbook-tp23032425p23593295.html
Sent from the POI - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to