領域を持つネストされたMail Merge

一部のシナリオでは、入れ子になったmail mergeをリージョンで使用する必要がある場合があります。 ネストされたマージは、データソースの階層データをマージテンプレートにマージして、ドキュメントに簡単に入力できる機能です。 基本的に、階層データは一連のデータ項目として表され、階層関係はデータ項目が互いにどのように関連しているかを記述します(データの1つの項目は別の

Aspose.Wordsを使用すると、入れ子になった領域でmail merge操作を実行できます。 この機能は、ツリーのような構造に編成されたデータソースがあり、mail merge操作を実行してテンプレートに階層データを移入する場合に使用できます。

ネストされたMail Mergeとは何ですか

Mail merge領域は、2つ以上のmail merge領域があり、そのうちの1つが階層的な形式で他の領域の中にある場合、ネストと呼ばれます。 各領域には1つのテーブルからのデータが含まれていることに注意してください。

ネストされたmail mergeの最も一般的な例は、多くのデータテーブルをリンクしてテンプレートに情報を提示する必要があるいくつかのアイテムを含む注文です。

下の図は、Ordermail merge領域がItemmail merge領域の親である2つのネストされた領域を示しています。

nested_mail_merge_with_regions

ネストされた領域でMail Mergeを処理する方法

テンプレートにマージされるデータは、主にリレーショナルデータベースやXMLドキュメントなど、さまざまなソースから取得できます。 この例では、次を使用します。 SQLite 私たちのデータを格納し、カスタムデータソースの実装でそれをロードするデータベース。

下の画像は、ネストされたマージ領域に渡されたOrderテーブルからのデータがItemテーブルにリンクされる方法と、マージ操作中に生成された出力を示しています。

mail_merge_with_nested_regions

出力ドキュメントからわかるように、Orderテーブルからの各注文は、Itemテーブルからのすべての注文の関連項目とマージテンプレートに挿入されます。 次の注文は、すべての注文とアイテムが一覧表示されるまで、そのアイテムと一緒に挿入されます。 テンプレート内のリージョンを使用してmail mergeを入れ子にする順序は、データソース内のテーブル間のデータリレーションシップと一致する必要があります。

カスタムデータソースからデータリレーションを作成する方法

カスタムデータソースの親子構造でリレーションシップを作成するには、IMailMergeDataSourceインターフェイスを実装します。 現在の親レコードの関連する子データを返すには、GetChildDataSourceメソッドを使用します。

次のコード例は、入れ子になったmail mergeを使用して請求書を生成する方法を示しています SQLite データベースと SQLiteCpp:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
void NestedMailMerge()
{
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
builder->InsertField(u" MERGEFIELD TableStart:Customers");
builder->Write(u"Full name:\t");
builder->InsertField(u" MERGEFIELD FullName ");
builder->Write(u"\nAddress:\t");
builder->InsertField(u" MERGEFIELD Address ");
builder->Write(u"\nOrders:\n");
builder->InsertField(u" MERGEFIELD TableStart:Orders");
builder->Write(u"\tItem name:\t");
builder->InsertField(u" MERGEFIELD ItemName ");
builder->Write(u"\n\tQuantity:\t");
builder->InsertField(u" MERGEFIELD Quantity ");
builder->InsertParagraph();
builder->InsertField(u" MERGEFIELD TableEnd:Orders");
builder->InsertField(u" MERGEFIELD TableEnd:Customers");
SQLite::Database database((std::string)(DatabaseDir + u"customers.db3"));
// To be able to mail merge from your data source,
// it must be wrapped into an object that implements the IMailMergeDataSource interface.
auto customersDataSource = MakeObject<NestedMailMergeCustom::CustomersDataSource>(database);
doc->get_MailMerge()->ExecuteWithRegions(customersDataSource);
doc->Save(ArtifactsDir + u"NestedMailMergeCustom.CustomMailMerge.docx");
}
class OrdersDataSource : public MailMerging::IMailMergeDataSource
{
public:
OrdersDataSource(SQLite::Database& database, int32_t id)
: mQuery(database, "SELECT ItemName, Quantity FROM Orders WHERE CustomerId = ?")
{
mQuery.bind(1, id);
}
String get_TableName() override
{
return u"Orders";
}
bool GetValue(String fieldName, SharedPtr<Object>& fieldValue) override
{
if (fieldName == u"ItemName")
{
fieldValue = System::ObjectExt::Box<String>(String::FromUtf8(mQuery.getColumn(0).getString()));
return true;
}
if (fieldName == u"Quantity")
{
fieldValue = System::ObjectExt::Box<int32_t>(mQuery.getColumn(1).getInt());
return true;
}
fieldValue.reset();
return false;
}
bool MoveNext() override
{
return mQuery.executeStep();
}
SharedPtr<IMailMergeDataSource> GetChildDataSource(String tableName) override
{
return nullptr;
}
private:
SQLite::Statement mQuery;
};
class CustomersDataSource : public MailMerging::IMailMergeDataSource
{
public:
CustomersDataSource(SQLite::Database& database)
: mDatabase{ database }
, mQuery{ mDatabase, "SELECT * FROM Customers" }
{
}
String get_TableName() override
{
return u"Customers";
}
bool GetValue(String fieldName, SharedPtr<Object>& fieldValue) override
{
if (fieldName == u"FullName")
{
fieldValue = System::ObjectExt::Box<String>(String::FromUtf8(mQuery.getColumn(1).getString()));
return true;
}
if (fieldName == u"Address")
{
fieldValue = System::ObjectExt::Box<String>(String::FromUtf8(mQuery.getColumn(2).getString()));
return true;
}
fieldValue.reset();
return false;
}
bool MoveNext() override
{
return mQuery.executeStep();
}
SharedPtr<IMailMergeDataSource> GetChildDataSource(String tableName) override
{
if (tableName == u"Orders")
{
return MakeObject<OrdersDataSource>(mDatabase, mQuery.getColumn(0).getInt());
}
return nullptr;
}
private:
SQLite::Database& mDatabase;
SQLite::Statement mQuery;
};