You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by bu...@apache.org on 2022/03/15 15:29:09 UTC

[Bug 49765] addPictures() not displaying Image in XWPF

https://bz.apache.org/bugzilla/show_bug.cgi?id=49765

--- Comment #43 from Stefan Edelbusch <ed...@boehme-weihs.de> ---
When I use the method XWPFRun.addPicture to add images to an word document I
got an error message when opening the new document which says that there is
some not readable content in the document.
Problem is, that it comes to a conflict between drawings (w:drawing) that were
already in the word template with the new inserted images. In the XML there are
subnodes of drawing of type "wp:docPr" which have identical ID's.

I managed to workaround this conflict by testing if the id for the next drawing
to insert is already used in the list of known drawings. If so, I increment
this next id as long as it is unique so it will not be used twice in the
document.

For that I expanded the XWPFDocument class as follows.

public class ExtendedXWPFDocument extends XWPFDocument {

    public void makeUniqueNextDrawingId(List<CTDrawing> drawingsAll)
    {
        try {
            Method getDrawingIdManager =
getClass().getSuperclass().getDeclaredMethod("getDrawingIdManager", new
Class<?>[]{});
            getDrawingIdManager.setAccessible(true);
            IdentifierManager idManager = (IdentifierManager)
getDrawingIdManager.invoke(this, (Object[])null);
            if(idManager != null) {
                Field field =
idManager.getClass().getDeclaredField("segments");
                if(field != null){

                    // make private field accessible
                    field.setAccessible(true);
                    List<?> segmentsList = (List<?>)field.get(idManager);

                    Object segment =  segmentsList.get(0);
                    Field fieldStart =
segment.getClass().getDeclaredField("start");
                    fieldStart.setAccessible(true);
                    long nextID = fieldStart.getLong(segment);

                    HashMap<Long, Object> drawingsInUseMap = new HashMap<Long,
Object>();

                    for (CTDrawing drawing : drawingsAll) {

                        List<CTInline> inlineList = drawing.getInlineList();
                        for (CTInline inline : inlineList) {
                            Long inlineId = inline.getDocPr().getId();
                            drawingsInUseMap.put(inlineId, inline);
                        }
                        List<CTAnchor> anchorList = drawing.getAnchorList();
                        for (CTAnchor anchor : anchorList) {
                            Long inlineId = anchor.getDocPr().getId();
                            drawingsInUseMap.put(inlineId, anchor);
                        }
                    }

                    while (drawingsInUseMap.containsKey(nextID)) {

                        nextID = idManager.reserveNew();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}


When I insert an image I first test, if next id is unique.

List<CTDrawing> drawingsAll = getAllDrawings();
document.makeUniqueNextDrawingId(drawingsAll);

run.addPicture(inputStream, format, image.getName(), width, height);

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
For additional commands, e-mail: dev-help@poi.apache.org