Hi Martin,
Let's check. You can print IDs of existing pictures on sheet B:
for(HSSFShape shape : sheetB.getDrawingPatriarch().getChildren()){
if(shape instanceof HSSFPicture){
HSSFPicture pic = (HSSFPicture)shape;
System.out.println("pictureId: " + pic.getPictureIndex());
}
}
I guess the index of the picture that you are adding to sheet A
collides with an existing ID from sheet B.
Each picture in HSSF is represented by a EscherBSERecord and
pictureIndex is a 0-based index of the corresponding EscherBSERecord
in the workbook stream.
I traced it down to InternalWorkbook.addBSERecord(EscherBSERecord e).
This method returns pictureIndex and it looks like it always starts
with 0, no matter if there are already pictures in the workbook.
The first line in addBSERecord is:
createDrawingGroup();
and this is what we can improve. This method always re-creates the
whole workbook-level drawing stuff while it should work in 'append'
mode if there are drawings objects.
Yegor
On Wed, Jul 6, 2011 at 3:48 PM, Martin Studer
<[email protected]> wrote:
> Hi Yegor,
>
> thank you very much for your explanation. I modified the following section
> in the code:
>
> Drawing drawing = null;
> if(isHSSF()) {
> drawing = ((HSSFSheet)sheet).getDrawingPatriarch();
> if(drawing == null) {
> drawing = sheet.createDrawingPatriarch();
> }
> } else if(isXSSF()) {
> drawing = ((XSSFSheet)sheet).createDrawingPatriarch();
> } else {
> drawing = sheet.createDrawingPatriarch();
> }
>
>
> I have two worksheets in my workbook, let's call them sheet A and B. There
> is an existing image on sheet B and
> I'm trying to add an image on sheet A. Using the above mentioned
> modification, I'm still getting the same behavior.
> Well, sheet A doesn't have a drawing patriarch, so one is created. For some
> reason, however, no picture will be added - but again the picture on the
> second sheet is replaced. I guess this is because something with the
> workbook-level picture index is wrong? Does createDrawingPatriarch modify
> something on the workbook level (probably even delete picture data)?
>
> Regards,
> Martin
>
>
> -----Ursprüngliche Nachricht-----
> Von: Yegor Kozlov [mailto:[email protected]]
> Gesendet: Mittwoch, 6. Juli 2011 12:54
> An: POI Users List
> Betreff: Re: Question about HSSFSheet drawing patriarch
>
> what happens when you re-create a drawing patriarch is not
> deterministic. According to the documentation,
> HSSFSheet.createDrawingPatriarch is supposed to wipe out any existing
> drawings on the sheet. It *may* work for simple shapes, but evidently
> fails for Pictures. I think it is because pictures are stores both in
> workbook and sheet levels. Very schematically it can be described as
> follows:
>
> Workbook
> [workbook-global drawing stuff] // image blob lives here
>
> Sheet1
> [sheet1 drawings] // image properties (anchor, etc.) live here. The
> shape refers to the blob in the workbook-global drawing
>
> Sheet2
> [sheet2 drawings]
> ....
>
> HSSFSheet.createDrawingPatriarch invalidates everything on the sheet,
> but does not clean its references in the workbook. This leads to the
> *strange* behavior that you described.
>
> I don't know how to bypass this limitation with the current drawing
> support in HSSF. I will be happy to improve it to support modifying
> existing drawings but it is not easy and will take quite a lot of time
> and technical efforts.
>
> My recommendation is not to recreate drawings.
>
>
> Yegor
>
> On Wed, Jul 6, 2011 at 11:05 AM, Martin Studer
> <[email protected]> wrote:
>> Dear POI Users/Developers,
>>
>> I've got a question on the HSSFSheet drawing patriarch. In the
> documentation
>> of HSSFSheet.createDrawingPatriarch it says: "Creates the top-level
> drawing
>> patriarch. This will have the effect of removing any existing drawings on
>> this sheet. This may then be used to add graphics or charts."
>>
>> So given that I have a workbook that already contains images, I would
> expect
>> any existing images to be removed. However, the effect that I get when
>> calling HSSFSheet.createDrawingPatriarch (and later Drawing.createPicture)
>> is that the previous images will just be replaced with the new image -
> they
>> are not removed. Also, the image does not appear at the new location
>> (anchor) that I've set.
>>
>> Here is an excerpt of the code:
>>
>> InputStream is = new FileInputStream(imageFile);
>>
>> byte[] bytes = IOUtils.toByteArray(is);
>>
>> int imageIndex = workbook.addPicture(bytes, imageType);
>>
>> is.close();
>>
>> Drawing drawing = sheet.createDrawingPatriarch();
>>
>> CreationHelper helper = workbook.getCreationHelper();
>>
>> ClientAnchor anchor = helper.createClientAnchor();
>>
>> anchor.setRow1(topLeft.getRow());
>>
>> anchor.setCol1(topLeft.getCol());
>>
>> anchor.setRow2(bottomRight.getRow() + 1);
>>
>> anchor.setCol2(bottomRight.getCol() + 1);
>>
>> anchor.setAnchorType(ClientAnchor.DONT_MOVE_AND_RESIZE);
>>
>> Picture picture = drawing.createPicture(anchor, imageIndex);
>>
>>
>>
>> I guess I must be doing something wrong? I'm using POI 3.8-beta3.
>>
>>
>>
>> Any help is very much appreciated.
>>
>>
>>
>>
>>
>> Thank you and best regards,
>>
>> Martin
>>
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]