이 기사에서는 MS Word 또는 Office Interop 없이 C# 또는 VB.NET을 사용하여 MS Word 편지 병합을 수행하는 방법을 보여 드리겠습니다. Aspose.Words for .NET은 모든 기본 기능과 확장된 MS Word 편지 병합 기능을 제공하는 기능이 풍부하고 강력한 Word API입니다. 이를 통해 Windows Forms, ASP.NET 웹 애플리케이션 또는 .NET/.NET Core 애플리케이션 내에서 편지, 봉투, 보고서, 송장 및 기타 유형의 문서를 생성할 수 있습니다.
.NET 편지 병합 API의 두드러진 기능을 다루는 이 문서는 다음 섹션으로 구성되어 있습니다.
- 편지 병합이란 무엇입니까?
- 편지 병합을 위한 데이터 원본
- 편지 병합을 위한 템플릿 준비
- .NET 편지 병합 API - 설치
- C#을 사용하여 Word 문서에서 편지 병합 수행
- XML 데이터 원본을 사용한 편지 병합
- 병합 필드의 사용자 지정 서식
- 지역과 편지 병합
- 중첩된 편지 병합 영역
편지 병합이란 무엇입니까?
메일 병합은 보고서, 편지, 봉투, 송장 및 기타 유형의 문서를 자동으로 생성하는 방법입니다. MS Word의 편지 병합을 사용하면 병합 필드가 포함된 템플릿 문서를 만든 다음 데이터 원본의 레코드를 사용하여 해당 필드를 채울 수 있습니다. 편지 병합을 이해하려면 10명의 다른 사람에게 편지를 보내야 하고 이름과 주소 필드만 업데이트해야 한다고 가정합니다. 이러한 경우 단순히 문자 템플릿을 만든 다음 데이터 소스를 사용하여 이름 및 주소 병합 필드를 채워 문자를 동적으로 생성합니다.
편지 병합을 위한 데이터 원본
편지 병합을 위한 데이터는 XML, JSON 또는 데이터베이스와 같은 모든 데이터 원본에서 가져올 수 있습니다. Aspose.Words for .NET에 관한 한 ADO.NET에서 지원하는 모든 데이터 소스를 사용할 수 있습니다. 데이터는 DataSet, DataTable, DataView 또는 값 배열에 로드할 수 있습니다.
편지 병합을 위한 템플릿 준비
편지 병합 템플릿은 병합 필드가 포함된 문서입니다. 그런 다음 이러한 필드는 편지 병합이 실행될 때 데이터 원본의 데이터로 채워집니다. 템플릿 문서는 템플릿 형식일 필요가 없으며 DOC/DOCX 문서일 수 있습니다. 이것이 편지 병합을 위한 템플릿을 준비하는 방법입니다.
- 문서를 열거나 MS Word에서 새 문서를 만듭니다.
- 병합 필드를 추가할 위치에 커서를 놓습니다.
- 삽입 메뉴에서 필드 옵션을 선택합니다.
- 필드 이름 목록에서 MergeField를 선택합니다.
- 필드 이름에 병합 필드의 이름을 입력하고 확인을 누릅니다.
- 문서를 저장합니다.
다음은 샘플 템플릿 문서의 스크린샷입니다.
.NET 편지 병합 API - 설치
.NET용 Aspose.Words는 다음 방법을 사용하여 다운로드하거나 설치할 수 있습니다.
C#을 사용하여 Word 문서에서 편지 병합 수행
템플릿이 준비되면 편지 병합을 실행하여 문서를 생성할 수 있습니다. 다음은 위에서 언급한 템플릿에서 편지 병합을 실행하는 단계입니다.
- Document 클래스를 사용하여 템플릿 문서를 로드합니다.
- Document.MailMerge.TrimWhitespaces와 같은 필수 편지 병합 옵션을 설정합니다.
- Document.MailMerge.Execute() 메서드를 사용하여 편지 병합을 실행하고 데이터 소스를 매개변수로 전달합니다.
- 생성된 문서는 Document.Save(String) 메소드를 이용하여 저장합니다.
다음 코드 샘플은 C#에서 값 배열을 사용하여 MS Word 편지 병합을 실행하는 방법을 보여줍니다.
// 전체 예제 및 데이터 파일을 보려면 https://github.com/aspose-words/Aspose.Words-for-.NET으로 이동하십시오.
// 문서 디렉토리의 경로입니다.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
// 기존 문서를 엽니다.
Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc");
// 후행 및 선행 공백 편지 병합 값 자르기
doc.MailMerge.TrimWhitespaces = false;
// 문서의 필드를 사용자 데이터로 채웁니다.
doc.MailMerge.Execute(
new string[] { "FullName", "Company", "Address", "Address2", "City" },
new object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" });
dataDir = dataDir + "MailMerge.ExecuteArray_out.doc";
// 디스크에 저장하거나 현재 브라우저 내에서 열 수 있는 옵션을 사용하여 Word 형식의 문서를 클라이언트 브라우저에 보냅니다.
doc.Save(dataDir);
편지 병합 후 Word 문서
C#에서 XML 데이터 원본을 사용하여 편지 병합 수행
XML 파일은 가져오기/내보내기 데이터를 유지하고 유지하는 데 널리 사용됩니다. .NET용 Aspose.Words는 편지 병합을 위한 데이터 소스로 XML도 지원합니다. XML을 DataSet 개체로 읽고 편지 병합을 실행하기만 하면 됩니다. 다음은 우리가 사용할 샘플 XML 파일입니다.
<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>
다음 코드 샘플은 XML 데이터 원본에서 데이터를 가져오고 C#을 사용하여 편지 병합을 실행합니다.
// 전체 예제 및 데이터 파일을 보려면 https://github.com/aspose-words/Aspose.Words-for-.NET으로 이동하십시오.
// 문서 디렉토리의 경로입니다.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
// 데이터 세트를 만들고 XML을 읽습니다.
DataSet customersDs = new DataSet();
customersDs.ReadXml(dataDir + "Customers.xml");
string fileName = "TestFile XML.doc";
// 템플릿 문서를 엽니다.
Document doc = new Document(dataDir + fileName);
// 메일 병합을 실행하여 DataTable을 사용하여 XML의 데이터로 템플릿을 채웁니다.
doc.MailMerge.Execute(customersDs.Tables["Customer"]);
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
// 출력 문서를 저장합니다.
doc.Save(dataDir);
다음은 XML 데이터로 채워질 편지 병합 템플릿입니다.
다음은 편지 병합을 실행한 후 얻은 결과 Word 문서의 1페이지입니다.
병합 필드의 사용자 지정 서식
.NET용 Aspose.Words를 사용하면 실행 중에 편지 병합을 더 잘 제어할 수 있습니다. MailMerge.FieldMergingCallback 속성을 사용하면 병합 필드가 발생할 때 편지 병합을 사용자 지정할 수 있습니다. MailMerge.FieldMergingCallback은 IFieldMergingCallback.FieldMerging 및 IFieldMergingCallback.ImageFieldMerging 메서드를 구현하는 클래스를 허용합니다.
다음 코드 샘플은 편지 병합 작업을 사용자 지정하고 이 템플릿 내의 셀에 서식을 적용하는 방법을 보여줍니다.
// 전체 예제 및 데이터 파일을 보려면 https://github.com/aspose-words/Aspose.Words-for-.NET으로 이동하십시오.
// 문서 디렉토리의 경로입니다.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");
// MergeField 이벤트에 대한 처리기를 추가합니다.
doc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows();
// 지역과 편지 병합을 실행합니다.
DataTable dataTable = GetSuppliersDataTable();
doc.MailMerge.ExecuteWithRegions(dataTable);
dataDir = dataDir + "MailMerge.AlternatingRows_out.doc";
doc.Save(dataDir);
다음은 HandleMergeFieldAlternatingRows 클래스의 구현입니다.
// 전체 예제 및 데이터 파일을 보려면 https://github.com/aspose-words/Aspose.Words-for-.NET으로 이동하십시오.
private class HandleMergeFieldAlternatingRows : IFieldMergingCallback
{
///<summary>
/// 문서에서 발견된 모든 병합 필드에 대해 호출됩니다.
/// 우리는 메일 병합 엔진에 일부 데이터를 반환하거나 뭔가를 할 수 있습니다
/// 문서와 함께. 이 경우 셀 서식을 수정합니다.
///</summary>
void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
{
if (mBuilder == null)
mBuilder = new DocumentBuilder(e.Document);
// 이런 식으로 우리는 새로운 행의 시작을 포착합니다.
if (e.FieldName.Equals("CompanyName"))
{
// 행 번호가 짝수인지 홀수인지에 따라 색상을 선택합니다.
Color rowColor;
if (IsOdd(mRowIdx))
rowColor = Color.FromArgb(213, 227, 235);
else
rowColor = Color.FromArgb(242, 242, 242);
// 현재 전체 행에 대해 셀 속성을 설정할 수 있는 방법은 없으며,
// 따라서 행의 모든 셀에 대해 반복해야 합니다.
for (int colIdx = 0; colIdx < 4; colIdx++)
{
mBuilder.MoveToCell(0, mRowIdx, colIdx, 0);
mBuilder.CellFormat.Shading.BackgroundPatternColor = rowColor;
}
mRowIdx++;
}
}
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
{
// 아무것도하지 마세요.
}
private DocumentBuilder mBuilder;
private int mRowIdx;
}
///<summary>
/// 값이 홀수이면 true를 반환합니다. 값이 짝수이면 false입니다.
///</summary>
private static bool IsOdd(int value)
{
// 코드는 약간 복잡하지만 그렇지 않으면 VB로의 자동 변환이 작동하지 않습니다.
return ((value / 2) * 2).Equals(value);
}
///<summary>
/// DataTable을 만들고 데이터로 채웁니다.
/// 실생활에서 이 DataTable은 데이터베이스에서 채워져야 합니다.
///</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;
}
C#을 사용하여 지역과 편지 병합
Word 문서의 특정 영역을 채우고 반복해야 하는 경우가 있을 수 있습니다. 이러한 경우 지역과 편지 병합을 사용할 수 있습니다. 지역을 생성하려면 지역의 시작과 끝을 지정해야 하며 Mail Megre는 데이터 원본의 각 레코드에 대해 해당 지역을 반복합니다. 예를 들어, 다음 템플릿에는 각각 «TableStart:Orders», «TableEnd:Orders» 및 «TableStart:OrderDetails», «TableEnd:OrderDetails» 병합 필드가 있는 Orders 및 OrderDetails라는 두 영역이 있습니다.
다음은 위에서 언급한 템플릿에 대한 지역에서 Mail Megre를 수행하는 코드 샘플입니다.
// 전체 예제 및 데이터 파일을 보려면 https://github.com/aspose-words/Aspose.Words-for-.NET으로 이동하십시오.
// 문서 디렉토리의 경로입니다.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
string fileName = "MailMerge.ExecuteWithRegions.doc";
Document doc = new Document(dataDir + fileName);
// DataTable을 데이터 원본으로 사용합니다.
int orderId = 10444;
DataTable orderTable = GetTestOrder(orderId);
doc.MailMerge.ExecuteWithRegions(orderTable);
// DataTable을 사용하는 대신 사용자 지정 정렬 또는 필터를 위한 DataView를 만든 다음 편지 병합을 할 수 있습니다.
DataView orderDetailsView = new DataView(GetTestOrderDetails(orderId));
orderDetailsView.Sort = "ExtendedPrice DESC";
// 편지 병합 작업을 실행합니다.
doc.MailMerge.ExecuteWithRegions(orderDetailsView);
// 병합된 문서를 저장합니다.
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
doc.Save(dataDir);
다음은 데이터베이스에서 데이터를 읽는 방법입니다.
// 전체 예제 및 데이터 파일을 보려면 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>
/// 연결, 명령,
/// 명령을 실행하고 결과를 DataTable에 반환합니다.
///</summary>
private static DataTable ExecuteDataTable(string commandText)
{
// 데이터베이스 연결을 엽니다.
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
RunExamples.GetDataDir_Database() + "Northwind.mdb";
OleDbConnection conn = new OleDbConnection(connString);
conn.Open();
// 명령을 만들고 실행합니다.
OleDbCommand cmd = new OleDbCommand(commandText, conn);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable table = new DataTable();
da.Fill(table);
// 데이터베이스를 닫습니다.
conn.Close();
return table;
}
중첩된 편지 병합 영역
대부분의 경우 데이터 원본에 있는 데이터는 관계의 형태로 제공됩니다. 예를 들어, “Order” 테이블은 주문의 항목 레코드를 유지하는 “OrderDetails"와 일대다 관계를 갖습니다. 이러한 부모-자식 관계를 처리하기 위해 중첩된 편지 병합이 사용됩니다. 다음은 이 시나리오에 잘 맞는 샘플 인보이스 템플릿입니다.
다음은 중첩된 편지 병합에 사용할 샘플 XML 데이터 원본입니다.
<?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>
반면 이 XML의 OrderSchema.xsd는 다음과 같습니다.
<?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>
다음 코드 샘플은 C#을 사용하여 중첩된 편지 병합을 실행하는 데 사용됩니다.
// 전체 예제 및 데이터 파일을 보려면 https://github.com/aspose-words/Aspose.Words-for-.NET으로 이동하십시오.
// 문서 디렉토리의 경로입니다.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
// 데이터 세트를 만들고 XML을 읽습니다.
DataSet pizzaDs = new DataSet();
// Datatable.TableNames 및 DataSet.Relations는 .NET에서 ReadXml을 통해 암시적으로 정의됩니다.
pizzaDs.ReadXml(dataDir + "CustomerData.xml");
string fileName = "Invoice Template.doc";
// 템플릿 문서를 엽니다.
Document doc = new Document(dataDir + fileName);
// 후행 및 선행 공백 편지 병합 값을 자릅니다.
doc.MailMerge.TrimWhitespaces = false;
// 지역과 중첩된 편지 병합을 실행합니다.
doc.MailMerge.ExecuteWithRegions(pizzaDs);
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
// 출력을 파일에 저장합니다.
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);
편지 병합 후 Word 문서
다음은 편지 병합을 실행한 후 생성된 Word 문서의 첫 번째 페이지입니다.
결론
.NET용 Aspose.Words는 .NET 응용 프로그램에 대한 모든 표준 및 확장된 편지 병합 기능을 제공하는 기능이 풍부한 편지 병합 API입니다. 몇 줄의 코드로 다양한 유형의 데이터 소스에서 간단하거나 복잡한 보고서를 원활하게 작성할 수 있습니다. 문서에서 .NET 편지 병합 API에 대해 자세히 알아볼 수 있습니다. .NET용 Aspose.Words에 대해 배우려면 개발자 안내서 및 GitHub 코드 샘플을 시작하십시오.
무료로 .NET용 Aspose.Words 사용해 보기
제한 없이 .NET용 Aspose.Words를 사용해 볼 수 있는 무료 임시 라이선스를 얻을 수 있습니다. 지금 임시 라이센스를 얻으십시오.