פוסט זה מכסה כיצד לבצע פעולות מיזוג דואר במסמכי MS Word באמצעות Java. בסוף מאמר זה, תלמד כיצד ליצור תבניות מיזוג דואר ולבצע מיזוג דואר באופן תוכנתי.

על מיזוג דואר

מיזוג דואר הוא דרך נוחה להפקת מכתבים, מעטפות, חשבוניות, דוחות וסוגים אחרים של מסמכים באופן דינמי. באמצעות מיזוג דואר, אתה יוצר קובץ תבנית המכיל את שדות המיזוג ולאחר מכן מאכלס שדות אלה באמצעות הנתונים במקור נתונים. נניח שאתה צריך לשלוח מכתב ל-20 אנשים שונים ואתה רק צריך לשנות את השם והכתובת של הכונסים בכל עותק. במקרה זה, תוכל ליצור תבנית מיזוג דואר עבור המכתב ולאחר מכן ליצור 20 אותיות על ידי איכלוס שדות השם והכתובת באופן דינמי.

Java Mail Merge API - הורדה חינם

Aspose.Words for Java הוא ממשק API ידוע לעיבוד תמלילים המאפשר ליצור סוגים שונים של מסמכים מאפס. ה-API מספק תכונות מיזוג דואר מובנות המאפשרות לך ליצור מסמכים באופן דינמי באמצעות תבניות ומקורות נתונים. ניתן להוריד את Aspose.Words עבור 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();

// הכנס שדה קלט טקסט השם הייחודי של שדה זה הוא "שלום", שאר הפרמטרים מגדירים
// איזה סוג של 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");

בצע מיזוג דואר במסמך Word באמצעות Java

לאחר שהתבנית מוכנה, תוכל לאכלס את שדות המיזוג בנתונים. להלן השלבים לביצוע מיזוג דואר בתבנית Word.

דוגמת הקוד הבאה מראה כיצד לבצע מיזוג דואר במסמכי 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");

תבנית

מיזוג דואר פשוט ב-Java

תְפוּקָה

מיזוג דואר פשוט

בצע מיזוג דואר באמצעות מקור נתונים ב-XML

בדוגמה הקודמת, ביצענו מיזוג דואר באמצעות אובייקטי Java. עם זאת, ברוב המקרים, מקור נתונים משמש לאכלוס שדות המיזוג. להדגמה, בואו נבדוק כיצד להשתמש במקור נתונים של XML במיזוג דואר. להלן השלבים עבורו.

  • טען את מקור הנתונים ב-XML באמצעות המחלקה DataSet.
  • טען את תבנית מיזוג הדואר באמצעות המחלקה Document.
  • השתמש בפונקציה execute כדי לאכלס את שדות המיזוג באמצעות טבלת הנתונים הרצויה במקור הנתונים.
  • שמור את מסמך ה-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");
// נתונים משורות של העמודה "CustomerName" בטבלה "Customer" יעברו
// ב-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

תרחיש פופולרי נוסף במיזוג דואר הוא כאשר יש לך אזורים מקוננים. לדוגמה, כאשר אתה צריך לרשום את ההזמנות והפריטים בכל הזמנה אז אתה יכול להשתמש באזורים המקוננים. התמונה הבאה הופכת את התמונה לבהירה יותר לגבי האזורים המקוננים.

בתמונה למעלה, יש לנו את טבלת ההזמנות ואת טבלת הפריטים שבהן כל רשומה ב-Items מקושרת לרשומה ב-Orders. לפיכך, קיים קשר של אחד לרבים בין שתי הטבלאות הללו. במקרים כאלה, Aspose.Words מבצעת את מיזוג הדואר תוך טיפול בקשרים המוגדרים במערך הנתונים. לדוגמה, אם יש לנו מקור נתונים של XML אז Aspose.Words ישתמש במידע הסכימה או במבנה של XML כדי לגלות את הקשרים. לפיכך, לא תצטרך לטפל בזה ידנית בעצמך ושיטה Document.getMailMerge().executeWithRegions(DataSet) תעבוד עבורך (כמו בדוגמה הקודמת).

החל עיצוב מותאם אישית על שדות מיזוג

על מנת לתת לך יותר שליטה על מיזוג הדואר, Aspose.Words עבור Java מאפשרת לך להתאים אישית את שדות המיזוג במהלך ביצוע מיזוג הדואר. השיטה 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 אם הערך הוא אי זוגי; 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");
    }

    /**
     * שיטת עוזר שיוצרת ResultSet ריק עם Java מנותק עם
     * העמודות שצוינו.
     */
    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();

        // ה"ריקוד" הזה נחוץ כדי להוסיף שורות לסוף ערכת התוצאות כראוי.
        // אם אני עושה משהו אחר אז יתווספו שורות או בחזית או בתוצאה
        // set זורק חריג לגבי שורה שנמחקה במהלך מיזוג דואר.
        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 באמצעות תיעוד.

ראה גם