W tym artykule pokażę, jak przeprowadzić korespondencję seryjną MS Word przy użyciu C# lub VB.NET bez MS Word lub Office Interop. Aspose.Words for .NET to bogaty w funkcje i potężny interfejs API programu Word, który zapewnia wszystkie podstawowe i rozszerzone funkcje korespondencji seryjnej MS Word. Pozwala generować listy, koperty, raporty, faktury i inne typy dokumentów w Windows Forms, aplikacjach internetowych ASP.NET lub dowolnej aplikacji .NET/.NET Core.

Omawiając najważniejsze funkcje naszego interfejsu API korespondencji seryjnej platformy .NET, ten artykuł składa się z następujących sekcji:

Co to jest korespondencja seryjna?

Mail Merge to sposób automatycznego generowania raportów, listów, kopert, faktur i innych typów dokumentów. Korespondencja seryjna w MS Word umożliwia utworzenie szablonu dokumentu zawierającego pola korespondencji seryjnej, a następnie wypełnienie tych pól przy użyciu rekordów w źródle danych. Aby zrozumieć funkcję korespondencji seryjnej, załóżmy, że musisz wysłać list do dziesięciu różnych osób i zaktualizować tylko pola nazwiska i adresu. W takim przypadku po prostu utwórz szablon pisma, a następnie dynamicznie wygeneruj pisma, wypełniając pola scalania nazwy i adresu za pomocą źródła danych.

Źródła danych dla korespondencji seryjnej

Dane do korespondencji seryjnej można pobrać z dowolnego źródła danych, takiego jak XML, JSON lub baza danych. Jeśli chodzi o Aspose.Words for .NET, możesz użyć dowolnego źródła danych, które jest obsługiwane przez ADO.NET. Dane można załadować do DataSet, DataTable, DataView lub tablicy wartości.

Przygotowanie szablonu do korespondencji seryjnej

Szablon korespondencji seryjnej to dokument zawierający pola korespondencji seryjnej. Pola te są następnie wypełniane danymi ze źródła danych podczas wykonywania korespondencji seryjnej. Dokument szablonu nie musi być formatem szablonu i może to być dokument DOC/DOCX. W ten sposób możesz przygotować szablon do korespondencji seryjnej.

  • Otwórz dokument lub utwórz nowy w MS Word.
  • Umieść kursor w miejscu, w którym chcesz dodać pole scalania.
  • Z menu Wstaw wybierz opcję Pole.
  • Z listy Nazwy pól wybierz opcję MergeField.
  • Wprowadź nazwę pola scalania w polu Nazwa pola i naciśnij OK.
  • Zapisz dokument.

Poniżej znajduje się zrzut ekranu dokumentu przykładowy szablon.

Szablon korespondencji seryjnej

Interfejs API korespondencji seryjnej platformy .NET — instalacja

Aspose.Words for .NET można pobrać lub zainstalować w następujący sposób:

Wykonaj korespondencję seryjną w dokumencie programu Word przy użyciu języka C#

Po przygotowaniu szablonu możesz wykonać korespondencję seryjną, aby wygenerować dokumenty. Poniżej przedstawiono kroki, aby wykonać korespondencję seryjną na wyżej wymienionym szablonie.

Poniższy przykładowy kod pokazuje, jak wykonać korespondencję seryjną programu MS Word przy użyciu tablicy wartości w języku C#.

// Aby uzyskać pełne przykłady i pliki danych, przejdź do https://github.com/aspose-words/Aspose.Words-for-.NET
// Ścieżka do katalogu dokumentów.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
// Otwórz istniejący dokument.
Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc");

// Przytnij końcowe i początkowe białe znaki wartości korespondencji seryjnej
doc.MailMerge.TrimWhitespaces = false;

// Wypełnij pola w dokumencie danymi użytkownika.
doc.MailMerge.Execute(
    new string[] { "FullName", "Company", "Address", "Address2", "City" },
    new object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" });

dataDir = dataDir + "MailMerge.ExecuteArray_out.doc";
// Wyślij dokument w formacie Word do przeglądarki klienta z opcją zapisania na dysku lub otwarcia w bieżącej przeglądarce.
doc.Save(dataDir);

Dokument programu Word po korespondencji seryjnej

Wykonaj korespondencję seryjną w języku C#

Wykonaj korespondencję seryjną przy użyciu źródła danych XML w języku C#

Pliki XML są powszechnie używane do przechowywania oraz importowania/eksportowania danych. Aspose.Words for .NET obsługuje również XML jako źródło danych dla korespondencji seryjnej. Po prostu wczytaj kod XML do obiektu DataSet i wykonaj korespondencję seryjną. Poniżej znajduje się przykładowy plik XML, którego będziemy używać.

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

Poniższy przykładowy kod pobiera dane ze źródła danych XML i wykonuje korespondencję seryjną przy użyciu języka C#.

// Aby uzyskać pełne przykłady i pliki danych, przejdź do https://github.com/aspose-words/Aspose.Words-for-.NET
// Ścieżka do katalogu dokumentów.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 

// Utwórz zestaw danych i przeczytaj plik XML.
DataSet customersDs = new DataSet();
customersDs.ReadXml(dataDir + "Customers.xml");

string fileName = "TestFile XML.doc";
// Otwórz dokument szablonu.
Document doc = new Document(dataDir + fileName);

// Wykonaj korespondencję seryjną, aby wypełnić szablon danymi z XML przy użyciu DataTable.
doc.MailMerge.Execute(customersDs.Tables["Customer"]);

dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
// Zapisz dokument wyjściowy.
doc.Save(dataDir);

Poniżej znajduje się szablon korespondencji seryjnej, który zostanie wypełniony danymi XML.

Szablon korespondencji seryjnej dla XML

Poniżej znajduje się strona 1 wynikowego dokumentu programu Word, który otrzymujemy po wykonaniu korespondencji seryjnej.

Wykonaj korespondencję seryjną z XML w C#

Niestandardowe formatowanie pól scalania

Aspose.Words for .NET zapewnia większą kontrolę nad korespondencją seryjną podczas wykonywania. Właściwość MailMerge.FieldMergingCallback umożliwia dostosowanie korespondencji seryjnej w przypadku napotkania dowolnego pola korespondencji seryjnej. MailMerge.FieldMergingCallback akceptuje klasę implementującą metody IFieldMergingCallback.FieldMerging i IFieldMergingCallback.ImageFieldMerging.

Poniższy przykładowy kod pokazuje, jak dostosować operację korespondencji seryjnej i zastosować formatowanie do komórek w tym szablonie.

// Aby uzyskać pełne przykłady i pliki danych, przejdź do https://github.com/aspose-words/Aspose.Words-for-.NET
// Ścieżka do katalogu dokumentów.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");

// Dodaj procedurę obsługi zdarzenia MergeField.
doc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows();

// Wykonaj korespondencję seryjną z regionami.
DataTable dataTable = GetSuppliersDataTable();
doc.MailMerge.ExecuteWithRegions(dataTable);
dataDir = dataDir + "MailMerge.AlternatingRows_out.doc";
doc.Save(dataDir);

Poniżej przedstawiono implementację klasy HandleMergeFieldAlternatingRows.

// Aby uzyskać pełne przykłady i pliki danych, przejdź do https://github.com/aspose-words/Aspose.Words-for-.NET
private class HandleMergeFieldAlternatingRows : IFieldMergingCallback
{
    ///<summary>
    /// Wywoływana dla każdego pola scalania napotkanego w dokumencie.
    /// Możemy zwrócić część danych do mechanizmu korespondencji seryjnej lub coś zrobić
    /// Inaczej z dokumentem. W tym przypadku modyfikujemy formatowanie komórek.
    ///</summary>
    void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
    {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.Document);

        // W ten sposób łapiemy początek nowego rzędu.
        if (e.FieldName.Equals("CompanyName"))
        {
            // Wybierz kolor w zależności od tego, czy numer wiersza jest parzysty, czy nieparzysty.
            Color rowColor;
            if (IsOdd(mRowIdx))
                rowColor = Color.FromArgb(213, 227, 235);
            else
                rowColor = Color.FromArgb(242, 242, 242);

            // W tej chwili nie ma możliwości ustawienia właściwości komórki dla całego wiersza,
            // Musimy więc iterować po wszystkich komórkach w wierszu.
           for (int colIdx = 0; colIdx < 4; colIdx++)
            {
                mBuilder.MoveToCell(0, mRowIdx, colIdx, 0);
                mBuilder.CellFormat.Shading.BackgroundPatternColor = rowColor;
            }

            mRowIdx++;
        }
    }

    void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
    {
        // Nic nie robić.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}     
///<summary>
/// Zwraca true, jeśli wartość jest nieparzysta; false, jeśli wartość jest parzysta.
///</summary>
private static bool IsOdd(int value)
{
    // Kod jest nieco skomplikowany, ale poza tym automatyczna konwersja do VB nie działa.
    return ((value / 2) * 2).Equals(value);
}      
///<summary>
/// Utwórz DataTable i wypełnij ją danymi.
/// W rzeczywistości ta tabela danych powinna być wypełniona z bazy danych.
///</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;
}

Korespondencja seryjna z regionami przy użyciu języka C#

Może się zdarzyć, że będziesz musiał wypełnić i powtórzyć określony region w dokumencie programu Word. W takim przypadku możesz użyć korespondencji seryjnej z regionami. Aby utworzyć region, musisz określić początek i koniec regionu, a następnie Mail Megre powtórzy ten region dla każdego rekordu w źródle danych. Na przykład poniższy szablon zawiera dwa regiony, Orders i OrderDetails, z polami scalania odpowiednio „TableStart:Orders”, „TableEnd:Orders” i „TableStart:OrderDetails”, „TableEnd:OrderDetails”.

Korespondencja seryjna z regionami

Poniżej znajduje się przykładowy kod, który wykonuje Mail Megre w regionach dla wyżej wymienionego template.

// Aby uzyskać pełne przykłady i pliki danych, przejdź do https://github.com/aspose-words/Aspose.Words-for-.NET
// Ścieżka do katalogu dokumentów.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
string fileName = "MailMerge.ExecuteWithRegions.doc";
Document doc = new Document(dataDir + fileName);
 
// Użyj DataTable jako źródła danych.
int orderId = 10444;
DataTable orderTable = GetTestOrder(orderId);
doc.MailMerge.ExecuteWithRegions(orderTable);
 
// Zamiast korzystać z DataTable, możesz utworzyć DataView do niestandardowego sortowania lub filtrowania, a następnie korespondencji seryjnej.
DataView orderDetailsView = new DataView(GetTestOrderDetails(orderId));
orderDetailsView.Sort = "ExtendedPrice DESC";
 
// Wykonaj operację korespondencji seryjnej.
doc.MailMerge.ExecuteWithRegions(orderDetailsView);
 
// Zapisz scalony dokument.
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
doc.Save(dataDir);

Poniżej przedstawiono metody odczytu danych z bazy danych.

// Aby uzyskać pełne przykłady i pliki danych, przejdź do 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>
/// Funkcja narzędziowa, która tworzy połączenie, polecenie, 
/// Wykonuje polecenie i zwraca wynik w DataTable.
///</summary>
private static DataTable ExecuteDataTable(string commandText)
{
    // Otwórz połączenie z bazą danych.
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
        RunExamples.GetDataDir_Database() + "Northwind.mdb";
    OleDbConnection conn = new OleDbConnection(connString);
    conn.Open();

    // Utwórz i wykonaj polecenie.
    OleDbCommand cmd = new OleDbCommand(commandText, conn);
    OleDbDataAdapter da = new OleDbDataAdapter(cmd);
    DataTable table = new DataTable();
    da.Fill(table);

    // Zamknij bazę danych.
    conn.Close();

    return table;
}

Zagnieżdżone regiony korespondencji seryjnej

Najczęściej dane, które mamy w źródle danych, mają postać relacji. Na przykład tabela „Zamówienie” będzie miała relację jeden-do-wielu z tabelą „Szczegóły zamówienia”, w której będą przechowywane rekordy pozycji w zamówieniu. Aby poradzić sobie z takimi relacjami rodzic-dziecko, używana jest zagnieżdżona korespondencja seryjna. Poniżej znajduje się przykładowy szablon faktury, który dobrze pasuje do tego scenariusza.

Szablon korespondencji seryjnej z regionami

Poniżej znajduje się przykładowe źródło danych XML, którego użyjemy do zagnieżdżonej korespondencji seryjnej.

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

Natomiast OrderSchema.xsd dla tego XML to:

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

Poniższy przykładowy kod służy do wykonywania zagnieżdżonej korespondencji seryjnej przy użyciu języka C#.

// Aby uzyskać pełne przykłady i pliki danych, przejdź do https://github.com/aspose-words/Aspose.Words-for-.NET
// Ścieżka do katalogu dokumentów.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
	 
// Utwórz zestaw danych i przeczytaj plik XML.
DataSet pizzaDs = new DataSet();
	 
// Datatable.TableNames i DataSet.Relations są definiowane niejawnie przez platformę .NET za pośrednictwem ReadXml.
pizzaDs.ReadXml(dataDir + "CustomerData.xml");
string fileName = "Invoice Template.doc";

// Otwórz dokument szablonu.
Document doc = new Document(dataDir + fileName);
	 
// Przytnij końcowe i początkowe białe znaki wartości korespondencji seryjnej.
doc.MailMerge.TrimWhitespaces = false;
	 
// Wykonaj zagnieżdżoną korespondencję seryjną z regionami.
doc.MailMerge.ExecuteWithRegions(pizzaDs);
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);

// Zapisz wynik do pliku.
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);

Dokument programu Word po korespondencji seryjnej

Poniżej znajduje się pierwsza strona wynikowego dokumentu programu Word po wykonaniu korespondencji seryjnej.

Dokument programu Word po korespondencji seryjnej

Wniosek

Aspose.Words for .NET to bogaty w funkcje interfejs API korespondencji seryjnej, który zapewnia wszystkie standardowe i rozszerzone funkcje korespondencji seryjnej dla aplikacji .NET. W ciągu kilku wierszy kodu możesz bezproblemowo tworzyć proste lub złożone raporty z różnych typów źródeł danych. Więcej informacji na temat interfejsu API korespondencji seryjnej platformy .NET można znaleźć w dokumentacji. Aby dowiedzieć się więcej o Aspose.Words for .NET, zacznij od przewodników dla programistów i przykładów kodu GitHub.

Wypróbuj Aspose.Words dla platformy .NET za darmo

Możesz otrzymać bezpłatną tymczasową licencję, aby wypróbować Aspose.Words for .NET bez żadnych ograniczeń. Uzyskaj tymczasową licencję już teraz.

Zobacz też