Page 1 of 1

A way to copy Binary part from one file to another

PostPosted: Thu Sep 25, 2008 11:18 pm
by neversaydie
Scenario:
> Say, I have a docx file named File1.docx conataining images and tables.
> And another docx file named File2.docx conataining images and tables.
> There can be n # of files.
> I try to upload File1.docx .... Filen.docx to an output file.
>
> I iterate through the body of file1 and add its objects to the output
> file body. In the case of the images, I copy the related binary parts
> over and keep track of relationship ids to match. I regenerate a new
> <w:p> object to hold the image. It works if I have only one file with images to copy from.
> For multiple files, each file will call the first image part name as
> image1, then the next as image2 and so on.
>
> To get around, I changed the org.docx4j.openpackaging.parts.Parts class.
> Kept the parts HashMap immutable, just added a getter method to get the map.
> Iterated through it and retrieved all the images in a document at run time.
> There is no way to change the PartName. So I copied the binarycontent
> retrieved from the map and put into a new Part. The code hangs into
> imagePart.setBinaryData(InputStream) method. It can not read the
> characters any more. It is possible that BufferUtil did not do it's
> job right. I am not sure. If you have any idea/suggestion, please share.

>
> Below is a snippet from what I did -
> private void copyBinaryImageParts(WordprocessingMLPackage wordMLPackage)
> throws InvalidFormatException {
>
> Parts documentParts = wordMLPackage.getParts();
> Iterator iterator = documentParts.getParts().entrySet().iterator();
> while (iterator.hasNext()) {
> Map.Entry entry = (Map.Entry) iterator.next();
> if ((entry.getKey() instanceof PartName)
> && ((PartName)
> entry.getKey()).getName().contains("/word/media/image")) {
> BinaryPart part = (BinaryPart) entry.getValue();
>
> Date dt = new Date();
> String partname = "/word/media/image" + dt.getTime() +
> ".png";
> BinaryPart imagePart = new BinaryPart(new
> PartName(partname));
>
>
> imagePart.setBinaryData(BufferUtil.newInputStream(part.getBuffer()));
> imagePart.setContentType(new
> ContentType(ContentTypes.IMAGE_PNG));
> imagePart.setRelationshipType(Namespaces.IMAGE);
> //Add to the arraylist to be used by mark up
>
> rels.add(wmlPack.getMainDocumentPart().addTargetPart(imagePart));
> }
> }
> }
>
>
>

Re: A way to copy Binary part from one file to another

PostPosted: Thu Sep 25, 2008 11:23 pm
by neversaydie
Helpful suggestion from Jason -

The code which saves a binary part into a zip file does this:

java.nio.ByteBuffer bb = ((BinaryPart)part).getBuffer();
bb.clear();
byte[] bytes = new byte[bb.capacity()];
bb.get(bytes, 0, bytes.length);
Here is a work around by Jason -

So that may be a way to copy without it hanging.

Alternatively, you could add a setPartName method to org.docx4j.openpackaging.parts.Part and then simply attach the existing part from the old document, to the new document.

Note that the latter approach is unsafe for people to use without knowing what they are doing:

1. the first document wouldn't know about the name change (but in this case you wouldn't care, because you aren't saving it) 2. it would be better to clone the Part than have a single object attached to 2 different package objects

Let me know how you go.

cheers

Jason

Re: A way to copy Binary part from one file to another

PostPosted: Thu Dec 15, 2011 10:45 pm
by nicolas
Hello Jason

I have the same problem. I would like to copy a document into another. Both have an image named image1.jpg. I tried to copy the BinaryPart with the image and the corresponding Relationship. The problem is that I can't modify the PartName. If I do so, I get a ConcurrentModificationException.

What's the best way to insert a document with an image into another document with another image?

Greeetings, Nick

Re: A way to copy Binary part from one file to another

PostPosted: Thu Aug 31, 2017 11:35 pm
by fegor
Hi!

In 2.7.1 versions, copy images using
Code: Select all
targetDoc.getMainDocumentPart().addTargetPart(sourcePart);
and work fine!, but in 3.x.x versions not work... why?

Re: A way to copy Binary part from one file to another

PostPosted: Fri Sep 01, 2017 12:53 pm
by jason
https://github.com/plutext/docx4j/blob/ ... .java#L241

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
public Relationship addTargetPart(Part targetpart) throws InvalidFormatException {
                return this.addTargetPart(targetpart, AddPartBehaviour.OVERWRITE_IF_NAME_EXISTS, null);
        }
 
Parsed in 0.014 seconds, using GeSHi 1.0.8.4


which I guess is the same as the old behaviour, but it was a long time ago and not worth checking right now...

Try org.docx4j.openpackaging.parts.relationships.RelationshipsPart.AddPartBehaviour.REUSE_EXISTING or RENAME_IF_NAME_EXISTS