Free Support Forum - aspose.com

Mail Merge & Carriage Return in word

Hi,

In order to prevent the blank lines from appearing in the Envelope address, I am using Merge Fields conditionally as displayed in the attached Template.

(Press Alt+F9 and Carriage return toolbar to see the hidden parts)

When I do a mail merge with Word usign sample values, I see it working correctly.

When I mail merge with Aspose, I am finding that Aspose is adding additional carriage return as can be seen in the Envelope_Result.doc.

Please let me know your thoughts.

Thanks!

Hi Sudheer,

Thanks for your request. As I can see after executing mail merge the output document looks as expected. I suppose the problem occurs after unlinking fields on your side. I suppose as a simple solution, you can remove empty paragraphs after unlinking or during unlinking fields.

Best regards,

Hi Alexy,

Removing paragraphs might work for this template.

Some other templates may have intentional empty paragraphs and I fear whether I will be removing them bcose I run this method (Unlink()) after every template is merged.

Can you please provide a sample to remove empty paragraphs?

Thanks!

Hi

Thanks for your request. Do you use code from here to replace fields with static text?

http://www.aspose.com/documentation/.net-components/aspose.words-for-.net/howto-replace-fields-with-static-text.html

if so, you should make the following modifications:

[Test]

public void Test001()

{

Document doc = new Document(@"Test001\Envelope_Template.doc");

string[] names = new string[] { "CaseNumber", "Recipient", "RecipientAddress1", "RecipientAddress2", "RecipientAddress3", "RecipientCity", "RecipientState", "RecipientZipCode" };

doc.MailMerge.Execute(names, names);

// Remove empty run nodes.

Node[] runs = doc.GetChildNodes(NodeType.Run, true).ToArray();

foreach (Run run in runs)

{

if(string.IsNullOrEmpty(run.Text))

run.Remove();

}

ConvertFieldsToStaticText(doc, FieldType.FieldIf);

doc.Save(@"Test001\out.doc");

}

///

/// Converts any fields of a specified type into static text.

///

/// The node in which all descendants of the specified FieldType will be converted to static text.

/// The FieldType of the field to convert to static text.

public static void ConvertFieldsToStaticText(CompositeNode compositeNode, FieldType targetFieldType)

{

// Define a list to store the field starts which match the specified field type.

ArrayList fieldStarts = new ArrayList();

// Iterate through all FieldStart nodes in the document and index the ones matching the field type.

foreach (FieldStart start in compositeNode.GetChildNodes(NodeType.FieldStart, true))

{

if (start.FieldType.Equals(targetFieldType))

fieldStarts.Add(start);

}

// Reverse the order of field starts found in the document so that nested fields are converted

// properly.

fieldStarts.Reverse();

// Keep a record of the nodes visited that should be removed so they can be removed

// after enumeration.

ArrayList nodes = new ArrayList();

// Iterate through all fields of targetFieldType in the document.

foreach (FieldStart start in fieldStarts)

{

// Pointer to the current node within the field.

Node currentNode = start;

// Stores the FieldSeparator node of the field. This is null until it is found.

// A field that has not been updated can have no field separator. In this case no action is taken.

Node fieldSeparator = null;

// Remove all nodes between the FieldStart and FieldSeparator. Stop removing as well if we find a FieldEnd of the same target field type.

while (!((currentNode.NodeType == NodeType.FieldSeparator || currentNode.NodeType == NodeType.FieldEnd) && ((FieldChar)currentNode).FieldType.Equals(targetFieldType)))

{

// Add the nodes from the field codes to a list to removed after all nodes have been processed.

if (!nodes.Contains(currentNode))

nodes.Add(currentNode);

// Find the next node in the document. We use the NextPreOrder method so even if the field spans over

// multiple paragraphs the nodes can still be enumerated properly.

currentNode = currentNode.NextPreOrder(compositeNode);

}

// The currentNode will either be a FieldSeparator node or FieldEnd node depending on the presense of the FieldSeparator or not.

if (currentNode.NodeType == NodeType.FieldSeparator)

{

// Search forward to find the FieldEnd node while leaving the field result intact.

fieldSeparator = currentNode;

bool isSkipping = true;

while (isSkipping)

{

currentNode = currentNode.NextPreOrder(compositeNode);

if (currentNode.NodeType == NodeType.FieldEnd)

{

if (((FieldEnd)currentNode).FieldType.Equals(targetFieldType))

isSkipping = false;

}

}

// Remove the FieldSeparator.

if (!nodes.Contains(fieldSeparator))

nodes.Add(fieldSeparator);

}

// Finally remove the FieldEnd node.

if (!nodes.Contains(currentNode))

nodes.Add(currentNode);

foreach (Node node in nodes)

{

// Store the parent of the node we are about to remove.

// If the parent node has become empty while removing other nodes then remove it as well.

CompositeNode parentNode = node.ParentNode;

// Only remove inline level nodes here.

if (node.ParentNode != null && !node.IsComposite)

{

node.Remove();

if (!parentNode.HasChildNodes)

parentNode.Remove();

}

}

}

foreach (Node node in nodes)

{

// Handle any composite nodes here. Only remove them

// if they have become empty.

if (node.ParentNode != null && node.IsComposite)

{

if (node.NodeType == NodeType.Paragraph)

{

// If the paragraph has become empty then remove it.

if (!((CompositeNode)node).HasChildNodes)

node.Remove();

}

else if (node.NodeType == NodeType.Table)

{

// A table can be empty but still have child nodes (Empty cells) therefore we

// use ToTxt to quickly test whether it is empty or not.

string nodeTextTrimmed = node.ToTxt().Trim();

if (string.IsNullOrEmpty(nodeTextTrimmed))

node.Remove();

}

}

}

}

Hope this helps.

Best regards,