
Jak stworzyc szablony formularzy do wypelnienia w C# przy uzyciu IronWord
Od lat zespoły .NET, które musiały generować spersonalizowane dokumenty Word na skalę, miały dwie rzeczywiste opcje, z których żadna nie była dobra.
Pierwszą było zautomatyzowanie samego Microsoft Word przez COM interop. Działało to, dopóki nie działało. Interop Word jest powolny, kruchy, wymaga licencji Word na każdym komputerze i rozpada się, gdy tylko próbujesz go uruchomić w kontenerze Linux, funkcji Azure lub jakimkolwiek innym środowisku serwerowym, gdzie Word nie jest zainstalowany. Większość zespołów, które tego próbowały, kończyła na przepisaniu tego.
Drugą była niestandardowa linia przeszukiwania i zastępowania. Odczytaj .docx jako XML lub jako tekst, podmień symbole zastępcze na rzeczywiste wartości i zapisz wynik. To działało w prostych przypadkach, ale łamało się na rzeczywistych dokumentach Word, które używają skomplikowanych struktur pól wyglądających zupełnie inaczej niż proste tokeny {{FirstName}}, które programiści oczekują znaleźć.
IronWord teraz wspiera mail merge natywnie. Szablony zaprojektowane w Microsoft Word, używając tej samej składni pola scalania, jaką Word sam tworzy, są populowane bezpośrednio z kodu .NET bez potrzeby instalacji Word.
Co robi funkcja
Silnik mail merge obsługuje oba style pól scalania, które generuje Word:
- Proste pola w formacie "FieldName", co otrzymujesz wpisując
<<FieldName>>bezpośrednio w szablonie - Skonplikowane pola, wieloelementowa struktura XML, którą Word generuje przez Wstaw → Szybkie elementy → Pole
Szablony mogą zawierać symbole zastępcze wartości pojedynczej, które są zastępowane raz na dokument, oraz powtarzające się regiony ograniczone przez znaczniki "TableStart:Name" i "TableEnd:Name", które rozwijają się na jeden wiersz na rekord danych.
Ta druga część to miejsce, gdzie funkcja zasługuje na swoje miejsce. Regiony powtarzające się to sposób, w jaki jednowierszowy szablon w fakturze rozwija się na pięćdziesięciowierszową tabelę pozycji lub, jak jeden kontakt w etykiecie staje się pełną siatką Avery wypełnioną z bazy danych.
Personalizowane listy przewodnie z CRM
Większość zespołów korzysta z mail merge najpierw przez operacje sprzedaży. CRM przechowuje dane klientów; marketing lub operacje sprzedażowe muszą wysłać spersonalizowane listy przewodnie, pakiety powitalne lub powiadomienia o odnowieniu. Schemat jest prosty: jeden szablon, wiersz na klienta, jeden spersonalizowany dokument wyjściowy.
// Template: "Dear «FirstName», thank you for your order of «Amount»..."
DataTable customers = LoadFromSalesforce(); // FirstName, LastName, Amount, ...
foreach (DataRow row in customers.Rows)
{
var doc = new WordDocument("cover-letter-template.docx");
doc.MailMerge.Execute(row);
doc.SaveAs($"letters/{row["LastName"]}.docx");
}Imports System.Data
' Template: "Dear «FirstName», thank you for your order of «Amount»..."
Dim customers As DataTable = LoadFromSalesforce() ' FirstName, LastName, Amount, ...
For Each row As DataRow In customers.Rows
Dim doc As New WordDocument("cover-letter-template.docx")
doc.MailMerge.Execute(row)
doc.SaveAs($"letters/{row("LastName")}.docx")
NextŹródło danych to DataTable, co oznacza, że wszystko, co ładuje się do jednego (Salesforce, HubSpot, SQL Server, CSV, odpowiedź API) staje się źródłem scalania bez dodatkowego kodu adaptera.
Faktury z powtarzającymi się pozycjami
Fakturowanie to miejsce, gdzie zdolność regionu powtarzającego się zasługuje na utrzymanie. Szablon faktury ma nagłówek (nazwa klienta, ID zamówienia, daty), jeden wiersz w tabeli pozycji i stopkę (sumy). Gdy scalenie jest wykonywane, pojedynczy wiersz szablonu rozwija się na jeden wiersz na produkt, niezależnie od tego, czy zamówienie ma jedną pozycję zakupową czy pięćdziesiąt.
// Template:
// Bill To: «CustomerName» Order: «OrderId»
// ┌──────────┬─────┬──────────┐
// │ «TableStart:Items»«Product» │ «Qty» │ «LineTotal» «TableEnd:Items» │
// └──────────┴─────┴──────────┘
// Total: «Total»
var doc = new WordDocument("invoice-template.docx");
doc.MailMerge.ExecuteWithRegions(orderLineItems); // one row per product
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CustomerName", "Acme Industries" },
{ "OrderId", "10444" },
{ "Total", "$1,117.71" },
});
doc.SaveAs("invoice-10444.docx");Imports System.Collections.Generic
' Template:
' Bill To: «CustomerName» Order: «OrderId»
' ┌──────────┬─────┬──────────┐
' │ «TableStart:Items»«Product» │ «Qty» │ «LineTotal» «TableEnd:Items» │
' └──────────┴─────┴──────────┘
' Total: «Total»
Dim doc As New WordDocument("invoice-template.docx")
doc.MailMerge.ExecuteWithRegions(orderLineItems) ' one row per product
doc.MailMerge.Execute(New Dictionary(Of String, String) From {
{"CustomerName", "Acme Industries"},
{"OrderId", "10444"},
{"Total", "$1,117.71"}
})
doc.SaveAs("invoice-10444.docx")Ten sam schemat działa na oferty, zamówienia zakupu, wyciągi i każdy dokument, gdzie lista o zmiennej długości znajduje się w stałokształtowej stronie.
Arkusze etykiet Avery i koperty
Zespoły zajmujące się wysyłkami i operacjami generują etykiety i koperty z list kontaktowych, a układy (Avery 5160, 5161, 5163 i ich międzynarodowe odpowiedniki) to znormalizowane szablony, które istnieją od dziesięcioleci. IronWord bezpośrednio wypełnia je: każda komórka w siatce etykiet pobiera odpowiedni kontakt z jednego wywołania API.
// Template: a 3×10 Avery 5160 grid, each cell has «CONTACT_FULLNAME» / «CONTACT_ADDRESS»
var doc = new WordDocument("avery-5160.docx");
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CONTACT_FULLNAME", "Jane Doe" },
{ "CONTACT_ADDRESS", "100 Main Street, Boston, MA 02108" },
});
doc.SaveAs("labels-jane.docx");Imports System.Collections.Generic
' Template: a 3×10 Avery 5160 grid, each cell has «CONTACT_FULLNAME» / «CONTACT_ADDRESS»
Dim doc As New WordDocument("avery-5160.docx")
doc.MailMerge.Execute(New Dictionary(Of String, String) From {
{"CONTACT_FULLNAME", "Jane Doe"},
{"CONTACT_ADDRESS", "100 Main Street, Boston, MA 02108"}
})
doc.SaveAs("labels-jane.docx")Dla list kontaktów o zmiennej długości stosuje się wzorzec ExecuteWithRegions z przykładu faktury: definiuje się jedną komórkę jako jednostkę powtarzalną, a reszta arkusza wypełnia się automatycznie.
Raporty wieloregionowe
Najpotężniejszym zastosowaniem są raporty wieloregionowe. Podsumowanie kwartalne może zawierać sekcje 'Najważniejsi klienci' oraz 'Najważniejsze produkty', z których każda jest zależna od swojej własnej tabeli danych. Z zestawem danych zawierającym wiele tabel, merge rozwija oba regiony w jednym wywołaniu.
// Template:
// Top Customers
// «TableStart:Customers» • «Name» | «City» | «Revenue» «TableEnd:Customers»
// Top Products
// «TableStart:Products» «ProductName»: «Revenue» «TableEnd:Products»
var ds = new DataSet();
ds.Tables.Add(topCustomers); // TableName = "Customers"
ds.Tables.Add(topProducts); // TableName = "Products"
var doc = new WordDocument("quarterly-report.docx");
doc.MailMerge.ExecuteWithRegions(ds); // expands both regions
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CompanyName", "Iron Software" },
{ "ReportDate", "Q2 2026" },
});
doc.SaveAs("Q2-2026-report.docx");Imports System.Data
Imports System.Collections.Generic
' Template:
' Top Customers
' «TableStart:Customers» • «Name» | «City» | «Revenue» «TableEnd:Customers»
' Top Products
' «TableStart:Products» «ProductName»: «Revenue» «TableEnd:Products»
Dim ds As New DataSet()
ds.Tables.Add(topCustomers) ' TableName = "Customers"
ds.Tables.Add(topProducts) ' TableName = "Products"
Dim doc As New WordDocument("quarterly-report.docx")
doc.MailMerge.ExecuteWithRegions(ds) ' expands both regions
doc.MailMerge.Execute(New Dictionary(Of String, String) From {
{"CompanyName", "Iron Software"},
{"ReportDate", "Q2 2026"}
})
doc.SaveAs("Q2-2026-report.docx")Każda tabela danych w DataSet odpowiada nazwo regionowi "TableStart:..." i pola skalarne uzupełniają wartości nagłówków w tym samym kroku.
Dla zespołów z przepływem pracy dokumentów, na które czeka czysta implementacja .NET, Iron Suite łączy IronWord wraz z IronPDF, IronOCR, IronXL i IronBarcode w jednej licencji.
Rozpocznij darmowy okres próbny, nie jest wymagana karta kredytowa.
Dlaczego to działa
Kilka rzeczy odróżnia to podejście od alternatyw:
Natywna składnia Word. Szablony projektowane są w Microsoft Word, używając narzędzi do pól scalanych, które Word już dostarcza. Zapisz jako .docx, przekaż plik do IronWord, a scalanie zostanie wykonane. Bez własnego języka szablonów, bez warstwy tłumaczeniowej, bez oddzielnej krzywej uczenia dla zespołu projektującego dokumenty.
Zarówno proste, jak i złożone formaty pól. Word tworzy dwie różne struktury pól w zależności od tego, jak pole zostało wstawione. IronWord obsługuje oba, co oznacza, że istniejące szablony zaprojektowane przez różnych członków zespołu w różny sposób wszystkie działają bez modyfikacji.
Brak zewnętrznych zależności. Biblioteka działa w pełni na .NET. Brak instalacji Word, brak COM, brak licencji Office, brak kruchości interop. Ten sam kod, który działa na maszynie deweloperskiej z systemem Windows, działa identycznie w kontenerze Linux, funkcji Azure lub agencie budującym bezserwerowym.
Podsumowanie
Scalanie poczty było od dawna brakującym elementem w narzędziach do dokumentów .NET, a dotychczasowe obejścia nie zestarzały się dobrze. Natywne scalanie poczty w IronWord zamyka tę lukę modelem, który odzwierciedla składnię pola scalania Worda, wspiera zarówno proste wartości, jak i powtarzające się regiony, i działa bez bagażu wdrożeniowego, który historycznie towarzyszył automatyzacji dokumentów w .NET.
Dla zespołów generujących faktury, etykiety, listy, umowy i raporty na dużą skalę, jest to najczystsza ścieżka od pojedynczego szablonu do tysięcy spersonalizowanych dokumentów.

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podręczników.
Powiązane artykuły


