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?
- Fonti di dati per la stampa unione
- Preparazione del modello per la stampa unione
- API di stampa unione .NET - Installazione
- Esegui la stampa unione nel documento di Word usando C#
- Stampa unione utilizzando l’origine dati XML
- Formattazione personalizzata dei campi di unione
- Stampa unione con le regioni
- Regioni nidificate di stampa unione
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.
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.
- Carica il documento modello usando la classe Document.
- Imposta le opzioni di stampa unione richieste come Document.MailMerge.TrimWhitespaces.
- Eseguire una stampa unione utilizzando il metodo Document.MailMerge.Execute() e passare l’origine dati come parametro.
- Salva il documento generato usando il metodo Document.Save(String).
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
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.
Quella che segue è la pagina 1 del documento Word risultante che otteniamo dopo aver eseguito la stampa unione.
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.
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.
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.
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.