En este artículo, le mostraré cómo realizar la combinación de correspondencia de MS Word usando C# o VB.NET sin MS Word u Office Interop. Aspose.Words for .NET es una API de Word potente y rica en funciones que proporciona todas las funciones básicas y ampliadas de combinación de correspondencia de MS Word. Le permite generar cartas, sobres, informes, facturas y otros tipos de documentos dentro de Windows Forms, aplicaciones web ASP.NET o cualquier aplicación .NET/.NET Core.

Cubriendo las características más destacadas de nuestra API de combinación de correspondencia de .NET, este artículo se compone de las siguientes secciones:

¿Qué es Combinar correspondencia?

Mail Merge es la forma de generación automatizada de informes, cartas, sobres, facturas y otros tipos de documentos. La combinación de correspondencia en MS Word le permite crear un documento de plantilla que contiene campos de combinación y luego completar esos campos usando registros en la fuente de datos. Para entender Mail Merge, suponga que tiene que enviar una carta a diez personas diferentes y solo se deben actualizar los campos de nombre y dirección. En tal caso, simplemente cree una plantilla de la carta y luego genere dinámicamente las cartas completando los campos de combinación de nombre y dirección utilizando la fuente de datos.

Orígenes de datos para la combinación de correspondencia

Los datos para la combinación de correspondencia se pueden obtener de cualquier fuente de datos, como XML, JSON o una base de datos. En lo que respecta a Aspose.Words for .NET, puede utilizar cualquier fuente de datos compatible con ADO.NET. Los datos se pueden cargar en un DataSet, DataTable, DataView o una matriz de valores.

Preparación de la plantilla para la combinación de correspondencia

La plantilla de combinación de correspondencia es el documento que contiene los campos de combinación. Luego, estos campos se completan con los datos en la fuente de datos cuando se ejecuta la combinación de correspondencia. El documento de plantilla no necesita tener un formato de plantilla y puede ser un documento DOC/DOCX. Así es como puede preparar una plantilla para Combinar correspondencia.

  • Abra su documento o cree uno nuevo en MS Word.
  • Coloque el cursor donde desee agregar un campo de combinación.
  • En el menú Insertar, seleccione la opción Campo.
  • En la lista de nombres de campo, seleccione MergeField.
  • Ingrese un nombre para el campo de combinación en Nombre del campo y presione OK.
  • Guarde el documento.

La siguiente es la captura de pantalla del documento plantilla de muestra.

Plantilla de combinación de correspondencia

API de combinación de correspondencia de .NET - Instalación

Aspose.Words for .NET se puede descargar o instalar de las siguientes maneras:

Realice la combinación de correspondencia en un documento de Word usando C#

Una vez que tengas la plantilla lista, puedes ejecutar la combinación de correspondencia para generar los documentos. Los siguientes son los pasos para ejecutar la combinación de correspondencia en la plantilla mencionada anteriormente.

El siguiente ejemplo de código muestra cómo ejecutar MS Word Mail Merge usando una matriz de valores en C#.

// Para obtener ejemplos completos y archivos de datos, vaya a https://github.com/aspose-words/Aspose.Words-for-.NET
// La ruta al directorio de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
// Abra un documento existente.
Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc");

// Recorte los valores de combinación de correspondencia de los espacios en blanco anteriores y posteriores
doc.MailMerge.TrimWhitespaces = false;

// Rellene los campos del documento con los datos del usuario.
doc.MailMerge.Execute(
    new string[] { "FullName", "Company", "Address", "Address2", "City" },
    new object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" });

dataDir = dataDir + "MailMerge.ExecuteArray_out.doc";
// Envíe el documento en formato Word al navegador del cliente con la opción de guardarlo en el disco o abrirlo dentro del navegador actual.
doc.Save(dataDir);

Documento de Word después de combinar correspondencia

Ejecutar combinación de correspondencia en C#

Realice la combinación de correspondencia usando la fuente de datos XML en C#

Los archivos XML se usan ampliamente para guardar datos, así como para importarlos/exportarlos. Aspose.Words for .NET también es compatible con XML como fuente de datos para la combinación de correspondencia. Simplemente lea el XML en un objeto DataSet y ejecute la combinación de correspondencia. El siguiente es el archivo XML de muestra que vamos a utilizar.

<customers>
<customer Name="John Ben Jan" ID="1" Domain="History" City="Boston"/>
<customer Name="Lisa Lane" ID="2" Domain="Chemistry" City="LA"/>
<customer Name="Dagomir Zits" ID="3" Domain="Heraldry" City="Milwaukee"/>
<customer Name="Sara Careira Santy" ID="4" Domain="IT" City="Miami"/>
</customers>

El siguiente ejemplo de código obtiene los datos de un origen de datos XML y ejecuta la combinación de correspondencia mediante C#.

// Para obtener ejemplos completos y archivos de datos, vaya a https://github.com/aspose-words/Aspose.Words-for-.NET
// La ruta al directorio de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 

// Cree el conjunto de datos y lea el XML.
DataSet customersDs = new DataSet();
customersDs.ReadXml(dataDir + "Customers.xml");

string fileName = "TestFile XML.doc";
// Abra un documento de plantilla.
Document doc = new Document(dataDir + fileName);

// Ejecute la combinación de correspondencia para llenar la plantilla con datos de XML usando DataTable.
doc.MailMerge.Execute(customersDs.Tables["Customer"]);

dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
// Guarde el documento de salida.
doc.Save(dataDir);

A continuación se muestra la plantilla de combinación de correspondencia que se completará con datos XML.

Plantilla de combinación de correspondencia para XML

La siguiente es la página 1 del documento de Word resultante que obtenemos después de ejecutar la combinación de correspondencia.

Ejecutar combinación de correspondencia con XML en C#

Formato personalizado de campos de combinación

Aspose.Words for .NET le brinda más control sobre la combinación de correspondencia durante la ejecución. La propiedad MailMerge.FieldMergingCallback le permite personalizar la combinación de correspondencia cuando se encuentra cualquier campo de combinación. MailMerge.FieldMergingCallback acepta la clase que implementa los métodos IFieldMergingCallback.FieldMerging y IFieldMergingCallback.ImageFieldMerging.

El siguiente ejemplo de código muestra cómo personalizar la operación Combinar correspondencia y aplicar formato a las celdas dentro de esta plantilla.

// Para obtener ejemplos completos y archivos de datos, vaya a https://github.com/aspose-words/Aspose.Words-for-.NET
// La ruta al directorio de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");

// Agregue un controlador para el evento MergeField.
doc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows();

// Ejecutar combinación de correspondencia con regiones.
DataTable dataTable = GetSuppliersDataTable();
doc.MailMerge.ExecuteWithRegions(dataTable);
dataDir = dataDir + "MailMerge.AlternatingRows_out.doc";
doc.Save(dataDir);

La siguiente es la implementación de la clase HandleMergeFieldAlternatingRows.

// Para obtener ejemplos completos y archivos de datos, vaya a https://github.com/aspose-words/Aspose.Words-for-.NET
private class HandleMergeFieldAlternatingRows : IFieldMergingCallback
{
    ///<summary>
    /// Llamado para cada campo de combinación encontrado en el documento.
    /// Podemos devolver algunos datos al motor de combinación de correspondencia o hacer algo
    /// Else con el documento. En este caso modificamos el formato de celda.
    ///</summary>
    void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
    {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.Document);

        // De esta manera atrapamos el comienzo de una nueva fila.
        if (e.FieldName.Equals("CompanyName"))
        {
            // Seleccione el color dependiendo de si el número de fila es par o impar.
            Color rowColor;
            if (IsOdd(mRowIdx))
                rowColor = Color.FromArgb(213, 227, 235);
            else
                rowColor = Color.FromArgb(242, 242, 242);

            // No hay forma de establecer propiedades de celda para toda la fila en este momento,
            // Así que tenemos que iterar sobre todas las celdas de la fila.
            for (int colIdx = 0; colIdx < 4; colIdx++)
            {
                mBuilder.MoveToCell(0, mRowIdx, colIdx, 0);
                mBuilder.CellFormat.Shading.BackgroundPatternColor = rowColor;
            }

            mRowIdx++;
        }
    }

    void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
    {
        // Hacer nada.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}     
///<summary>
/// Devuelve verdadero si el valor es impar; false si el valor es par.
///</summary>
private static bool IsOdd(int value)
{
    // El código es un poco complejo, pero por lo demás la conversión automática a VB no funciona.
    return ((value / 2) * 2).Equals(value);
}      
///<summary>
/// Crear DataTable y llenarlo con datos.
/// En la vida real, este DataTable debe completarse desde una base de datos.
///</summary>
private static DataTable GetSuppliersDataTable()
{
    DataTable dataTable = new DataTable("Suppliers");
    dataTable.Columns.Add("CompanyName");
    dataTable.Columns.Add("ContactName");
    for (int i = 0; i < 10; i++)
    {
        DataRow datarow = dataTable.NewRow();
        dataTable.Rows.Add(datarow);
        datarow[0] = "Company " + i.ToString();
        datarow[1] = "Contact " + i.ToString();
    }
    return dataTable;
}

Combinación de correspondencia con Regiones usando C#

Puede darse el caso de que necesite rellenar y repetir una región particular en el documento de Word. Para tal caso, puede usar Combinar correspondencia con regiones. Para crear una región, debe especificar el inicio y el final de la región y luego Mail Megre repetirá esa región para cada registro en la fuente de datos. Por ejemplo, la siguiente plantilla contiene dos regiones, Orders y OrderDetails con los campos combinados «TableStart:Orders», «TableEnd:Orders» y «TableStart:OrderDetails», «TableEnd:OrderDetails» respectivamente.

Combinación de correo con regiones

El siguiente es el ejemplo de código que realiza Mail Megre en regiones para la plantilla mencionada anteriormente.

// Para obtener ejemplos completos y archivos de datos, vaya a https://github.com/aspose-words/Aspose.Words-for-.NET
// La ruta al directorio de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
string fileName = "MailMerge.ExecuteWithRegions.doc";
Document doc = new Document(dataDir + fileName);
 
// Utilice DataTable como fuente de datos.
int orderId = 10444;
DataTable orderTable = GetTestOrder(orderId);
doc.MailMerge.ExecuteWithRegions(orderTable);
 
// En lugar de usar DataTable, puede crear un DataView para ordenar o filtrar de forma personalizada y luego combinar correspondencia.
DataView orderDetailsView = new DataView(GetTestOrderDetails(orderId));
orderDetailsView.Sort = "ExtendedPrice DESC";
 
// Ejecute la operación de combinación de correspondencia.
doc.MailMerge.ExecuteWithRegions(orderDetailsView);
 
// Guarde el documento combinado.
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
doc.Save(dataDir);

Los siguientes son los métodos para leer datos de la base de datos.

// Para obtener ejemplos completos y archivos de datos, vaya a https://github.com/aspose-words/Aspose.Words-for-.NET
private static DataTable GetTestOrder(int orderId)
{
    DataTable table = ExecuteDataTable(string.Format(
        "SELECT * FROM AsposeWordOrders WHERE OrderId = {0}", orderId));
    table.TableName = "Orders";
    return table;
}
private static DataTable GetTestOrderDetails(int orderId)
{
    DataTable table = ExecuteDataTable(string.Format(
        "SELECT * FROM AsposeWordOrderDetails WHERE OrderId = {0} ORDER BY ProductID", orderId));
    table.TableName = "OrderDetails";
    return table;
}
///<summary>
/// Función de utilidad que crea una conexión, comando, 
/// Ejecuta el comando y devuelve el resultado en un DataTable.
///</summary>
private static DataTable ExecuteDataTable(string commandText)
{
    // Abra la conexión de la base de datos.
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
        RunExamples.GetDataDir_Database() + "Northwind.mdb";
    OleDbConnection conn = new OleDbConnection(connString);
    conn.Open();

    // Crear y ejecutar un comando.
    OleDbCommand cmd = new OleDbCommand(commandText, conn);
    OleDbDataAdapter da = new OleDbDataAdapter(cmd);
    DataTable table = new DataTable();
    da.Fill(table);

    // Cierra la base de datos.
    conn.Close();

    return table;
}

Regiones de combinación de correspondencia anidadas

La mayoría de las veces, los datos que tenemos en la fuente de datos vienen en forma de relaciones. Por ejemplo, la tabla “Pedido” tendrá una relación de uno a varios con “Detalles del pedido” que mantendrá registros de los artículos en un pedido. Para manejar tales relaciones padre-hijo, se utiliza la combinación de correspondencia anidada. La siguiente es una muestra de plantilla de factura que se adapta bien a este escenario.

Plantilla de combinación de correspondencia con regiones

La siguiente es la fuente de datos XML de muestra que usaremos para la combinación de correspondencia anidada.

<?xml version="1.0" encoding="utf-8"?>
<Orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="OrdersSchema.xsd">
  <Order>
    <Number>23</Number>
    <Address>Nelson Street</Address>
    <Suburb>Howick</Suburb>
    <City>Auckland</City>
    <Phonenumber>543 1234</Phonenumber>
    <Date>03/01/2010</Date>
    <Total>14.00</Total>
    <Item>
      <Name>BBQ Chicken Pizza</Name>
      <Price>6.00</Price>
      <Quantity>1</Quantity>
      <ItemTotal>6.00</ItemTotal>
    </Item>
    <Item>
      <Name>1.5 Litre Coke</Name>
      <Price>4.00</Price>
      <Quantity>2</Quantity>
      <ItemTotal>8.00</ItemTotal>
    </Item>
  </Order>
  <Order>
    <Number>10</Number>
    <Address>Parkville Avenue</Address>
    <Suburb>Pakuranga</Suburb>
    <City>Auckland</City>
    <Phonenumber>548 7342</Phonenumber>
    <Date>05/03/2010</Date>
    <Total>6.00</Total>
    <Item>
      <Name>Hawaiian Pizza</Name>
      <Price>4.00</Price>
      <Quantity>1</Quantity>
      <ItemTotal>4.00</ItemTotal>
    </Item>
    <Item>
      <Name>Fries</Name>
      <Price>1.00</Price>
      <Quantity>2</Quantity>
      <ItemTotal>2.00</ItemTotal>
    </Item>
  </Order>
</Orders>

Mientras que OrderSchema.xsd para este XML es:

<?xml version="1.0" encoding ="utf-8"?>
<xs:schema id="OrdersSchema"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element name="Orders">
 <xs:complexType>
 <xs:sequence>
  <xs:element name="Order">
  <xs:complexType>
  <xs:sequence>
  <xs:element name="Number"/>
  <xs:element name="Address"/>
  <xs:element name="Suburb"/>
  <xs:element name="City"/>
  <xs:element name="Phonenumber">
  <xs:element name="Date"/>
  <xs:element name="Total"/>
  <xs:element name="Item">
   <xs:complexType>
   <xs:sequence>
   <xs:element name="Name"/>
   <xs:element name="Price"/>
   <xs:element name="Quantity"/>
   <xs:element name="ItemTotal"/>
   </xs:sequence>
  </xs:complexType>
  </xs:element>
  </xs:sequence>
  </xs:complexType>
 </xs:element>
 </xs:sequence>
 </xs:complexType>
 </xs:element>
</xs:schema>

El siguiente ejemplo de código se usa para ejecutar la combinación de correspondencia anidada usando C#.

// Para obtener ejemplos completos y archivos de datos, vaya a https://github.com/aspose-words/Aspose.Words-for-.NET
// La ruta al directorio de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
	 
// Cree el conjunto de datos y lea el XML.
DataSet pizzaDs = new DataSet();
	 
// Datatable.TableNames y DataSet.Relations están definidos implícitamente por .NET a través de ReadXml.
pizzaDs.ReadXml(dataDir + "CustomerData.xml");
string fileName = "Invoice Template.doc";

// Abra el documento de plantilla.
Document doc = new Document(dataDir + fileName);
	 
// Recorte los valores de combinación de correspondencia de los espacios en blanco anteriores y posteriores.
doc.MailMerge.TrimWhitespaces = false;
	 
// Ejecute la combinación de correspondencia anidada con regiones.
doc.MailMerge.ExecuteWithRegions(pizzaDs);
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);

// Guarde la salida en un archivo.
doc.Save(dataDir);

Debug.Assert(doc.MailMerge.GetFieldNames().Length == 0, "There was a problem with mail merge");
Console.WriteLine("\nMail merge performed with nested data successfully.\nFile saved at " + dataDir);

Documento de Word después de combinar correspondencia

A continuación se muestra la primera página del documento de Word resultante después de ejecutar la combinación de correspondencia.

Documento de Word después de combinar correspondencia

Conclusión

Aspose.Words for .NET es una API de combinación de correspondencia rica en características que proporciona todas las características estándar y extendidas de combinación de correspondencia para aplicaciones .NET. Con unas pocas líneas de código, puede crear informes simples o complejos a partir de varios tipos de fuentes de datos sin problemas. Puede obtener más información sobre la API de combinación de correspondencia de .NET en la documentación. Para obtener más información sobre Aspose.Words for .NET, comience con las guías para desarrolladores y los ejemplos de código GitHub.

Pruebe Aspose.Words for .NET gratis

Puede obtener una licencia temporal gratuita para probar Aspose.Words for .NET sin limitaciones. Obtenga su licencia temporal ahora.

Ver también