Text Wrapping around Image during Mail Merge

Hello there,

I am inserting Images during mail merge process at run time. In some cases, I also need to apply formatting to selected Images.

Below is the code snippet in MailMerge_MergeImageField handler:

private void MailMerge_MergeImageField(object sender, MergeImageFieldEventArgs e)
{
    byte[] imageBytes = (e.FieldValue as byte[]);

    if (imageBytes != null)
    {
        if (imageFormattingDictionary.Count> 0 && imageFormattingDictionary.ContainsKey(e.FieldName))
        {
            bool isImageInserted = false;
            Image objImage = Image.FromStream(new MemoryStream((byte[]) e.FieldValue));
            // Apply Image Formatting
            Dictionary <string, string> imageFormatting = imageFormattingDictionary[e.FieldName];
            foreach(string key in imageFormatting.Keys)
            {
                switch (key)
                {
                    case "SIZE":
                        Bitmap objBitmap = null;
                        string imageSize = imageFormatting[key];
                        if (imageSize == "S")
                        {
                            objBitmap = new Bitmap(objImage, new Size(227, 171));
                        }
                        else if (imageSize == "N")
                        {
                            objBitmap = new Bitmap(objImage, new Size(353, 265));
                        }
                        objImage = objBitmap;
                        break;

                    case "ALIGN":

                        DocumentBuilder builder = new DocumentBuilder(e.Document);
                        builder.MoveToMergeField(e.FieldName);
                        Shape shape = builder.InsertImage(objImage);
                        isImageInserted = true;
                        shape.WrapType = WrapType.Square;
                        shape.BehindText = true;

                        string imageAlignment = imageFormatting[key];
                        if (imageAlignment == "RIGHT")
                        {
                            shape.HorizontalAlignment = HorizontalAlignment.Right;
                        }
                        else if (imageAlignment == "CENTER")
                        {
                            shape.HorizontalAlignment = HorizontalAlignment.Center;
                        }
                        else
                        {
                            shape.HorizontalAlignment = HorizontalAlignment.Left;
                        }
                        break;
                }
            }
            if (!isImageInserted)
            {
                e.Image = objImage;
            }

        }
        else
        {
            e.Image = Image.FromStream(new MemoryStream((byte[]) e.FieldValue));
        }
    }
    else
    {
        e.Field.Remove();
    }
}

I have two issues here:

  1. When I am iterating over imageFormatting.Keys in
foreach(string key in imageFormatting.Keys)

I want a way so that I apply all the formatting viz. SIZE and ALIGN and then finally insert image for the merge field. But, I do not know a way in case “ALIGN” where a Shape object is required to be inserted in the document before applying any wrapping style. So setting e.Image will be useless in case of ALIGN as shape is already inserted.
Please suggest if there is another work around for this that can help me to set e.Image after foreach loop.

  1. Wrapping Text around Image: I just want the text from only first paragraph following Image to be wrapped around. But in output, it just wraps maximum text that can be wrapped around image depending on image’s size. Please suggest if I can achieve this.

Source+Output docs are attached for your reference.

Thank you!

Hi Nutan,

Thanks for your inquiry.

  1. If your image is inline, you should specify paragraph alignment to make image to be centered. For instance, see the following code:
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Set paragraph alignment.
builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
// Insert inline image.
builder.InsertImage(@"Common\test.jpg");
doc.Save(@"Test001\out.doc");

If your image is not inline, you should use Shape.HorizontalAlignment property, like shown below:

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Shape image = builder.InsertImage(@"Common\test.jpg");
image.WrapType = WrapType.None;
image.HorizontalAlignment = HorizontalAlignment.Center;
doc.Save(@"Test001\out.doc");
  1. I suppose, there is no way to achieve this in MS Word as well. In the expected document you attached, you just pushed down content after the image using empty paragraphs. But in run-time you do not know how much space the image till take and how many empty paragraph you should insert.

Best regards.

Thanks you Alexey!

  1. Actually I wanted a way here to apply alignment to Image and then insert that into document.

Is it possible to do something like:

// Apply formatting to Image
Shape shape = new Shape(objImage); //just to show my requirement, I understand there is no Shape constructor that takes in Image
shape.WrapType = WrapType.Square;

shape.BehindText = true;
shape.HorizontalAlignment = HorizontalAlignment.Right;

// Insert shape after Formatting
DocumentBuilder builder = new DocumentBuilder(e.Document);
builder.MoveToMergeField(e.FieldName);
builder.Insert(shape); //just to show my requirement, I understand there is no Insert() for DocumentBuilder

Please let me know if there is a way to achieve above.

  1. Yes, you are right, I entered line breaks manually to show the expected output

Can we achieve this if we have a marker between first and second paragraph (shown as ‘WAITPHOTO’) in attached doc. If yes, any sample code would be of great help.
And if not, can you please suggest any other way round to achieve that… we can always suggest the client to modify the templates accordingly.

Thanks a lot!

Hi Nutan,

Thanks for your inquiry.

  1. I think the following code could be helpful:
// Apply formatting to Image
Shape shape = new Shape(doc, ShapeType.Image);
shape.ImageData.SetImage(objImage);
shape.Width = 100;
shape.Height = 100;
shape.WrapType = WrapType.Square;
shape.BehindText = true;
shape.HorizontalAlignment = HorizontalAlignment.Right;
// Insert shape after Formatting
builder.InsertNode(shape);
  1. Unfortunately, I cannot suggest you any way to work around the problem with text wrapping around. I think in your case it is better to use inline images.

Best regards.