Issues Merging Images in Docx Files Using docx4j

61 Views Asked by At

I'm using docx4j to merge two Word documents, but I'm encountering an issue with images not displaying correctly. The links, styles, and general file structure are merging as expected, but the images are not appearing in the merged document. Instead, there's just a blank space where each image should be, accompanied by the message "Unable to render image." Below is the function I'm using for the merge:

  public byte[] unififyDocx(MultipartFile originalFile, String parentFilePath) {

        try {

            Document parentDoc = cmis.getFile(parentFilePath);

            WordprocessingMLPackage wordMLPackageParent = WordprocessingMLPackage.load(parentDoc.getContentStream().getStream());

            WordprocessingMLPackage wordMLPackageOriginal = WordprocessingMLPackage.load(originalFile.getInputStream());

            resolveRelationshipIdConflicts(wordMLPackageParent, wordMLPackageOriginal);

            wordMLPackageParent.getMainDocumentPart().getContent().addAll(wordMLPackageOriginal.getMainDocumentPart().getContent());

            mergeHyperlinkRelationships(wordMLPackageParent, wordMLPackageOriginal);

            mergeImagesRelationships(wordMLPackageParent, wordMLPackageOriginal);

            StyleDefinitionsPart originalStylesPart = wordMLPackageOriginal.getMainDocumentPart().getStyleDefinitionsPart();

            if (originalStylesPart != null) {
                StyleDefinitionsPart parentStylesPart = new StyleDefinitionsPart();
                parentStylesPart.setJaxbElement(originalStylesPart.getJaxbElement());
                wordMLPackageParent.getMainDocumentPart().addTargetPart(parentStylesPart);
            }

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

            wordMLPackageParent.save(byteArrayOutputStream);

            return byteArrayOutputStream.toByteArray();

        } catch (Exception ex) {
            logger.error("Exception: ", ex);
            throw new GenericErrorException(erroPadrao);
        }

    }
        public static void resolveRelationshipIdConflicts(WordprocessingMLPackage model, WordprocessingMLPackage thesis) throws Exception {
        RelationshipsPart modelRelsPart = model.getMainDocumentPart().getRelationshipsPart();
        RelationshipsPart thesisRelsPart = thesis.getMainDocumentPart().getRelationshipsPart();

        Set<String> modelIds = new HashSet<>();
        for (Relationship rel : modelRelsPart.getRelationships().getRelationship()) {
            modelIds.add(rel.getId());
        }

        Relationships thesisRelationships = thesisRelsPart.getRelationships();
        for (Relationship rel : thesisRelationships.getRelationship()) {
            if (modelIds.contains(rel.getId())) {
                String newId = generateRandomRelId(modelRelsPart, thesisRelsPart);
                updateRelationshipId(thesis, rel.getId(), newId);
                rel.setId(newId);
            }
        }
    }
    public static void mergeImagesRelationships(WordprocessingMLPackage parentPkg, WordprocessingMLPackage originalPkg) throws Exception {
        RelationshipsPart parentRelsPart = parentPkg.getMainDocumentPart().getRelationshipsPart();
        RelationshipsPart originalRelsPart = originalPkg.getMainDocumentPart().getRelationshipsPart();
        
        for (Relationship rel : originalRelsPart.getRelationships().getRelationship()) {
            if (rel.getType().equals(Namespaces.IMAGE)) {
                parentRelsPart.addRelationship(rel);
                BinaryPartAbstractImage originalImagePart = (BinaryPartAbstractImage) originalPkg.getParts().get(new PartName("/word/"+ rel.getTarget()));

                ImagePngPart newImagePart = new ImagePngPart(new PartName("/word/media/" + originalImagePart.getPartName().getName().substring(originalImagePart.getPartName().getName().lastIndexOf("/") + 1)));
                newImagePart.setBinaryData(originalImagePart.getBuffer());

                parentPkg.getParts().getParts().put(newImagePart.getPartName(), newImagePart);

                parentPkg.getMainDocumentPart().addTargetPart(newImagePart);
                parentRelsPart.addPart(newImagePart, RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS, parentPkg.getContentTypeManager());
            }
        }
    }
  private static void updateRelationshipId(WordprocessingMLPackage pkg, String oldId, String newId) throws Exception {
        String xmlContent = XmlUtils.marshaltoString(pkg.getMainDocumentPart().getJaxbElement());
        xmlContent = xmlContent.replaceAll("r:id=\"" + oldId + "\"", "r:id=\"" + newId + "\"");
        xmlContent = xmlContent.replaceAll("r:embed=\"" + oldId + "\"", "r:embed=\"" + newId + "\"");
        pkg.getMainDocumentPart().setContents((org.docx4j.wml.Document) XmlUtils.unmarshalString(xmlContent));
    }

The links, styles and the general file structure are working as expected. But the images are not being show on the document, the is just a blak space on it's place with the messa "Unable to render image"

0

There are 0 best solutions below