โพสต์นี้ครอบคลุมวิธีการดำเนินการ Mail Merge ในเอกสาร MS Word โดยใช้ Java ในตอนท้ายของบทความนี้ คุณจะได้เรียนรู้วิธีสร้างเทมเพลตจดหมายเวียนและดำเนินการจดหมายเวียนโดยทางโปรแกรม

เกี่ยวกับจดหมายเวียน

Mail Merge เป็นวิธีที่สะดวกในการสร้างจดหมาย ซองจดหมาย ใบแจ้งหนี้ รายงาน และเอกสารประเภทอื่นๆ แบบไดนามิก เมื่อใช้ Mail Merge คุณจะสร้างไฟล์เทมเพลตที่มีเขตข้อมูลผสาน จากนั้นเติมข้อมูลในฟิลด์เหล่านั้นโดยใช้ข้อมูลในแหล่งข้อมูล สมมติว่าคุณต้องส่งจดหมายถึง 20 คนที่แตกต่างกัน และคุณต้องเปลี่ยนชื่อและที่อยู่ของผู้รับในแต่ละฉบับเท่านั้น ในกรณีนี้ คุณสามารถสร้างแม่แบบจดหมายเวียนสำหรับจดหมาย แล้วสร้างจดหมาย 20 ฉบับโดยการเติมฟิลด์ชื่อและที่อยู่แบบไดนามิก

Java Mail Merge API - ดาวน์โหลดฟรี

Aspose.Words for Java คือ API การประมวลผลคำที่รู้จักกันดี ซึ่งช่วยให้คุณสร้างเอกสารประเภทต่างๆ ได้ตั้งแต่เริ่มต้น API มีคุณสมบัติ Mail Merge ในตัวที่ให้คุณสร้างเอกสารแบบไดนามิกโดยใช้เทมเพลตและแหล่งข้อมูล 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

เทมเพลตที่ใช้ใน Mail Merge สามารถเป็นเอกสาร Word แบบธรรมดา (เช่น DOCX) และไม่จำเป็นต้องอยู่ในรูปแบบเทมเพลต เอกสารแม่แบบประกอบด้วยเขตข้อมูลผสานที่มีการเติมข้อมูลเมื่อดำเนินการจดหมายเวียน ต่อไปนี้เป็นขั้นตอนในการเตรียมเทมเพลต Mail Merge โดยใช้ MS Word

  • สร้างเอกสารใหม่ใน MS Word
  • วางเคอร์เซอร์ในตำแหน่งที่คุณต้องการเพิ่มเขตข้อมูลผสาน
  • จากเมนูแทรก เลือกตัวเลือกฟิลด์
  • จากรายการชื่อเขตข้อมูล เลือก MergeField
  • ป้อนชื่อสำหรับฟิลด์ผสานใน ชื่อฟิลด์ แล้วกด ตกลง
  • บันทึกเอกสารเป็น DOCX

ต่อไปนี้เป็นภาพหน้าจอของเอกสาร sample template

เทมเพลตคำจดหมายเวียน

สร้างเทมเพลตจดหมายเวียนโดยใช้ Java

คุณยังสามารถสร้างเทมเพลตจดหมายเวียนโดยทางโปรแกรมได้อีกด้วย ต่อไปนี้เป็นขั้นตอนสำหรับมัน

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการสร้างแม่แบบจดหมายเวียนโดยใช้ Java

// สร้างตัวสร้างเอกสาร
DocumentBuilder builder = new DocumentBuilder();

// แทรกฟิลด์ป้อนข้อความ ชื่อเฉพาะของฟิลด์นี้คือ "สวัสดี" ซึ่งพารามิเตอร์อื่นๆ กำหนด
// 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");

ทำ Mail Merge ในเอกสาร Word โดยใช้ Java

เมื่อเทมเพลตพร้อมแล้ว คุณสามารถเติมข้อมูลลงในฟิลด์ผสานได้ ต่อไปนี้เป็นขั้นตอนการดำเนินการจดหมายเวียนบนเทมเพลต Word

  • สร้างเทมเพลตใหม่โดยใช้คลาส Document (หรือโหลดเทมเพลตที่มีอยู่)
  • สร้างอินสแตนซ์ของคลาส DocumentBuilder และส่งวัตถุ Document ไปยังตัวสร้าง
  • ดำเนินการจดหมายเวียนโดยใช้เมธอด Document.getMailMerge().execute() และส่งแหล่งข้อมูลเป็นพารามิเตอร์
  • บันทึกเอกสาร Word ที่สร้างขึ้นโดยใช้เมธอด DocumentBuilder.getDocument().save(String)

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการดำเนินการจดหมายเวียนในเอกสาร Word โดยใช้ Java

// รวมโค้ดสำหรับเทมเพลตของเรา
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

ในตัวอย่างก่อนหน้านี้ เราทำ Mail Merge โดยใช้วัตถุ Java อย่างไรก็ตาม ในกรณีส่วนใหญ่ แหล่งข้อมูลจะถูกใช้เพื่อเติมฟิลด์ผสาน สำหรับการสาธิต มาดูวิธีการใช้แหล่งข้อมูล XML ใน Mail Merge ต่อไปนี้เป็นขั้นตอนสำหรับมัน

  • โหลดแหล่งข้อมูล 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");

// ดำเนินการจดหมายเวียนเพื่อเติมเทมเพลตด้วยข้อมูลจาก XML โดยใช้ DataTable
// โปรดทราบว่าคลาสนี้ยังใช้งานได้กับภูมิภาคเดียวที่ทำซ้ำได้ (และภูมิภาคที่ซ้อนกัน)
// ในการผสานหลายภูมิภาคพร้อมกันจากแหล่งข้อมูล 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");
// ข้อมูลจากแถวของคอลัมน์ "ชื่อลูกค้า" ของตาราง "ลูกค้า" จะไป
// ใน 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();

// เรามีตารางข้อมูลที่สองที่เรียกว่า "คำสั่งซื้อ" ซึ่งมีข้อมูลแบบกลุ่มต่อหนึ่ง
// ความสัมพันธ์กับ "ลูกค้า"
// การเลือกแถวที่มีค่า 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

อีกสถานการณ์หนึ่งที่ได้รับความนิยมใน Mail Merge คือเมื่อคุณมีภูมิภาคที่ซ้อนกัน ตัวอย่างเช่น เมื่อคุณต้องแสดงรายการคำสั่งซื้อและรายการในแต่ละคำสั่งซื้อ คุณสามารถใช้ขอบเขตที่ซ้อนกันได้ ภาพต่อไปนี้ทำให้ภาพชัดเจนยิ่งขึ้นเกี่ยวกับภูมิภาคที่ซ้อนกัน

ในภาพด้านบน เรามีตารางคำสั่งซื้อและตารางรายการที่แต่ละระเบียนในรายการจะเชื่อมโยงกับบันทึกในคำสั่งซื้อ ดังนั้นจึงมีความสัมพันธ์แบบหนึ่งต่อกลุ่มระหว่างสองตารางนี้ ในกรณีดังกล่าว Aspose.Words ดำเนินการจดหมายเวียนโดยดูแลความสัมพันธ์ที่กำหนดไว้ในชุดข้อมูล ตัวอย่างเช่น หากเรามีแหล่งข้อมูล XML แล้ว Aspose.Words จะใช้ข้อมูลสคีมาหรือโครงสร้างของ XML เพื่อค้นหาความสัมพันธ์ ดังนั้น คุณจะไม่ต้องจัดการด้วยตนเอง และเมธอด Document.getMailMerge().executeWithRegions(DataSet) จะทำงานให้คุณ (ตามตัวอย่างก่อนหน้านี้)

ใช้การจัดรูปแบบที่กำหนดเองในฟิลด์ผสาน

เพื่อให้คุณควบคุม Mail Merge ได้มากขึ้น Aspose.Words for Java ให้คุณปรับแต่งฟิลด์ผสานระหว่างการดำเนินการ Mail Merge เมธอด 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");
    }

    /**
     * คืนค่าจริงหากค่าเป็นเลขคี่ เท็จถ้าค่าเป็นเลขคู่
     */
    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;
    }

    /**
     * เมธอดตัวช่วยที่เพิ่มแถวใหม่ที่มีค่าที่ระบุให้กับ a
     * ตัดการเชื่อมต่อ 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();

        // จำเป็นต้องใช้ "การเต้นรำ" นี้เพื่อเพิ่มแถวที่ส่วนท้ายของชุดผลลัพธ์อย่างถูกต้อง
        // ถ้าฉันทำอย่างอื่น แถวจะถูกเพิ่มที่ด้านหน้าหรือผลลัพธ์
        // ชุดแสดงข้อยกเว้นเกี่ยวกับแถวที่ถูกลบระหว่างจดหมายเวียน
        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;
}

บทสรุป

Mail Merge มอบคุณสมบัติที่หลากหลายในการสร้างเอกสาร MS Word แบบไดนามิก คุณสามารถสร้างรายงานที่เรียบง่ายและซับซ้อนโดยอิงจากข้อมูลในฐานข้อมูลหรือแหล่งข้อมูลอื่นๆ ในบทความนี้ คุณได้เห็นวิธีการใช้คุณลักษณะ Mail Merge โดยทางโปรแกรมโดยใช้ Java คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ Java Mail Merge API ได้โดยใช้ เอกสารประกอบ

ดูสิ่งนี้ด้วย