Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files. Get free and professional technical support for Spire.Doc for .NET, Java, Android, C++, Python.

Fri Dec 10, 2021 2:42 am

Hello, I am currently trying to implement a mail merge for multiple labels within a table in Microsoft Word 2019 using Visual Studio C#. I was wondering if Spire had a function similar to the «NextRecord» in Word or would I have to manually select the table columns to insert the next record?

Code: Select all
static void Main(string[] args)
{
    Product p1 = new Product(1, "2134567", "Alfa", "Street A");
    Product p2 = new Product(2, "1237268", "Beta", "Street B");
    Product p3 = new Product(3, "9876534", "Charlie", "Street C");
    Product p4 = new Product(4, "0234106", "Delta", "Street D");
    List<Product> listProd = new List<Product>();
    listProd.Add(p1);
    listProd.Add(p2);
    listProd.Add(p3);
    listProd.Add(p4);

    Document document = new Document("template_1.docx");

    MailMergeDataTable table = new MailMergeDataTable("Products", listProd);
    document.MailMerge.ExecuteGroup(table);
}

public class Product
{
    public Product(int number, string serial, string name, string address)
    {
        this.Number = number;
        this.Serial = serial;
        this.Name = name;
        this.Address = address;
    }
    public int Number { get; set; }
    public string Serial { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
}

adrianchan
 
Posts: 13
Joined: Fri Dec 10, 2021 2:08 am

Fri Dec 10, 2021 7:44 am

Hello,

Thank you for your inquiry.
Our Spire.Doc can meet your needs, but you need to add a Next field after each «GroupEnd:Label» (such as a screenshot). I have attached sample code and input Word file for your reference.

nextField.png

Sincerely,
Annika
E-iceblue support team
User avatar

Annika.Zhou
 
Posts: 1642
Joined: Wed Apr 07, 2021 2:50 am

Tue Dec 21, 2021 8:51 am

Hello,

Hope you are doing well!
How is your issue going? Did the code we provided work for you? Any feedback will be greatly appreciated.

Sincerely,
Annika
E-iceblue support team
User avatar

Annika.Zhou
 
Posts: 1642
Joined: Wed Apr 07, 2021 2:50 am

Thu Jan 06, 2022 6:47 am

Hi Annika,

Sorry for the late reply, your code has been very helpful in our project. The next issue I currently have is adding columns and data to the datatable. Is there a generic method to add columns and rows automatically using a dictionary, since we are working with multiple document templates with different merge fields? Currently Method 1 is being used to insert data into the templates but the values of the columns and rows are essentially hard-coded. Any help would be appreciated.

Kind regards,
Adrian

Code: Select all
//Method 1
dataTable.Columns.Add(new DataColumn("reg_name1"));
dataTable.Columns.Add(new DataColumn("reg_name2"));
dataTable.Columns.Add(new DataColumn("reg_name3"));
dataTable.Columns.Add(new DataColumn("cont_tel"));
dataTable.Columns.Add(new DataColumn("address1"));
dataTable.Columns.Add(new DataColumn("address2"));
dataTable.Columns.Add(new DataColumn("address3"));
dataTable.Columns.Add(new DataColumn("address4"));

foreach (DocumentTemplate.GeneratedDocument item in generatedDocumentList)
{
    dataTable.Rows.Add(item.reg_name1, item.reg_name2, item.reg_name3, item.cont_tel, item.address1, item.address2, item.address3, item.address4);
}

//Method 2
string[] mergeFieldNames = doc.MailMerge.GetMergeFieldNames();
foreach (string item in mergeFieldNames)
{
    dataTable.Columns.Add(new DataColumn(item));
}

// Unsure how to proceed with adding rows

adrianchan
 
Posts: 13
Joined: Fri Dec 10, 2021 2:08 am

Thu Jan 06, 2022 9:22 am

Hello,

Thank you for your feedback.
Please refer to the following code to achieve your requirement. If there is any questions, please feel free to contact us.
Code: Select all
//Get the merge field name in the group name "Label"
string[] mergeFieldNames = document.MailMerge.GetMergeFieldNames("Label");

ArrayList result = new ArrayList();
//Delete duplicate merge field names
for (int i = 0; i < mergeFieldNames.Length; i++)
{
    if (!result.Contains(mergeFieldNames[i].ToString()))
        result.Add(mergeFieldNames[i].ToString());
}

ArrayList result2 = new ArrayList();
//Sort the merge field names in "result"
DocumentTemplate.GeneratedDocument item0 = generatedDocumentList[0];
foreach (PropertyInfo fi in item0.GetType().GetProperties())
{
    string items = fi.Name;
    for (int i = 0; i < result.Count;i++)
    {
        if (result[i].ToString() == items)
        {
            result2.Add(result[i].ToString());
        }
    }
}

foreach (string margeFieldName in result2)
{
    dataTable.Columns.Add(new DataColumn(margeFieldName));
}
//Add row
foreach (DocumentTemplate.GeneratedDocument item in generatedDocumentList)
{

    dataTable.Rows.Add(item.reg_name1, item.reg_name2, item.reg_name3, item.cont_tel, item.address1, item.address2, item.address3, item.address4);
}

Sincerely,
Annika
E-iceblue support team
User avatar

Annika.Zhou
 
Posts: 1642
Joined: Wed Apr 07, 2021 2:50 am

Tue Jan 11, 2022 1:56 am

Is there a method to perform mail merge using a dictionary? I am not sure about the new Dictionary("Variable A", "VariableB = %VariableB%" syntax.

(Edit: Is there a method to add data from a list of objects without hard-coding the datatable row names?)

Kind regards,
Adrian

adrianchan
 
Posts: 13
Joined: Fri Dec 10, 2021 2:08 am

Tue Jan 11, 2022 8:10 am

Hello,

Thanks for your feedback.
For mail merge, we have a DictionaryEntry method, but this method doesn't work in your case.
In addition, combined with your previous posts, using the Execute(DataTable table) method is the most suitable for your needs. If the table does not set the name of the column, the data for the corresponding column cannot be found during the mail merge. Based on the code you provided in your first post, you can use the following code to add column names.
Code: Select all
Product product = new Product();
foreach (PropertyInfo fi in product.GetType().GetProperties())
{
     dataTable.Columns. Add(new DataColumn(fi.Name));
}

Sincerely,
Annika
E-iceblue support team
User avatar

Annika.Zhou
 
Posts: 1642
Joined: Wed Apr 07, 2021 2:50 am

Return to Spire.Doc