How to Mail Merge Word Documents in C

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronWord는 C#에서 Microsoft Office Interop 없이도 사전 작성된 Word 템플릿의 MERGEFIELD 플레이스홀더에 딕셔너리, DataSet 객체 또는 반복 영역 테이블에서 데이터로 채워 메일 머지를 수행합니다. Microsoft Word 또는 기타 호환 도구에서 생성된 병합 필드가 자동으로 감지됩니다.

메일 머지는 대규모로 개인화된 문서를 생성하는 표준 방식입니다: 템플릿을 공유하지만 수신자별로 다른 양식 편지, 송장, 증명서, 계약서 및 보고서 형태. 각 문서를 손으로 편집하는 대신 병합 필드가 포함된 단일 .docx 템플릿을 생성하고 IronWord가 데이터 소스에서 이들을 채우도록 합니다. 모든 작업은 WordDocument.MailMerge 엔트리 포인트를 통해 이루어집니다.

퀵스타트: Word 문서 메일 머지

템플릿에 MERGEFIELD 플레이스홀더를 포함하고 Execute에 필드 이름 및 값을 포함한 사전을 전달하고 결과를 저장합니다.

  1. NuGet 패키지 관리자를 사용하여 https://www.nuget.org/packages/IronWord 설치하기

    PM > Install-Package IronWord
  2. 다음 코드 조각을 복사하여 실행하세요.

    WordDocument doc = new WordDocument("template.docx");
    doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" }, { "Company", "Acme Corp" } });
    doc.SaveAs("output.docx");
  3. 실제 운영 환경에서 테스트할 수 있도록 배포하세요.

    무료 체험판으로 오늘 프로젝트에서 IronWord 사용 시작하기

    arrow pointer


사전에서 메일 머지를 수행하려면?

가장 간단한 데이터 소스는 병합 필드 이름으로 키된 IDictionary<string, string>입니다. Execute는 이름과 키가 일치하는 모든 필드를 교체합니다.

WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Execute(new Dictionary<string, string>
{
    { "FirstName", "Jane" },
    { "LastName",  "Smith" },
    { "Company",   "Acme Corp" }
});
doc.SaveAs("output.docx");
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Execute(new Dictionary<string, string>
{
    { "FirstName", "Jane" },
    { "LastName",  "Smith" },
    { "Company",   "Acme Corp" }
});
doc.SaveAs("output.docx");
Dim doc As New WordDocument("template.docx")
doc.MailMerge.Execute(New Dictionary(Of String, String) From {
    {"FirstName", "Jane"},
    {"LastName", "Smith"},
    {"Company", "Acme Corp"}
})
doc.SaveAs("output.docx")
$vbLabelText   $csharpLabel

필드 이름 조회는 기본적으로 대소문자를 구분하지 않고 Microsoft Word와 일치합니다. MailMerge.Options.CaseInsensitiveFieldNames = false을/를 설정하여 대소문자를 정확히 일치하도록 요구하세요.

필드 이름 및 값의 두 병렬 시퀀스를 제공할 수도 있습니다:

doc.MailMerge.Execute(
    new[] { "FirstName", "LastName" },
    new[] { "Jane", "Smith" });
doc.MailMerge.Execute(
    new[] { "FirstName", "LastName" },
    new[] { "Jane", "Smith" });
doc.MailMerge.Execute(  
    New String() { "FirstName", "LastName" },  
    New String() { "Jane", "Smith" })
$vbLabelText   $csharpLabel

Execute(fieldNames, values)은(는) 두 시퀀스의 길이가 다르면 ArgumentException을(를) 던집니다.

데이터테이블 또는 데이터행에서 메일 머지를 수행하려면?

데이터가 데이터베이스 또는 기존 DataSet에서 올 경우, DataTable 또는 DataRow을(를) Execute에 직접 전달합니다. 병합 필드 이름은 열 이름과 일치합니다. Execute(DataTable)는 표의 첫 번째 행의 값을 사용하고, Execute(DataRow)은 행의 상위 표의 열 이름을 사용합니다.

DataTable table = new DataTable();
table.Columns.Add("FirstName");
table.Columns.Add("LastName");
DataRow row = table.NewRow();
row["FirstName"] = "Jane";
row["LastName"]  = "Smith";
table.Rows.Add(row);

WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Execute(row);
doc.SaveAs("output.docx");
DataTable table = new DataTable();
table.Columns.Add("FirstName");
table.Columns.Add("LastName");
DataRow row = table.NewRow();
row["FirstName"] = "Jane";
row["LastName"]  = "Smith";
table.Rows.Add(row);

WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Execute(row);
doc.SaveAs("output.docx");
Imports System.Data

Dim table As New DataTable()
table.Columns.Add("FirstName")
table.Columns.Add("LastName")
Dim row As DataRow = table.NewRow()
row("FirstName") = "Jane"
row("LastName") = "Smith"
table.Rows.Add(row)

Dim doc As New WordDocument("template.docx")
doc.MailMerge.Execute(row)
doc.SaveAs("output.docx")
$vbLabelText   $csharpLabel

반복 테이블 영역을 채우려면?

반복 영역은 템플릿의 한 행을 여러 개로 만들어 청구 라인 항목이나 주문 목록에 이상적입니다. 템플릿에서 TableStart:RegionNameTableEnd:RegionName라는 두 개의 마커 필드 사이에 반복 콘텐츠를 감쌉니다. 그런 다음 테이블의 각 행에 대해 영역의 콘텐츠를 반복하는 ExecuteWithRegions을(를) 호출합니다.

ExecuteWithRegions은 이름이 표와 일치하는 모든 영역을 확장하는 전체 DataSet, 이름이 dataTable.TableName과 일치하는 영역을 확장하는 단일 DataTable 또는 영역 이름과 DataTable을 수용합니다.

DataTable orders = new DataTable("Orders");
orders.Columns.Add("Item");
orders.Columns.Add("Qty");
orders.Rows.Add("Widget A", "3");
orders.Rows.Add("Widget B", "1");

DataSet ds = new DataSet();
ds.Tables.Add(orders);

WordDocument doc = new WordDocument("invoice-template.docx");
doc.MailMerge.ExecuteWithRegions(ds);
doc.MailMerge.Execute(new Dictionary<string, string> { { "CustomerName", "Jane Smith" } });
doc.SaveAs("invoice.docx");
DataTable orders = new DataTable("Orders");
orders.Columns.Add("Item");
orders.Columns.Add("Qty");
orders.Rows.Add("Widget A", "3");
orders.Rows.Add("Widget B", "1");

DataSet ds = new DataSet();
ds.Tables.Add(orders);

WordDocument doc = new WordDocument("invoice-template.docx");
doc.MailMerge.ExecuteWithRegions(ds);
doc.MailMerge.Execute(new Dictionary<string, string> { { "CustomerName", "Jane Smith" } });
doc.SaveAs("invoice.docx");
Imports System.Data
Imports System.Collections.Generic

Dim orders As New DataTable("Orders")
orders.Columns.Add("Item")
orders.Columns.Add("Qty")
orders.Rows.Add("Widget A", "3")
orders.Rows.Add("Widget B", "1")

Dim ds As New DataSet()
ds.Tables.Add(orders)

Dim doc As New WordDocument("invoice-template.docx")
doc.MailMerge.ExecuteWithRegions(ds)
doc.MailMerge.Execute(New Dictionary(Of String, String) From {{"CustomerName", "Jane Smith"}})
doc.SaveAs("invoice.docx")
$vbLabelText   $csharpLabel

참고해 주세요ExecuteWithRegions은(는) 반복 영역만 채웁니다. 위와 같이 영역 확장 후 표준 병합 필드를 채우려면 Execute(...)을 호출하세요.

템플릿의 병합 필드를 검사하려면?

병합 전에 템플릿에 무엇이 포함되어 있는지 파악하여 템플릿을 확인하거나 데이터 소스를 동적으로 구축하는 데 유용합니다.

  • GetFieldNames()은 문서 순서로 중복되지 않는 모든 값 스타일 병합 필드의 이름을 반환합니다.
  • GetRegionNames()은 문서에 선언된 모든 TableStart 영역의 이름을 반환합니다.
  • GetFields()TableEnd 마커를 포함한 모든 필드를 MergeField 객체로 반환합니다.
WordDocument doc = new WordDocument("template.docx");
IReadOnlyList<string> fieldNames = doc.MailMerge.GetFieldNames();
IReadOnlyList<string> regionNames = doc.MailMerge.GetRegionNames();
// fieldNames:  ["FirstName", "LastName", "Company"]
// regionNames: ["Orders", "LineItems"]
WordDocument doc = new WordDocument("template.docx");
IReadOnlyList<string> fieldNames = doc.MailMerge.GetFieldNames();
IReadOnlyList<string> regionNames = doc.MailMerge.GetRegionNames();
// fieldNames:  ["FirstName", "LastName", "Company"]
// regionNames: ["Orders", "LineItems"]
Dim doc As New WordDocument("template.docx")
Dim fieldNames As IReadOnlyList(Of String) = doc.MailMerge.GetFieldNames()
Dim regionNames As IReadOnlyList(Of String) = doc.MailMerge.GetRegionNames()
' fieldNames:  ["FirstName", "LastName", "Company"]
' regionNames: ["Orders", "LineItems"]
$vbLabelText   $csharpLabel

MergeField은(는) 문서에 저장된 전체 Instruction 텍스트 (예: MERGEFIELD FirstName \* MERGEFORMAT)와 딱 "TableStart:Orders""Orders" 예제를 포함하는 영역 마커에만 설정된 RegionName, 영역들의 경계를 나타내는 Kind을(를) 노출합니다: Value (데이터 값 대신 텍스트로 대체), TableStart 또는 TableEnd (반복 영역의 경계를 나타내는), 또는 NextRecord (같은 템플릿 본내에서 다음 데이터 레코드로 넘어가는 NEXT 필드).

일치하지 않은 필드 및 null 값을 제어하려면?

병합 동작은 MailMerge.Options을 통해 구성됩니다:

옵션 Default 행동
RemoveUnusedFields true 데이터 소스에 일치하는 키가 없는 병합 필드를 제거합니다. false으로 설정하여 그대로 유지하십시오.
RemoveUnusedRegions true 데이터 소스에서 일치하는 테이블이 없는 TableEnd 영역을 제거합니다.
NullValueReplacement "" 자료 출처에서 필드에 대해 null 값을 제공할 때 대체되는 텍스트입니다.
CaseInsensitiveFieldNames true 필드 이름을 일치시킬 때 대소문자를 구분하지 않고 Microsoft Word 동작을 모방합니다.
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Options.RemoveUnusedFields = false;
doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" } });
doc.SaveAs("partial-output.docx");
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Options.RemoveUnusedFields = false;
doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" } });
doc.SaveAs("partial-output.docx");
Dim doc As New WordDocument("template.docx")
doc.MailMerge.Options.RemoveUnusedFields = False
doc.MailMerge.Execute(New Dictionary(Of String, String) From {{"FirstName", "Jane"}})
doc.SaveAs("partial-output.docx")
$vbLabelText   $csharpLabel

Word 문서의 텍스트를 교체하는 방법을 참고하십시오. 자료 출처 없이도 간단히 값 치환이 가능합니다.

자주 묻는 질문

C#으로 Word 문서의 메일 병합 실행 방법

MERGEFIELD 플레이스홀더가 포함된 Word 템플릿을 WordDocument 생성자로 로드한 다음 요청 시 키 또는 열과 일치하는 필드를 교체하고 SaveAs로 결과를 저장하기 위해 doc.MailMerge.Execute를 사전, DataTable, 또는 DataRow와 함께 호출하십시오. Microsoft Word에서 생성된 병합 필드는 자동으로 감지되고, Microsoft Office 설치가 필요하지 않습니다.

IronWord 메일 병합이 사용할 수 있는 데이터 소스는 무엇입니까?

MailMerge.Execute는 사전의 필드명과 값, 필드명과 값의 두 개의 병렬 시퀀스, DataTable (첫 번째 행), DataRow (부모 테이블의 열 사용)를 허용합니다. MailMerge.ExecuteWithRegions는 반복 테이블 영역을 확장하기 위해 DataSet 또는 DataTable을 허용합니다.

Word 메일 병합에서 반복 테이블 영역을 어떻게 채우나요?

템플릿의 반복 콘텐츠를 TableStart:RegionName 및 TableEnd:RegionName 병합 필드 사이에 감싸고 DataSet 또는 DataTable을 사용하여 MailMerge.ExecuteWithRegions를 호출합니다. 해당 테이블의 각 행당 지역의 콘텐츠가 반복됩니다. ExecuteWithRegions는 영역만 채우므로 표준 병합 필드를 채우기 위해 이후 Execute를 호출합니다.

병합하기 전에 템플릿의 병합 필드를 검사할 수 있습니까?

네. MailMerge.GetFieldNames는 문서 순서대로 값 스타일의 필드명을 반환하고, GetRegionNames는 TableStart 지역의 이름을 반환하며, GetFields는 각 필드의 Name, Instruction, Kind (Value, TableStart, TableEnd, 또는 NextRecord), RegionName을 노출하는 MergeField 객체를 반환합니다.

일치하는 데이터가 없는 병합 필드는 어떻게 됩니까?

기본적으로 MailMergeOptions.RemoveUnusedFields는 참이므로 데이터 소스에 일치하는 키가 없는 필드는 출력에서 제거됩니다. 그것을 거짓으로 설정하여 필드를 남겨둘 수 있습니다. RemoveUnusedRegions가 참일 때 일치하지 않는 TableStart/TableEnd 지역은 제거되며, null 값은 NullValueReplacement 문자열로 대체됩니다.

메일 병합 필드 매칭은 대소문자를 구분합니까?

아니요. 필드명 조회는 기본적으로 대소문자를 구분하지 않아 Microsoft Word 행동과 일치합니다. 정확한 대소문자 일치를 원하시면 MailMerge.Options.CaseInsensitiveFieldNames를 거짓으로 설정하세요.

Curtis Chau
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.

시작할 준비 되셨나요?
Nuget 다운로드 48,355 | 버전: 2026.7 방금 출시
Still Scrolling Icon

아직도 스크롤하고 계신가요?

빠른 증거를 원하시나요? PM > Install-Package IronWord
샘플 실행 데이터를 워드 문서로 변환 확인.