-1

How can one generate docx serial letter in ASP.NET MVC application? I can fill in a simple docx template with data from DB by using docx with Content Controls and OpenXML library - as suggested for example here.

However, when trying to use this for serial letter and merge generated documents into single output docx (hint here), resulting serial letter has data of the first entry - e.g. when I was generating letter for 10 employees and feed this data, resulting output generated 10 letters but all with the data of the first employee.

Edit: (sample code added)

internal static Stream CreateMultiPartDocument(IList<object> data, string templatePath)
{
    Stream mainDocumentStream = CreateTempDocument(data[0], templatePath);            

    for(int i = 1; i < data.Count; i++)
    {
        object childDocumentData = data[i];
        Stream childDocumentStream = CreateTempDocument(childDocumentData, templatePath);

        AppendChildDocument(mainDocumentStream, childDocumentStream);
    }

    mainDocumentStream.Flush();
    mainDocumentStream.Position = 0;

    return mainDocumentStream;
}


internal static Stream CreateTempDocument(object data, string templatePath)
{
    string fullTemplatePath = Path.Combine(TEMPLATE_BASE_PATH, templatePath);
    FileStream templateFile = File.Open(fullTemplatePath, FileMode.Open);

    if(null != templateFile)
    {                
        MemoryStream fileInMemory = new MemoryStream();
        templateFile.CopyTo(fileInMemory);

        string customXML = data.SerializeToXml();

        ReplaceCustomXmlInMemory(fileInMemory, customXML);
        fileInMemory.Flush();
        fileInMemory.Position = 0;

        templateFile.Close();
        return fileInMemory;
    }

    return null;
}

private static void ReplaceCustomXmlInMemory(MemoryStream fileInMemory, string customXML)
{
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(fileInMemory, true))
    {
        MainDocumentPart mainPart = wordDoc.MainDocumentPart;
        mainPart.DeleteParts(mainPart.CustomXmlParts);
        CustomXmlPart customXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
        using (StreamWriter streamWriter = new StreamWriter(customXmlPart.GetStream()))
        {
            streamWriter.Write(customXML);
        }

        wordDoc.Close();
    }
}
Community
  • 1
  • 1
gurbi
  • 163
  • 2
  • 14
  • 1
    If you have written some code for this but you can't get it to work, then you have come to the right place: just add your code (or the relevant parts) to the question. Without that we cannot help. Please see https://stackoverflow.com/help/how-to-ask – Peter B Nov 22 '16 at 08:29

1 Answers1

0

The only solution I was able to find is to switch from OpenXml to Syncfusion's FileFormats library - they support mail merge functionality from scratch, with multiple formats of input possible. See link here. It is available also as a Nuget package, so it was super simple.

gurbi
  • 163
  • 2
  • 14