Esta publicación cubre cómo realizar operaciones de combinación de correspondencia en documentos de MS Word utilizando Java. Al final de este artículo, aprenderá cómo crear plantillas de combinación de correspondencia y ejecutar la combinación de correspondencia mediante programación.

Acerca de la combinación de correspondencia

Combinar correspondencia es una forma conveniente de generar cartas, sobres, facturas, informes y otros tipos de documentos de forma dinámica. Con Combinar correspondencia, crea un archivo de plantilla que contiene los campos de combinación y luego completa esos campos usando los datos en una fuente de datos. Supongamos que tiene que enviar una carta a 20 personas diferentes y solo necesita cambiar el nombre y la dirección de los destinatarios en cada copia. En este caso, puede crear una plantilla de combinación de correspondencia para la carta y luego generar 20 cartas llenando los campos de nombre y dirección dinámicamente.

API de combinación de correspondencia de Java - Descarga gratuita

Aspose.Words for Java es una conocida API de procesamiento de texto que le permite crear varios tipos de documentos desde cero. La API proporciona funciones integradas de combinación de correspondencia que le permiten generar documentos de forma dinámica utilizando plantillas y fuentes de datos. Aspose.Words for Java puede descargarse como JAR o instalarse dentro de las aplicaciones basadas en Maven.

<repository>
    <id>AsposeJavaAPI</id>
    <name>Aspose Java API</name>
    <url>https://repository.aspose.com/repo/</url>
</repository>
<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-words</artifactId>
    <version>20.11</version>
    <classifier>jdk17</classifier>
</dependency>

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

Los datos de la combinación de correspondencia se pueden obtener de cualquier fuente de datos, como JSON, XML, una hoja de cálculo o una base de datos.

Crear plantilla para combinar correspondencia en MS Word

La plantilla que se utiliza en Combinar correspondencia puede ser un documento de Word simple (es decir, DOCX) y no es necesario que tenga un formato de plantilla. El documento de plantilla contiene los campos de combinación que se completan con datos cuando se ejecuta la combinación de correspondencia. Los siguientes son los pasos para preparar una plantilla de combinación de correspondencia usando MS Word.

  • Cree un nuevo documento 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 como DOCX.

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

plantilla de word de combinación de correspondencia

Crear plantilla de combinación de correo usando Java

También puede generar la plantilla de combinación de correspondencia mediante programación. Los siguientes son los pasos para ello.

El siguiente ejemplo de código muestra cómo crear una plantilla de combinación de correspondencia usando Java.

// Crear generador de documentos
DocumentBuilder builder = new DocumentBuilder();

// Inserte un campo de entrada de texto, el nombre único de este campo es "Hola", los otros parámetros definen
// qué tipo de FormField es, el formato del texto, el resultado del campo y la longitud máxima del texto (0 = sin límite)
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0);
builder.insertField("MERGEFIELD CustomerFirstName \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0);
builder.insertField("MERGEFIELD CustomerLastName \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " , ", 0);

// Insertar un salto de párrafo en el documento
builder.insertParagraph();

// Insertar cuerpo de correo
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Thanks for purchasing our ", 0);
builder.insertField("MERGEFIELD ProductName \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", please download your Invoice at ",
	0);
builder.insertField("MERGEFIELD InvoiceURL \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "",
	". If you have any questions please call ", 0);
builder.insertField("MERGEFIELD Supportphone \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", or email us at ", 0);
builder.insertField("MERGEFIELD SupportEmail \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ".", 0);

builder.insertParagraph();

// Insertar final de correo
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Best regards,", 0);
builder.insertBreak(BreakType.LINE_BREAK);
builder.insertField("MERGEFIELD EmployeeFullname \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0);
builder.insertField("MERGEFIELD EmployeeDepartment \\* MERGEFORMAT");

// Guardar documento
builder.getDocument().save("document.docx");

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

Una vez que la plantilla esté lista, puede completar los campos de combinación con datos. Los siguientes son los pasos para realizar la combinación de correspondencia en una plantilla de Word.

El siguiente ejemplo de código muestra cómo realizar la combinación de correspondencia en documentos de Word usando Java.

// Incluir el código de nuestra plantilla
Document doc = new Document();

// Pasar el documento al generador de documentos
DocumentBuilder builder = new DocumentBuilder(doc);

// Crear campos de combinación
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");

// Guardar la plantilla
builder.getDocument().save("MailMerge.TestTemplate.docx");

// Rellena los campos del documento con los datos del usuario
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
		new Object[] { "John Doe", "Hawaiian", "2" });

// Guardar el documento 
builder.getDocument().save("MailMerge.Simple.docx");

Modelo

combinación de correspondencia simple en java

Producción

combinación de correo simple

Realizar la combinación de correspondencia usando la fuente de datos XML

En el ejemplo anterior, realizamos la combinación de correspondencia usando los objetos de Java. Sin embargo, en la mayoría de los casos, se utiliza una fuente de datos para completar los campos de combinación. Para una demostración, veamos cómo usar una fuente de datos XML en Mail Merge. Los siguientes son los pasos para ello.

  • Cargue la fuente de datos XML utilizando la clase DataSet.
  • Cargue la plantilla de combinación de correspondencia usando la clase Document.
  • Utilice la función de ejecución para completar los campos de combinación utilizando la tabla de datos deseada en la fuente de datos.
  • Guarde el documento de Word generado utilizando el método Document.save(String).

El siguiente es el origen de datos XML que se utiliza en este ejemplo.

<?xml version="1.0" encoding="utf-8"?>
<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 muestra cómo completar la plantilla de combinación de correspondencia mediante la tabla de datos del cliente en el origen de datos XML proporcionado.

// Crear el conjunto de datos y leer el XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// Abrir un documento de plantilla
Document doc = new Document("TestFile XML.docx");

// Ejecute la combinación de correspondencia para llenar la plantilla con datos de XML usando DataTable.
// Tenga en cuenta que esta clase también funciona con una sola región repetible (y cualquier región anidada).
// Para combinar varias regiones al mismo tiempo desde una sola fuente de datos XML, use la clase XmlMailMergeDataSet.
// por ejemplo, doc.getMailMerge().executeWithRegions(nuevo XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));

// Guardar el documento de salida
doc.save("generated-document.docx");

Modelo

combinación de correspondencia con XML

Producción

combinación de correspondencia xml

Combinar correspondencia con Regiones en Java

En ciertos casos, es posible que deba repetir una región en particular en el documento. Por ejemplo, desea mostrar los pedidos realizados por cada cliente en una tabla separada. En tales casos, puede aprovechar las regiones de combinación de correspondencia. Para crear una región, puede especificar el inicio y el final de la región. Como resultado, la región se repetirá para cada instancia de los datos durante la ejecución de la combinación de correspondencia.

La siguiente captura de pantalla muestra una plantilla en la que la región consta de una tabla. Comienza con «TableStart:Customers» y termina en «TableEnd:Customers».

plantilla de región de combinación de correspondencia

El siguiente ejemplo de código muestra cómo crear una plantilla con regiones y llenarla con los datos.

// Crear documento
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// El punto de inicio de la combinación de correspondencia con las regiones del conjunto de datos.
builder.insertField(" MERGEFIELD TableStart:Customers");
// Los datos de las filas de la columna "CustomerName" de la tabla "Customers" irán
// en este MERGEFIELD.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");

// Crear encabezados de columna
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();

// Tenemos una segunda tabla de datos llamada "Órdenes", que tiene una relación muchos a uno.
// relación con "Clientes"
// recogiendo filas con el mismo valor de CustomerID.
builder.insertCell();
builder.insertField(" MERGEFIELD TableStart:Orders");
builder.insertField(" MERGEFIELD ItemName");
builder.insertCell();
builder.insertField(" MERGEFIELD Quantity");
builder.insertField(" MERGEFIELD TableEnd:Orders");
builder.endTable();

// El punto final de la combinación de correspondencia con las regiones.
builder.insertField(" MERGEFIELD TableEnd:Customers");

// Pase nuestro conjunto de datos para realizar la combinación de correspondencia con las regiones.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);

// Guardar el resultado
doc.save("MailMerge.ExecuteWithRegions.docx");

Producción

región de combinación de correspondencia

Cree regiones de combinación de correo anidado usando Java

Otro escenario popular en Mail Merge es cuando tiene regiones anidadas. Por ejemplo, cuando tiene que enumerar los pedidos y los artículos en cada pedido, puede usar las regiones anidadas. La siguiente imagen hace que la imagen sea más clara acerca de las regiones anidadas.

En la imagen de arriba, tenemos la tabla Pedidos y la tabla Artículos donde cada registro en Artículos está vinculado a un registro en Pedidos. Por lo tanto, existe una relación de uno a muchos entre estas dos tablas. En tales casos, Aspose.Words ejecuta la combinación de correspondencia cuidando las relaciones definidas en el conjunto de datos. Por ejemplo, si tenemos una fuente de datos XML, Aspose.Words utilizará la información del esquema o la estructura de XML para averiguar las relaciones. Por lo tanto, no tendrá que manejarlo manualmente y el método Document.getMailMerge().executeWithRegions(DataSet) funcionará para usted (como en el ejemplo anterior).

Aplicar formato personalizado en campos de combinación

Para darle más control sobre la combinación de correspondencia, Aspose.Words for Java le permite personalizar los campos de combinación durante la ejecución de la combinación de correspondencia. El método setFieldMergingCallback(IFieldMergingCallback) acepta una clase que implementa los métodos fieldMerging(FieldMergingArgs) e imageFieldMerging(ImageFieldMergingArgs) para el control personalizado del proceso de combinación de correspondencia. El evento fieldMerging(FieldMergingArgs) ocurre cuando se encuentra un campo de combinación durante la ejecución de la combinación de correspondencia.

El siguiente es el ejemplo de código completo de cómo personalizar la operación Combinar correspondencia y aplicar formato a las celdas.

public class ApplyCustomFormattingDuringMailMerge {

    private static final String dataDir = Utils.getSharedDataDir(ApplyCustomFormattingDuringMailMerge.class) + "MailMerge/";

    public static void main(String[] args) throws Exception {
        Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");

        // Agregue un controlador para el evento MergeField.
        doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());

        // Ejecutar combinación de correspondencia con regiones.
        DataTable dataTable = getSuppliersDataTable();
        doc.getMailMerge().executeWithRegions(dataTable);

        doc.save(dataDir + "MailMerge.AlternatingRows Out.doc");
    }

    /**
     * Devuelve verdadero si el valor es impar; false si el valor es par.
     */
    public static boolean isOdd(int value) throws Exception {
        return (value % 2 != 0);
    }

    /**
     * Cree DataTable y llénelo con datos. En la vida real, este DataTable
     * debe ser llenado desde una base de datos.
     */
    private static DataTable getSuppliersDataTable() throws Exception {
        java.sql.ResultSet resultSet = createCachedRowSet(new String[]{"CompanyName", "ContactName"});

        for (int i = 0; i < 10; i++)
            addRow(resultSet, new String[]{"Company " + Integer.toString(i), "Contact " + Integer.toString(i)});

        return new DataTable(resultSet, "Suppliers");
    }

    /**
     * Un método auxiliar que crea un ResultSet desconectado de Java vacío con
     * las columnas especificadas.
     */
    private static ResultSet createCachedRowSet(String[] columnNames) throws Exception {
        RowSetMetaDataImpl metaData = new RowSetMetaDataImpl();
        metaData.setColumnCount(columnNames.length);
        for (int i = 0; i < columnNames.length; i++) {
            metaData.setColumnName(i + 1, columnNames[i]);
            metaData.setColumnType(i + 1, java.sql.Types.VARCHAR);
        }

        CachedRowSet rowSet = RowSetProvider.newFactory().createCachedRowSet();
        ;
        rowSet.setMetaData(metaData);

        return rowSet;
    }

    /**
     * Un método auxiliar que agrega una nueva fila con los valores especificados a un
     * Conjunto de resultados desconectado.
     */
    private static void addRow(ResultSet resultSet, String[] values) throws Exception {
        resultSet.moveToInsertRow();

        for (int i = 0; i < values.length; i++)
            resultSet.updateString(i + 1, values[i]);

        resultSet.insertRow();

        // Este "baile" es necesario para agregar filas al final del conjunto de resultados correctamente.
        // Si hago algo más, las filas se agregan al frente o el resultado
        // set lanza una excepción sobre una fila eliminada durante la combinación de correspondencia.
        resultSet.moveToCurrentRow();
        resultSet.last();
    }
}

class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
    /**
     * Llamado para cada campo de combinación encontrado en el documento. podemos
     * devolver algunos datos al motor de combinación de correspondencia o hacer otra cosa con el
     * documento. En este caso modificamos el formato de celda.
     */
    public void fieldMerging(FieldMergingArgs e) throws Exception {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.getDocument());

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

            // No hay forma de establecer propiedades de celda para toda la fila en este momento,
            // entonces tenemos que iterar sobre todas las celdas de la fila.
            for (int colIdx = 0; colIdx < 4; colIdx++) {
                mBuilder.moveToCell(0, mRowIdx, colIdx, 0);
                mBuilder.getCellFormat().getShading().setBackgroundPatternColor(rowColor);
            }

            mRowIdx++;
        }
    }

    public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception {
        // Hacer nada.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

Conclusión

Mail Merge le ofrece una amplia gama de funciones para generar documentos de MS Word de forma dinámica. Puede generar informes simples y complejos basados en los datos de las bases de datos u otras fuentes de datos. En este artículo, ha visto cómo implementar las funciones de combinación de correspondencia mediante programación utilizando Java. Puede obtener más información sobre la API de combinación de correspondencia de Java utilizando la documentación.

Ver también