Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Insert images into document with shapes #458

Open
wants to merge 7 commits into
base: trunk
Choose a base branch
from

Conversation

georgberky
Copy link

@georgberky georgberky commented Apr 20, 2023

Dear POI crew,

thank you for your work on POI. We might have found a bug that occurs when inserting images into Word documents that already contain shapes. There seems to be some kind of collision between the shapes' and the images' IDs. The problem only seems to occur after a certain amount of shapes is already present in the document.

POI seems to be able to open those documents just fine. However, when opening them in Word, we get the "do you want to recover this document" dialog.

We wrote a test that should illustrate the problem but we don't know how to fix it.

Georg Berky and others added 3 commits April 19, 2023 13:49
- given a document with 0 - 10 shapes
- inserting 0 to 10 images
- works for inserting 0 to 1 images
- fails for more than 1 image
- no matter the amount of shapes
@centic9
Copy link
Member

centic9 commented Apr 22, 2023

The duplication seems to be because of the "AlternatContent" (i.e. MSs way of not changing the spec, but still adding new types of content ...).

Can you try to add the following between opening the document and adding content? I am not 100% sure this is really the issue, so please verify that Microsoft Word can then read the document properly.

This can also be used as workaround if it is really fixing the issue.

            for (XWPFParagraph paragraph : document.getParagraphs()) {
                for (XWPFRun run : paragraph.getRuns()) {
                    XmlCursor cursor = run.getCTR().newCursor();
                    cursor.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' "
                            + "declare namespace mc='http://schemas.openxmlformats.org/markup-compatibility/2006' "
                            + "declare namespace wp='http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing' "
                            + ".//mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr");

                    while(cursor.hasNextSelection()) {
                        cursor.toNextSelection();
                        XmlObject obj = cursor.getObject();

                        CTNonVisualDrawingProps docPr = CTNonVisualDrawingProps.Factory.parse(obj.xmlText());

                        document.getDrawingIdManager().reserve(docPr.getId());
                    }
                }
            }

@centic9
Copy link
Member

centic9 commented Apr 22, 2023

@georgberky
Copy link
Author

@centic9 , thanks for replying so fast.

We're testing the workaround in our project.

Another observation: "unable to open document" in Word only seems to happen when the shape is part of the footer. Word seems to be able to handle shapes in the document body better 🤔.

- also use footer paragraphs in workaround
- still produces broken documents :(

Co-authored-by: Christina Eckleder <[email protected]>
@georgberky
Copy link
Author

Hi @centic9 , we've done some more research and are using documents with shapes in the footer now. Applying the workaround as you posted it didn't fix the documents.

We also tried to add the footer paragraphs to the list of paragraphs the workaround iterates over. That didn't help either.

We also discarded our test assertions as the docPr values alone don't seem to cause the problem for word.

@centic9
Copy link
Member

centic9 commented Apr 24, 2023

Ok, as said I am not sure if this will even make it work, but two things I see which might be off:

  • It's important to do the "workaround()" immediately after loading the document, not at the end, otherwise avoiding duplicate ids will not work
  • The current "workaround()" only looks at XPath ".//mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr", if the "docPr" is at a different location in the XML of the Paragraph/Run, another XPath/Cursor might be necessary to also find and "reserve()" those elements

Otherwise you will need to narrow down the problem as much as possible, both by making the document as simple a possible and the changes to the document as well. Unfortunately I cannot help much because I only have the online-version of Microsoft Word and this one seems to be able to load the document just fine.

Georg Berky added 3 commits April 25, 2023 10:23
- doesn't fix "cannot load document" error
@georgberky
Copy link
Author

Thanks again for helping.

I'm now running the workaround directly after loading the document. I've also changed the XPath to .//wp:docPr. The XPath worked when running "evaluate XPath" in IntelliJ on footer2.xml, but it didn't fix the broken documents.

I'll keep digging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants