In questo articolo, ti mostrerò come eseguire MS Word Mail Merge usando C# o VB.NET senza MS Word o Office Interop. Aspose.Words for .NET è un’API di Word ricca di funzionalità e potente che fornisce tutte le funzionalità di stampa unione di MS Word di base ed estese. Consente di generare lettere, buste, report, fatture e altri tipi di documenti all’interno di Windows Form, applicazioni Web ASP.NET o qualsiasi applicazione .NET/.NET Core.

Coprendo le caratteristiche salienti della nostra API .NET Mail Merge, questo articolo è composto dalle seguenti sezioni:

Cos’è la stampa unione?

Mail Merge è il modo per la generazione automatizzata di rapporti, lettere, buste, fatture e altri tipi di documenti. La stampa unione in MS Word consente di creare un documento modello contenente campi di unione e quindi popolare quei campi utilizzando i record nell’origine dati. Per capire Mail Merge, supponiamo di dover inviare una lettera a dieci persone diverse e solo il nome e i campi dell’indirizzo devono essere aggiornati. In tal caso, è sufficiente creare un modello della lettera e quindi generare dinamicamente le lettere compilando i campi di unione nome e indirizzo utilizzando l’origine dati.

Fonti di dati per la stampa unione

I dati per la stampa unione possono essere recuperati da qualsiasi origine dati come XML, JSON o un database. Per quanto riguarda Aspose.Words per .NET, è possibile utilizzare qualsiasi origine dati supportata da ADO.NET. I dati possono essere caricati in un DataSet, DataTable, DataView o in una matrice di valori.

Preparazione del modello per la stampa unione

Il modello Stampa unione è il documento che contiene i campi di unione. Questi campi vengono quindi compilati con i dati nell’origine dati quando viene eseguita la stampa unione. Il documento modello non deve necessariamente essere un formato modello e può essere un documento DOC/DOCX. Ecco come puoi preparare un modello per la stampa unione.

  • Apri il tuo documento o creane uno nuovo 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 in Nome campo e premere OK.
  • Salva il documento.

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

Modello di stampa unione

API di stampa unione .NET - Installazione

Aspose.Words per .NET può essere scaricato o installato nei seguenti modi:

Esegui la stampa unione nel documento di Word usando C#

Una volta che hai il modello pronto, puoi eseguire la Stampa unione per generare i documenti. Di seguito sono riportati i passaggi per eseguire la stampa unione sul modello sopra menzionato.

Nell’esempio di codice seguente viene illustrato come eseguire Stampa unione di MS Word usando una matrice di valori in C#.

// Per esempi completi e file di dati, visitare https://github.com/aspose-words/Aspose.Words-for-.NET
// Il percorso della directory dei documenti.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
// Apri un documento esistente.
Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc");

// Taglia i valori di stampa unione degli spazi bianchi finali e iniziali
doc.MailMerge.TrimWhitespaces = false;

// Compila i campi del documento con i dati dell'utente.
doc.MailMerge.Execute(
    new string[] { "FullName", "Company", "Address", "Address2", "City" },
    new object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" });

dataDir = dataDir + "MailMerge.ExecuteArray_out.doc";
// Invia il documento in formato Word al browser client con l'opzione di salvare su disco o aprire all'interno del browser corrente.
doc.Save(dataDir);

Documento Word dopo la stampa unione

Esegui stampa unione in C#

Eseguire la stampa unione utilizzando l’origine dati XML in C#

I file XML sono ampiamente utilizzati per conservare e importare/esportare dati. Aspose.Words per .NET supporta anche XML come origine dati per la stampa unione. Basta leggere l’XML in un oggetto DataSet ed eseguire la stampa unione. Quello che segue è il file XML di esempio che useremo.

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

L’esempio di codice seguente recupera i dati da un’origine dati XML ed esegue la stampa unione usando C#.

// Per esempi completi e file di dati, visitare https://github.com/aspose-words/Aspose.Words-for-.NET
// Il percorso della directory dei documenti.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 

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

string fileName = "TestFile XML.doc";
// Apri un documento modello.
Document doc = new Document(dataDir + fileName);

// Eseguire la stampa unione per riempire il modello con i dati da XML utilizzando DataTable.
doc.MailMerge.Execute(customersDs.Tables["Customer"]);

dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
// Salva il documento di output.
doc.Save(dataDir);

Di seguito è riportato il template di Mail Merge che verrà popolato con dati XML.

Modello di stampa unione per XML

Quella che segue è la pagina 1 del documento Word risultante che otteniamo dopo aver eseguito la stampa unione.

Esegui stampa unione con XML in C#

Formattazione personalizzata dei campi di unione

Aspose.Words per .NET ti offre un maggiore controllo sulla stampa unione durante l’esecuzione. La proprietà MailMerge.FieldMergingCallback consente di personalizzare la stampa unione quando viene rilevato un campo di unione. MailMerge.FieldMergingCallback accetta la classe che implementa i metodi IFieldMergingCallback.FieldMerging e IFieldMergingCallback.ImageFieldMerging.

L’esempio di codice seguente mostra come personalizzare l’operazione di stampa unione e applicare la formattazione alle celle all’interno di questo modello.

// Per esempi completi e file di dati, visitare https://github.com/aspose-words/Aspose.Words-for-.NET
// Il percorso della directory dei documenti.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");

// Aggiungi un gestore per l'evento MergeField.
doc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows();

// Eseguire la stampa unione con le regioni.
DataTable dataTable = GetSuppliersDataTable();
doc.MailMerge.ExecuteWithRegions(dataTable);
dataDir = dataDir + "MailMerge.AlternatingRows_out.doc";
doc.Save(dataDir);

Di seguito è l’implementazione della classe HandleMergeFieldAlternatingRows.

// Per esempi completi e file di dati, visitare https://github.com/aspose-words/Aspose.Words-for-.NET
private class HandleMergeFieldAlternatingRows : IFieldMergingCallback
{
    ///<summary>
    /// Chiamato per ogni campo di unione incontrato nel documento.
    /// Possiamo restituire alcuni dati al motore di stampa unione o fare qualcosa
    /// Altro con il documento. In questo caso modifichiamo la formattazione della cella.
    ///</summary>
    void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
    {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.Document);

        // In questo modo catturiamo l'inizio di una nuova riga.
        if (e.FieldName.Equals("CompanyName"))
        {
            // Seleziona il colore a seconda che il numero di riga sia pari o dispari.
            Color rowColor;
            if (IsOdd(mRowIdx))
                rowColor = Color.FromArgb(213, 227, 235);
            else
                rowColor = Color.FromArgb(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.CellFormat.Shading.BackgroundPatternColor = rowColor;
            }

            mRowIdx++;
        }
    }

    void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
    {
        // Fare niente.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}     
///<summary>
/// Restituisce vero se il valore è dispari; false se il valore è pari.
///</summary>
private static bool IsOdd(int value)
{
    // Il codice è un po' complesso, ma per il resto la conversione automatica in VB non funziona.
    return ((value / 2) * 2).Equals(value);
}      
///<summary>
/// Crea DataTable e riempila di dati.
/// Nella vita reale questo DataTable dovrebbe essere compilato da un database.
///</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;
}

Stampa unione con regioni utilizzando C#

Potrebbe verificarsi il caso in cui è necessario popolare e ripetere una determinata regione nel documento di Word. In tal caso, puoi utilizzare la stampa unione con le regioni. Per creare una regione è necessario specificare l’inizio e la fine della regione e quindi Mail Megre ripeterà quella regione per ogni record nell’origine dati. Ad esempio, il seguente modello contiene due regioni, Orders e OrderDetails con i campi di unione «TableStart:Orders», «TableEnd:Orders» e «TableStart:OrderDetails», «TableEnd:OrderDetails» rispettivamente.

Stampa unione con le regioni

Di seguito è riportato l’esempio di codice che esegue Mail Megre nelle regioni per il modello menzionato sopra.

// Per esempi completi e file di dati, visitare https://github.com/aspose-words/Aspose.Words-for-.NET
// Il percorso della directory dei documenti.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
string fileName = "MailMerge.ExecuteWithRegions.doc";
Document doc = new Document(dataDir + fileName);
 
// Usa DataTable come origine dati.
int orderId = 10444;
DataTable orderTable = GetTestOrder(orderId);
doc.MailMerge.ExecuteWithRegions(orderTable);
 
// Invece di utilizzare DataTable, puoi creare un DataView per l'ordinamento o il filtro personalizzato e quindi la stampa unione.
DataView orderDetailsView = new DataView(GetTestOrderDetails(orderId));
orderDetailsView.Sort = "ExtendedPrice DESC";
 
// Eseguire l'operazione di stampa unione.
doc.MailMerge.ExecuteWithRegions(orderDetailsView);
 
// Salva il documento unito.
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
doc.Save(dataDir);

Di seguito sono riportati i metodi per leggere i dati dal database.

// Per esempi completi e file di dati, visitare 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>
/// Funzione di utilità che crea una connessione, un comando, 
/// Esegue il comando e restituisce il risultato in una DataTable.
///</summary>
private static DataTable ExecuteDataTable(string commandText)
{
    // Aprire la connessione al database.
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
        RunExamples.GetDataDir_Database() + "Northwind.mdb";
    OleDbConnection conn = new OleDbConnection(connString);
    conn.Open();

    // Crea ed esegui un comando.
    OleDbCommand cmd = new OleDbCommand(commandText, conn);
    OleDbDataAdapter da = new OleDbDataAdapter(cmd);
    DataTable table = new DataTable();
    da.Fill(table);

    // Chiudere il database.
    conn.Close();

    return table;
}

Regioni nidificate di stampa unione

Molto spesso, i dati che abbiamo nell’origine dati si presentano sotto forma di relazioni. Ad esempio, la tabella “Order” avrà una relazione uno-a-molti con “OrderDetails” che manterrà i record degli articoli in un ordine. Per gestire tali relazioni padre-figlio, viene utilizzata la stampa unione nidificata. Quello che segue è un esempio di modello di fattura che si adatta bene a questo scenario.

Modello di stampa unione con le regioni

Quella che segue è l’origine dati XML di esempio che useremo per la stampa unione nidificata.

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

Considerando che OrderSchema.xsd per questo XML è:

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

L’esempio di codice seguente viene usato per eseguire la stampa unione nidificata usando C#.

// Per esempi completi e file di dati, visitare https://github.com/aspose-words/Aspose.Words-for-.NET
// Il percorso della directory dei documenti.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
	 
// Crea il set di dati e leggi l'XML.
DataSet pizzaDs = new DataSet();
	 
// Datatable.TableNames e DataSet.Relations sono definiti in modo implicito da .NET tramite ReadXml.
pizzaDs.ReadXml(dataDir + "CustomerData.xml");
string fileName = "Invoice Template.doc";

// Apri il documento modello.
Document doc = new Document(dataDir + fileName);
	 
// Taglia i valori di stampa unione degli spazi bianchi finali e iniziali.
doc.MailMerge.TrimWhitespaces = false;
	 
// Esegui la stampa unione nidificata con le regioni.
doc.MailMerge.ExecuteWithRegions(pizzaDs);
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);

// Salva l'output su file.
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 Word dopo la stampa unione

Di seguito è riportata la prima pagina del documento Word risultante dopo l’esecuzione della stampa unione.

Documento Word dopo la stampa unione

Conclusione

Aspose.Words per .NET è un’API Mail Merge ricca di funzionalità che fornisce tutte le funzionalità di Mail Merge standard ed estese per le applicazioni .NET. In poche righe di codice, puoi creare report semplici o complessi da vari tipi di origini dati senza problemi. Puoi leggere di più sull’API .NET Mail Merge dalla documentazione. Per informazioni su Aspose.Words per .NET, inizia con gli esempi di codice guide per sviluppatori e GitHub.

Prova Aspose.Words per .NET gratuitamente

Puoi ottenere una licenza temporanea gratuita per provare Aspose.Words per .NET senza alcuna limitazione. Ottieni la tua licenza temporanea ora.

Guarda anche