이 게시물은 Java를 사용하여 MS Word 문서에서 편지 병합 작업을 수행하는 방법을 다룹니다. 이 기사를 마치면 편지 병합 템플릿을 만들고 프로그래밍 방식으로 편지 병합을 실행하는 방법을 배우게 됩니다.

편지 병합 정보

메일 병합은 편지, 봉투, 송장, 보고서 및 기타 유형의 문서를 동적으로 생성하는 편리한 방법입니다. 편지 병합을 사용하여 병합 필드가 포함된 템플릿 파일을 만든 다음 데이터 원본의 데이터를 사용하여 해당 필드를 채웁니다. 20명의 다른 사람에게 편지를 보내야 하고 각 사본에서 받는 사람의 이름과 주소만 변경하면 된다고 가정해 보겠습니다. 이 경우 편지에 대한 편지 병합 템플릿을 만든 다음 이름 및 주소 필드를 동적으로 채워서 20개의 편지를 생성할 수 있습니다.

Java 메일 병합 API - 무료 다운로드

Aspose.Words for Java는 처음부터 다양한 유형의 문서를 생성할 수 있는 잘 알려진 워드 프로세싱 API입니다. API는 템플릿 및 데이터 원본을 사용하여 문서를 동적으로 생성할 수 있는 기본 제공 편지 병합 기능을 제공합니다. Aspose.Words for Java는 JAR로 다운로드하거나 Maven 기반 애플리케이션 내에 설치할 수 있습니다.

<repository>
    <id>AsposeJavaAPI</id>
    <name>Aspose Java API</name>
    <url>https://repository.aspose.com/repo/</url>
</repository>
<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-words</artifactId>
    <version>20.11</version>
    <classifier>jdk17</classifier>
</dependency>

편지 병합을 위한 데이터 원본

편지 병합의 데이터는 JSON, XML, 스프레드시트 또는 데이터베이스와 같은 모든 데이터 소스에서 가져올 수 있습니다.

MS Word에서 편지 병합을 위한 템플릿 만들기

편지 병합에 사용되는 템플릿은 간단한 Word 문서(예: DOCX)일 수 있으며 템플릿 형식일 필요는 없습니다. 템플릿 문서에는 편지 병합이 실행될 때 데이터로 채워지는 병합 필드가 있습니다. 다음은 MS Word를 사용하여 편지 병합 템플릿을 준비하는 단계입니다.

  • MS Word에서 새 문서를 만듭니다.
  • 병합 필드를 추가할 위치에 커서를 놓습니다.
  • 삽입 메뉴에서 필드 옵션을 선택합니다.
  • 필드 이름 목록에서 MergeField를 선택합니다.
  • 필드 이름에 병합 필드의 이름을 입력하고 확인을 누릅니다.
  • 문서를 DOCX로 저장합니다.

다음은 샘플 템플릿 문서의 스크린샷입니다.

편지 병합 워드 템플릿

Java를 사용하여 편지 병합 템플릿 만들기

프로그래밍 방식으로 편지 병합 템플릿을 생성할 수도 있습니다. 다음은 이를 위한 단계입니다.

다음 코드 샘플은 Java를 사용하여 편지 병합 템플릿을 만드는 방법을 보여줍니다.

// 문서 빌더 만들기
DocumentBuilder builder = new DocumentBuilder();

// 텍스트 입력 필드 삽입 이 필드의 고유 이름은 "Hello"이고 다른 매개변수는 다음을 정의합니다.
// FormField의 유형, 텍스트 형식, 필드 결과 및 최대 텍스트 길이(0 = 제한 없음)
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0);
builder.insertField("MERGEFIELD CustomerFirstName \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0);
builder.insertField("MERGEFIELD CustomerLastName \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " , ", 0);

// 문서에 단락 나누기 삽입
builder.insertParagraph();

// 메일 본문 삽입
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Thanks for purchasing our ", 0);
builder.insertField("MERGEFIELD ProductName \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", please download your Invoice at ",
	0);
builder.insertField("MERGEFIELD InvoiceURL \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "",
	". If you have any questions please call ", 0);
builder.insertField("MERGEFIELD Supportphone \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", or email us at ", 0);
builder.insertField("MERGEFIELD SupportEmail \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ".", 0);

builder.insertParagraph();

// 메일 끝 삽입
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Best regards,", 0);
builder.insertBreak(BreakType.LINE_BREAK);
builder.insertField("MERGEFIELD EmployeeFullname \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0);
builder.insertField("MERGEFIELD EmployeeDepartment \\* MERGEFORMAT");

// 문서 저장
builder.getDocument().save("document.docx");

Java를 사용하여 Word 문서에서 편지 병합 수행

템플릿이 준비되면 병합 필드를 데이터로 채울 수 있습니다. 다음은 Word 템플릿에서 편지 병합을 수행하는 단계입니다.

다음 코드 샘플은 Java를 사용하여 Word 문서에서 편지 병합을 수행하는 방법을 보여줍니다.

// 템플릿 코드 포함
Document doc = new Document();

// 문서 빌더에 문서 전달
DocumentBuilder builder = new DocumentBuilder(doc);

// 병합 필드 만들기
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");

// 템플릿 저장
builder.getDocument().save("MailMerge.TestTemplate.docx");

// 문서의 필드를 사용자 데이터로 채우기
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
		new Object[] { "John Doe", "Hawaiian", "2" });

// 문서 저장 
builder.getDocument().save("MailMerge.Simple.docx");

주형

자바의 간단한 편지 병합

산출

간단한 편지 병합

XML 데이터 원본을 사용하여 편지 병합 수행

이전 예제에서는 Java 개체를 사용하여 편지 병합을 수행했습니다. 그러나 대부분의 경우 데이터 원본을 사용하여 병합 필드를 채웁니다. 데모를 위해 편지 병합에서 XML 데이터 원본을 사용하는 방법을 확인하겠습니다. 다음은 이를 위한 단계입니다.

  • DataSet 클래스를 사용하여 XML 데이터 소스를 로드합니다.
  • Document 클래스를 사용하여 편지 병합 템플릿을 로드합니다.
  • 데이터 소스에서 원하는 데이터 테이블을 사용하여 병합 필드를 채우려면 실행 기능을 사용하십시오.
  • 생성된 Word 문서는 Document.save(String) 메소드를 이용하여 저장합니다.

다음은 이 예제에서 사용되는 XML 데이터 소스입니다.

<?xml version="1.0" encoding="utf-8"?>
<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 데이터 원본의 고객 데이터 테이블을 사용하여 편지 병합 템플릿을 채우는 방법을 보여줍니다.

// 데이터 세트 생성 및 XML 읽기
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// 템플릿 문서 열기
Document doc = new Document("TestFile XML.docx");

// 메일 병합을 실행하여 DataTable을 사용하여 XML의 데이터로 템플릿을 채웁니다.
// 이 클래스는 단일 반복 가능 영역(및 모든 중첩 영역)에서도 작동합니다.
// 단일 XML 데이터 원본에서 여러 영역을 동시에 병합하려면 XmlMailMergeDataSet 클래스를 사용합니다.
// 예: doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));

// 출력 문서 저장
doc.save("generated-document.docx");

주형

XML과 편지 병합

산출

편지 병합 XML

Java에서 영역과 편지 병합

경우에 따라 문서의 특정 영역을 반복해야 할 수도 있습니다. 예를 들어, 각 고객이 주문한 주문을 별도의 테이블에 표시하려고 합니다. 이러한 경우 편지 병합 영역을 활용할 수 있습니다. 영역을 생성하기 위해 영역의 시작과 끝을 지정할 수 있습니다. 결과적으로 편지 병합을 실행하는 동안 데이터의 각 인스턴스에 대해 영역이 반복됩니다.

다음 스크린샷은 영역이 테이블로 구성된 템플릿을 보여줍니다. «TableStart:Customers»로 시작하여 «TableEnd:Customers»에서 끝납니다.

편지 병합 영역 템플릿

다음 코드 샘플은 영역이 있는 템플릿을 만들고 데이터로 채우는 방법을 보여줍니다.

// 문서 만들기
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// 데이터 집합이 있는 지역과 편지 병합의 시작점입니다.
builder.insertField(" MERGEFIELD TableStart:Customers");
// "Customers" 테이블의 "CustomerName" 열 행의 데이터는
// 이 MERGEFIELD에서.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");

// 열 머리글 만들기
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();

// "Orders"라는 두 번째 데이터 테이블이 있습니다.
// "고객"과의 관계
// 동일한 CustomerID 값을 가진 행을 선택합니다.
builder.insertCell();
builder.insertField(" MERGEFIELD TableStart:Orders");
builder.insertField(" MERGEFIELD ItemName");
builder.insertCell();
builder.insertField(" MERGEFIELD Quantity");
builder.insertField(" MERGEFIELD TableEnd:Orders");
builder.endTable();

// 지역과 편지 병합의 끝점입니다.
builder.insertField(" MERGEFIELD TableEnd:Customers");

// 데이터 세트를 전달하여 지역과 편지 병합을 수행합니다.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);

// 결과 저장
doc.save("MailMerge.ExecuteWithRegions.docx");

산출

편지 병합 영역

Java를 사용하여 중첩된 편지 병합 영역 만들기

편지 병합의 또 다른 인기 있는 시나리오는 중첩 영역이 있는 경우입니다. 예를 들어 주문과 각 주문의 항목을 나열해야 하는 경우 중첩 영역을 사용할 수 있습니다. 다음 이미지는 중첩 영역에 대한 그림을 더 명확하게 만듭니다.

위의 이미지에는 항목의 각 레코드가 주문의 레코드에 연결된 Orders 테이블과 Items 테이블이 있습니다. 따라서 이 두 테이블 사이에는 일대다 관계가 존재합니다. 이러한 경우 Aspose.Words는 DataSet에 정의된 관계를 처리하면서 편지 병합을 실행합니다. 예를 들어, XML 데이터 소스가 있는 경우 Aspose.Words는 스키마 정보 또는 XML 구조를 사용하여 관계를 찾습니다. 따라서 수동으로 처리할 필요가 없으며 Document.getMailMerge().executeWithRegions(DataSet) 메서드가 (이전 예와 같이) 작동합니다.

병합 필드에 사용자 지정 서식 적용

편지 병합에 대한 더 많은 제어를 제공하기 위해 Java용 Aspose.Words를 사용하면 편지 병합 실행 중에 병합 필드를 사용자 정의할 수 있습니다. setFieldMergingCallback(IFieldMergingCallback) 메서드는 편지 병합 프로세스에 대한 사용자 지정 제어를 위해 fieldMerging(FieldMergingArgs)imageFieldMerging(ImageFieldMergingArgs) 메서드를 구현하는 클래스를 허용합니다. 편지 병합 실행 중에 병합 필드가 발생하면 fieldMerging(FieldMergingArgs) 이벤트가 발생합니다.

다음은 편지 병합 작업을 사용자 지정하고 셀에 서식을 적용하는 방법의 전체 코드 샘플입니다.

public class ApplyCustomFormattingDuringMailMerge {

    private static final String dataDir = Utils.getSharedDataDir(ApplyCustomFormattingDuringMailMerge.class) + "MailMerge/";

    public static void main(String[] args) throws Exception {
        Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");

        // MergeField 이벤트에 대한 처리기를 추가합니다.
        doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());

        // 지역과 편지 병합을 실행합니다.
        DataTable dataTable = getSuppliersDataTable();
        doc.getMailMerge().executeWithRegions(dataTable);

        doc.save(dataDir + "MailMerge.AlternatingRows Out.doc");
    }

    /**
     * 값이 홀수이면 true를 반환하고, 그렇지 않으면 true를 반환합니다. 값이 짝수이면 false입니다.
     */
    public static boolean isOdd(int value) throws Exception {
        return (value % 2 != 0);
    }

    /**
     * DataTable을 만들고 데이터로 채웁니다. 실생활에서 이 DataTable
     * 데이터베이스에서 채워야 합니다.
     */
    private static DataTable getSuppliersDataTable() throws Exception {
        java.sql.ResultSet resultSet = createCachedRowSet(new String[]{"CompanyName", "ContactName"});

        for (int i = 0; i < 10; i++)
            addRow(resultSet, new String[]{"Company " + Integer.toString(i), "Contact " + Integer.toString(i)});

        return new DataTable(resultSet, "Suppliers");
    }

    /**
     * 빈 Java 연결이 끊긴 ResultSet를 생성하는 도우미 메서드
     * 지정된 열.
     */
    private static ResultSet createCachedRowSet(String[] columnNames) throws Exception {
        RowSetMetaDataImpl metaData = new RowSetMetaDataImpl();
        metaData.setColumnCount(columnNames.length);
        for (int i = 0; i < columnNames.length; i++) {
            metaData.setColumnName(i + 1, columnNames[i]);
            metaData.setColumnType(i + 1, java.sql.Types.VARCHAR);
        }

        CachedRowSet rowSet = RowSetProvider.newFactory().createCachedRowSet();
        ;
        rowSet.setMetaData(metaData);

        return rowSet;
    }

    /**
     * 지정된 값으로 새 행을 추가하는 도우미 메서드
     * 연결이 끊긴 ResultSet.
     */
    private static void addRow(ResultSet resultSet, String[] values) throws Exception {
        resultSet.moveToInsertRow();

        for (int i = 0; i < values.length; i++)
            resultSet.updateString(i + 1, values[i]);

        resultSet.insertRow();

        // 이 "춤"은 결과 집합의 끝에 행을 올바르게 추가하는 데 필요합니다.
        // 다른 작업을 수행하면 행이 맨 앞이나 결과에 추가됩니다.
        // 집합은 편지 병합 중에 삭제된 행에 대한 예외를 throw합니다.
        resultSet.moveToCurrentRow();
        resultSet.last();
    }
}

class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
    /**
     * 문서에서 발견된 모든 병합 필드에 대해 호출됩니다. 우리는 할 수 있습니다
     * 일부 데이터를 편지 병합 엔진으로 반환하거나
     * 문서. 이 경우 셀 서식을 수정합니다.
     */
    public void fieldMerging(FieldMergingArgs e) throws Exception {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.getDocument());

        // 이런 식으로 우리는 새로운 행의 시작을 포착합니다.
        if (e.getFieldName().equals("CompanyName")) {
            // 행 번호가 짝수인지 홀수인지에 따라 색상을 선택합니다.
            Color rowColor;
            if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
                rowColor = new Color(213, 227, 235);
            else
                rowColor = new Color(242, 242, 242);

            // 현재로서는 전체 행에 대한 셀 속성을 설정할 수 있는 방법이 없으며,
            // 따라서 행의 모든 셀을 반복해야 합니다.
            for (int colIdx = 0; colIdx < 4; colIdx++) {
                mBuilder.moveToCell(0, mRowIdx, colIdx, 0);
                mBuilder.getCellFormat().getShading().setBackgroundPatternColor(rowColor);
            }

            mRowIdx++;
        }
    }

    public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception {
        // 아무것도하지 마세요.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

결론

편지 병합은 MS Word 문서를 동적으로 생성하는 다양한 기능을 제공합니다. 데이터베이스 또는 기타 데이터 소스의 데이터를 기반으로 간단한 보고서와 복잡한 보고서를 생성할 수 있습니다. 이 기사에서 Java를 사용하여 프로그래밍 방식으로 편지 병합 기능을 구현하는 방법을 살펴보았습니다. 문서를 사용하여 Java Mail Merge API에 대해 자세히 알아볼 수 있습니다.

또한보십시오