Insert an unknown number of images into a Document

Hello devs,

I have a template where I need to merge an unknown number of attached images to notes. This template is the layout for notes and each note has X number of images. Currently, I am trying to put a MERGEFIELD in the template named “AttachedImages” and then my data has only one filed which is a list of strings containing file name each which; when the backend receives a request, it processes each item to download image from a storage and then create a Picture which I am trying to append to the content when merge field is inserted. This approach could be different provided it merges every image for each note.



private void MergeAttachedImages(int? tenantId, DocumentModel templateDoc, FormRequestDto formRequest)
    templateDoc.MailMerge.FieldMerging += async (sender, e) =>
        if (true || e.IsValueFound && e.Value != null)
            switch (e.FieldName) // TODO: change this swtich to if
                case "-------------AttachedImages":
                    if (true || e.Value is IEnumerable<object> objList)
                        List<ImageBlob>? imageFileNameList = formRequest.attachedImages;
                        if (imageFileNameList != null)

                            foreach (var imageFileName in imageFileNameList)
                                string templateContainer = tenantId != null ? "tenant" + tenantId.ToString()?.PadLeft(4, '0') : "defaultform";
                                byte[]? imageDataBytes = _storageService.Read(templateContainer, imageFileName.ImageBlobName);
                                if (imageDataBytes != null)
                                    MemoryStream memoryStream = new MemoryStream(imageDataBytes, true);
                                    //e.Inline = new Picture(e.Document, memoryStream);

                                    Picture picture = new Picture(e.Document, memoryStream);

                                    Layout? pictureLayout = picture.Layout;
                                    Size? pictureSize = pictureLayout?.Size;
                                    var pageSize = new Size(
                                        imageFileName.MaxWidth, //?? pictureSize.Value.Width,
                                        LengthUnit.Inch); //?? pictureSize.Value.Height);
                                    var ratioX = pageSize.Width / pictureSize.Value.Width;
                                    var ratioY = pageSize.Height / pictureSize.Value.Height;
                                    var ratio = Math.Min(ratioX, ratioY);
                                    if (ratio < 1)
                                        pictureLayout.Size = new Size(pictureSize.Value.Width * ratio, pictureSize.Value.Height * ratio);


                                    //Layout? pictureLayout = picture.Layout;
                                    //Size? pictureSize = pictureLayout?.Size;
                                    //PageSetup? pageSetup = e.Inline.Document.Sections.FirstOrDefault()?.PageSetup;
                                    //PageMargins? pageMergins = pageSetup?.PageMargins;
                                    //var pageSize = new Size(
                                    //    pageSetup.PageWidth - pageMergins.Left - pageMergins.Right,
                                    //    pageSetup.PageHeight - pageMergins.Top - pageMergins.Bottom);
                                    //var ratioX = pageSize.Width / pictureSize.Value.Width;
                                    //var ratioY = pageSize.Height / pictureSize.Value.Height;
                                    //var ratio = Math.Min(ratioX, ratioY);
                                    //if (ratio < 1)
                                    //    pictureLayout.Size = new Size(pictureSize.Value.Width * ratio, pictureSize.Value.Height * ratio);

                    //case "MyImage":
                    //    if (e.Inline is Picture image)
                    //        image.Metadata.Description = "Three dancing penguins.";
                    //    break;

Hi Noe,

Instead of that, you could use a merge range with a single picture mail merge field.
In other words, something like this:


Then you could execute the mail merge process like this:

var document = DocumentModel.Load("input.docx");

        MyImages = new[]
            new { MyImage = "image1.png" },
            new { MyImage = "image2.png" },
            new { MyImage = "image3.png" },


The result would be:


For more information, please check the Merge Pictures and Merge Ranges examples.

I hope this helps.


1 Like

Thank you, this is the kind of approach I was looking for: simpler and effictive.