Questo post spiega come eseguire operazioni di stampa unione in documenti MS Word utilizzando Java. Entro la fine di questo articolo, imparerai come creare modelli di stampa unione ed eseguire la stampa unione a livello di codice.

Informazioni sulla stampa unione

Mail Merge è un modo conveniente per generare in modo dinamico lettere, buste, fatture, rapporti e altri tipi di documenti. Usando Stampa unione, crei un file modello contenente i campi di unione e poi popola quei campi usando i dati in un’origine dati. Supponiamo di dover inviare una lettera a 20 persone diverse e di cambiare solo il nome e l’indirizzo dei destinatari su ogni copia. In questo caso, puoi creare un modello di stampa unione per la lettera e quindi generare 20 lettere popolando dinamicamente i campi del nome e dell’indirizzo.

API Java Mail Merge - Download gratuito

Aspose.Words for Java è una nota API di elaborazione testi che ti consente di creare vari tipi di documenti da zero. L’API fornisce funzionalità integrate di stampa unione che consentono di generare documenti dinamicamente utilizzando modelli e origini dati. Aspose.Words per Java può essere scaricato come JAR o installato all’interno delle applicazioni basate su 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>

Fonti di dati per la stampa unione

I dati nella stampa unione possono essere recuperati da qualsiasi origine dati come JSON, XML, foglio di calcolo o un database.

Crea un modello per la stampa unione in MS Word

Il modello utilizzato in Mail Merge può essere un semplice documento Word (cioè DOCX) e non è necessario che sia in un formato modello. Il documento modello contiene i campi di unione che vengono popolati con i dati quando viene eseguita la stampa unione. Di seguito sono riportati i passaggi su come preparare un modello di stampa unione utilizzando MS Word.

  • Crea un nuovo documento in MS Word.
  • Posiziona il cursore nel punto in cui desideri aggiungere un campo di unione.
  • Dal menu Inserisci selezionare l’opzione Campo.
  • Dall’elenco Nomi campo, selezionare MergeField.
  • Immettere un nome per il campo di unione nel Nome campo e premere OK.
  • Salva il documento come DOCX.

Quello che segue è lo screenshot del documento modello di esempio.

modello di parola stampa unione

Crea un modello di stampa unione utilizzando Java

Puoi anche generare il modello Stampa unione a livello di codice. Di seguito sono riportati i passaggi per esso.

L’esempio di codice seguente mostra come creare un modello di stampa unione utilizzando Java.

// Crea generatore di documenti
DocumentBuilder builder = new DocumentBuilder();

// Inserire un campo di inserimento testo il nome univoco di questo campo è "Ciao", gli altri parametri definiscono
// che tipo di FormField è, il formato del testo, il risultato del campo e la lunghezza massima del testo (0 = nessun limite)
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);

// Inserisci un'interruzione di paragrafo nel documento
builder.insertParagraph();

// Inserisci il corpo della posta
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();

// Inserisci la fine della mail
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");

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

Eseguire la stampa unione nel documento di Word utilizzando Java

Una volta che il modello è pronto, puoi popolare i campi di unione con i dati. Di seguito sono riportati i passaggi per eseguire la stampa unione su un modello di Word.

L’esempio di codice seguente mostra come eseguire la stampa unione nei documenti di Word utilizzando Java.

// Includi il codice per il nostro modello
Document doc = new Document();

// Passa il documento al generatore di documenti
DocumentBuilder builder = new DocumentBuilder(doc);

// Crea campi di unione
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");

// Salva il modello
builder.getDocument().save("MailMerge.TestTemplate.docx");

// Compila i campi del documento con i dati dell'utente
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
		new Object[] { "John Doe", "Hawaiian", "2" });

// Salva il documento 
builder.getDocument().save("MailMerge.Simple.docx");

Modello

semplice stampa unione in java

Produzione

semplice stampa unione

Eseguire la stampa unione utilizzando l’origine dati XML

Nell’esempio precedente, abbiamo eseguito la stampa unione utilizzando gli oggetti Java. Tuttavia, nella maggior parte dei casi, viene utilizzata un’origine dati per popolare i campi di unione. A scopo dimostrativo, diamo un’occhiata a come utilizzare un’origine dati XML in Mail Merge. Di seguito sono riportati i passaggi per questo.

  • Caricare l’origine dati XML utilizzando la classe DataSet.
  • Carica il modello di stampa unione usando la classe Document.
  • Utilizzare la funzione di esecuzione per popolare i campi di unione utilizzando la tabella di dati desiderata nell’origine dati.
  • Salva il documento Word generato usando il metodo Document.save(String).

Di seguito è riportata l’origine dati XML utilizzata in questo esempio.

<?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> 

Nell’esempio di codice seguente viene illustrato come popolare il modello Stampa unione utilizzando la tabella dati cliente nell’origine dati XML fornita.

// Crea il set di dati e leggi l'XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// Apri un documento modello
Document doc = new Document("TestFile XML.docx");

// Eseguire la stampa unione per riempire il modello con i dati da XML utilizzando DataTable.
// Si noti che questa classe funziona anche con una singola regione ripetibile (e qualsiasi regione nidificata).
// Per unire più aree contemporaneamente da un'unica origine dati XML, utilizzare la classe XmlMailMergeDataSet.
// es. doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));

// Salva il documento di output
doc.save("generated-document.docx");

Modello

stampa unione con XML

Produzione

stampa unione xml

Stampa unione con le regioni in Java

In alcuni casi, potrebbe essere necessario ripetere una determinata regione nel documento. Ad esempio, si desidera visualizzare gli ordini effettuati da ciascun cliente in una tabella separata. In questi casi, puoi sfruttare le regioni di stampa unione. Per creare una regione, puoi specificare l’inizio e la fine della regione. Di conseguenza, la regione verrà ripetuta per ogni istanza dei dati durante l’esecuzione della stampa unione.

La schermata seguente mostra un modello in cui la regione è costituita da una tabella. Inizia con «TableStart:Customers» e termina con «TableEnd:Customers».

modello regione stampa unione

L’esempio di codice seguente mostra come creare un modello con le aree e popolarlo con i dati.

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

// Il punto di partenza della stampa unione con le regioni del set di dati.
builder.insertField(" MERGEFIELD TableStart:Customers");
// I dati dalle righe della colonna "Nome cliente" della tabella "Clienti" andranno
// in questo MERGEFIELD.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");

// Crea intestazioni di colonna
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();

// Abbiamo una seconda tabella di dati chiamata "Ordini", che ha molti-a-uno
// rapporto con i "Clienti"
// prelevare righe con lo stesso valore 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();

// Il punto finale della stampa unione con le regioni.
builder.insertField(" MERGEFIELD TableEnd:Customers");

// Passa il nostro set di dati per eseguire la stampa unione con le regioni.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);

// Salva il risultato
doc.save("MailMerge.ExecuteWithRegions.docx");

Produzione

regione di stampa unione

Crea regioni nidificate di unione di posta utilizzando Java

Un altro scenario popolare in Mail Merge è quando hai regioni nidificate. Ad esempio, quando devi elencare gli ordini e gli articoli in ciascun ordine, puoi utilizzare le regioni nidificate. L’immagine seguente rende l’immagine più chiara sulle regioni nidificate.

Nell’immagine sopra, abbiamo la tabella Ordini e la tabella Articoli in cui ogni record in Articoli è collegato a un record in Ordini. Quindi, esiste una relazione uno-a-molti tra queste due tabelle. In questi casi, Aspose.Words esegue il Mail Merge curando le relazioni definite nel DataSet. Ad esempio, se disponiamo di un’origine dati XML, Aspose.Words utilizzerà le informazioni sullo schema o la struttura di XML per scoprire le relazioni. Pertanto, non dovrai gestirlo manualmente da solo e il metodo Document.getMailMerge().executeWithRegions(DataSet) funzionerà per te (come nell’esempio precedente).

Applica la formattazione personalizzata ai campi di unione

Per darti un maggiore controllo sulla stampa unione, Aspose.Words per Java ti consente di personalizzare i campi di unione durante l’esecuzione della stampa unione. Il metodo setFieldMergingCallback(IFieldMergingCallback) accetta una classe che implementa i metodi fieldMerging(FieldMergingArgs) e imageFieldMerging(ImageFieldMergingArgs) per il controllo personalizzato sul processo di stampa unione. L’evento fieldMerging(FieldMergingArgs) si verifica quando viene rilevato un campo di unione durante l’esecuzione della stampa unione.

Di seguito è riportato l’esempio di codice completo su come personalizzare l’operazione di stampa unione e applicare la formattazione alle celle.

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");

        // Aggiungi un gestore per l'evento MergeField.
        doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());

        // Eseguire la stampa unione con le regioni.
        DataTable dataTable = getSuppliersDataTable();
        doc.getMailMerge().executeWithRegions(dataTable);

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

    /**
     * Restituisce vero se il valore è dispari; false se il valore è pari.
     */
    public static boolean isOdd(int value) throws Exception {
        return (value % 2 != 0);
    }

    /**
     * Crea DataTable e riempilo di dati. Nella vita reale questo DataTable
     * dovrebbe essere compilato da un database.
     */
    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 metodo di supporto che crea un ResultSet disconnesso Java vuoto con
     * le colonne specificate.
     */
    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 metodo di supporto che aggiunge una nuova riga con i valori specificati a a
     * ResultSet disconnesso.
     */
    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();

        // Questa "danza" è necessaria per aggiungere correttamente le righe alla fine del set di risultati.
        // Se faccio qualcos'altro, le righe vengono aggiunte nella parte anteriore o nel risultato
        // set genera un'eccezione su una riga eliminata durante la stampa unione.
        resultSet.moveToCurrentRow();
        resultSet.last();
    }
}

class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
    /**
     * Chiamato per ogni campo di unione incontrato nel documento. Possiamo anche noi
     * restituire alcuni dati al motore di stampa unione o fare qualcos'altro con il
     * documento. In questo caso modifichiamo la formattazione della cella.
     */
    public void fieldMerging(FieldMergingArgs e) throws Exception {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.getDocument());

        // In questo modo catturiamo l'inizio di una nuova riga.
        if (e.getFieldName().equals("CompanyName")) {
            // Seleziona il colore a seconda che il numero di riga sia pari o dispari.
            Color rowColor;
            if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
                rowColor = new Color(213, 227, 235);
            else
                rowColor = new Color(242, 242, 242);

            // Al momento non è possibile impostare le proprietà della cella per l'intera riga,
            // quindi dobbiamo scorrere tutte le celle nella riga.
            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 {
        // Fare niente.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

Conclusione

Mail Merge ti offre un’ampia gamma di funzionalità per generare documenti MS Word in modo dinamico. È possibile generare report semplici e complessi basati sui dati nei database o in altre origini dati. In questo articolo, hai visto come implementare le funzionalità di stampa unione a livello di codice utilizzando Java. Puoi saperne di più sull’API Java Mail Merge utilizzando la documentazione.

Guarda anche