You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@poi.apache.org by matthewxb <ma...@gmail.com> on 2009/05/18 10:35:50 UTC

Re: Copy images from Workbook to Workbook

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: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: Copy images from Workbook to Workbook

Posted by TimShiu <ti...@ssc-ltd.com>.
Thanks for all the efforts on this issue and I have another little problem.

According to MSB's coding, the picture information like filename & the cell
location can be extracted.
My question is can we get back the byte[] of those pictures accordingly?
e.g. I want to get the image with its top left corner cell is at (0, 0)

I discovered that matthewxb can do it successfully by using
shape.getPicIndex() function to get the pictureData with the index. But I
don't know when and where the picIndex is set to the shape object.

Can anybody give me a hint on this problem? Thanks.
-- 
View this message in context: http://www.nabble.com/Copy-images-from-Workbook-to-Workbook-tp23032425p24303124.html
Sent from the POI - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org