Free Support Forum - aspose.com

Error merge image

Hello,

I am trying to make a poc based on Aspose.Words for Java and I’m having a problem when try to merge an image.


My word document looks like this:


Titre : { MERGEFIELD TITRE \* MERGEFORMAT }

Image : { MERGEFIELD \d "Image:IMAGETEST" \* MERGEFORMATINET}


My service :


public DocumentDto mergeDocument(String template, Map data) {

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(template);

DocumentDto docx = new DocumentDto();

try {

Document document = new Document(is);

document.getMailMerge().setFieldMergingCallback(new HandleMergeImageField());

String[] fields = document.getMailMerge().getFieldNames();

Object[] values = new Object[fields.length];

IntStream.range(0, fields.length).forEach(i -> values[i] = data.get(fields[i]));

document.getMailMerge().execute(fields, values);

ByteArrayOutputStream dstStream = new ByteArrayOutputStream();

document.save(dstStream, SaveFormat.DOCX);

docx.setDocument(dstStream.toByteArray());

} catch (Exception e) {

logger.warning(() -> MessageFormat.format("Error : {0}", e.getMessage()));

}

return docx;

}

private class HandleMergeImageField implements IFieldMergingCallback {

public void fieldMerging(FieldMergingArgs args) throws Exception {

// Do nothing.

}

/**

* This is called when mail merge engine encounters Image:XXX merge field in the document. You have a chance to return an Image object, file

* name or a stream that contains the image.

*/

public void imageFieldMerging(ImageFieldMergingArgs e) throws Exception {

if (e.getFieldValue() == null) {

e.setImageStream(new ByteArrayInputStream(new byte[] {}));

} else {

ByteArrayInputStream imageStream = new ByteArrayInputStream((byte[]) e.getFieldValue());

e.setImageStream(imageStream);

}

}

}


My Junit test :


@Test

public void testMergeDocument() {

Map data = new HashMap();

data.put("TITRE", "TITRE_DOC");

data.put("Image:IMAGETEST", "C:\\project\\avatar.jpeg");

DocumentDto docx = service.mergeDocument("com/poc/template.docx", data);

Assert.assertNotNull("document Not null", docx);

Assert.assertNotNull("document Byte Not null", docx.getDocument());

}


My problem is located on HandleMergeImageField. imageFieldMerging, the e.getFieldValue() is null event if arrays passed to getMailMerge().execute contains the value of the field.


I trought also to pass byte[] of the image but I had the same problem.


Thanks for your help;

Hi,


Thanks for your inquiry. Please see attached simplified template and following code:
Document doc = new Document(getMyDir() + “input.docx”);
doc.getMailMerge().setFieldMergingCallback(new HandleImageMergeField());
doc.getMailMerge().execute(
new String[] { “MyImageField” },
new Object[] { ImageIO.read(new File(getMyDir() + “aspose.words.jpg”)) });
doc.save(getMyDir() + “15.7.0.docx”);

private static class HandleImageMergeField  implements IFieldMergingCallback {
public void fieldMerging(FieldMergingArgs args) throws Exception {
// Do nothing.
}
<font color="RED"><b>public</b></font> <font color="RED"><b>void</b></font> imageFieldMerging<font color="BLUE"><b>(</b></font>ImageFieldMergingArgs e<font color="BLUE"><b>)</b></font> <font color="RED"><b>throws</b></font> Exception <font color="BLUE"><b>{</b></font>
    ByteArrayOutputStream os <font color="BLUE">=</font> <font color="RED"><b>new</b></font> ByteArrayOutputStream<font color="BLUE"><b>(</b></font><font color="BLUE"><b>)</b></font><font color="BLUE"><b>;</b></font>
    ImageIO<font color="BLUE"><b>.</b></font>write<font color="BLUE"><b>(</b></font><font color="BLUE"><b>(</b></font>BufferedImage<font color="BLUE"><b>)</b></font> e<font color="BLUE"><b>.</b></font>getFieldValue<font color="BLUE"><b>(</b></font><font color="BLUE"><b>)</b></font><font color="BLUE"><b>,</b></font> <font color="PURPLE">"jpg"</font><font color="BLUE"><b>,</b></font> os<font color="BLUE"><b>)</b></font><font color="BLUE"><b>;</b></font>
    InputStream is <font color="BLUE">=</font> <font color="RED"><b>new</b></font> ByteArrayInputStream<font color="BLUE"><b>(</b></font>os<font color="BLUE"><b>.</b></font>toByteArray<font color="BLUE"><b>(</b></font><font color="BLUE"><b>)</b></font><font color="BLUE"><b>)</b></font><font color="BLUE"><b>;</b></font>
    e<font color="BLUE"><b>.</b></font>setImageStream<font color="BLUE"><b>(</b></font>is<font color="BLUE"><b>)</b></font><font color="BLUE"><b>;</b></font>
<font color="BLUE"><b>}</b></font>

}

I hope, this helps in fixing your own issue. You can fix your template document and code accordingly.

Best regards,

Hello,

Thanks for your Help.
My service will be used by other services, so I will get the image as byte[] and not a BufferedImage.
Best regards,
Hi,

I just tested your code with your template. but I'm still getting e.getFieldValue () = null event if the parameter ImageFieldMergingArgs is a BufferedImage non null ([BufferedImage@44a2b17b: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_ColorSpace@7a56812e transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 200 height = 200 #numDataElements 3 dataOff[0] = 2])

Thanks for your Help.

Hi,


Finally i found the cause of the error.

As my service uses String[] fields = document.getMailMerge().getFieldNames();
fields contains “Image:MyImageField” and not MyImageField” and the array for fields also contains “Image:MyImageField”.

The question will be now : how can get fileds without prefix?

Thanks.



Hi,


Thanks for your inquiry. You can use the following code to remove “Image:” prefix from merge fields:
Document doc = new Document(getMyDir() + “input.docx”);
for(String field : doc.getMailMerge().getFieldNames()){
if (field.startsWith(“Image:”))
field = field.replace(“Image:”, “”);
System.out.println(field);
}
I hope, this helps.

Best regards,

Hello,

That’s what I want avoid.
Thanks for all :slight_smile: