gembox-document

System.InvalidOperationException when creating Word file with Gembox


We are merging a Word template document that contains merge fields using Gembox Document. We noticed when some of the field values contain special characters \t or \n, an exception occurs...

An error occured - Text cannot contain new line (' '), carriage return (' ') or tab (' ') characters. If you want to break the text or insert a tab, insert SpecialCharacter instance with specific SpecialCharacterType to the parent's InlineCollection.

We found this post which describes a solution to the issue, but we are not seeing how to apply that to our scenario.

This is our code which throws the exception...

    public static void Merge(DocumentModel word, PricingSummaryModel model)
    {
        word.MailMerge.FieldMerging += (sender, e) =>
        {
            if (e.FieldName.Contains("CustomField."))
            {
                var trove = FindCustomFieldValueTrove(e.FieldName, model);
                var value = ProcessCustomField(e.FieldName, e.Field.GetInstructionText(), trove);

                e.Inline = new Run(e.Document, value) { CharacterFormat = e.Field.CharacterFormat.Clone() };
                e.Cancel = false;
            }
        };

        word.MailMerge.Execute(model);
    }

We can fix the problem by removing any special characters first...

enter image description here

But then we lose the special characters of course. For our scenario, how can this be done? We aren't "constructing" a document as referenced in the aforementioned post. Rather we are starting with a Word template and essentially mail merging field values for the fields.


Solution

  • You'll need to handle those special characters and add the appropriate element(s) to the e.Inlines collection.

    For example, try this:

    var value = ProcessCustomField(e.FieldName, e.Field.GetInstructionText(), trove);
    
    int startIndex = 0, currentIndex = 0, length = value.Length;
    for (; currentIndex < length; currentIndex++)
    {
        char c = value[currentIndex];
        if (c == '\t' || c == '\n')
        {
            e.Inlines.Add(
                new Run(e.Document, value.Substring(startIndex, currentIndex - startIndex))
                { CharacterFormat = e.Field.CharacterFormat.Clone() });
    
            e.Inlines.Add(
                new SpecialCharacter(e.Document, c == '\t' ? SpecialCharacterType.Tab : SpecialCharacterType.LineBreak)
                { CharacterFormat = e.Field.CharacterFormat.Clone() });
    
            startIndex = currentIndex + 1;
        }
        else if (currentIndex == length - 1)
            e.Inlines.Add(
                new Run(e.Document, value.Substring(startIndex, currentIndex - startIndex + 1))
                { CharacterFormat = e.Field.CharacterFormat.Clone() });
    }
    
    e.Cancel = false;