Zagnieżdżone Mail Merge z regionami

W niektórych scenariuszach może być konieczne użycie zagnieżdżonego Mail Merge z regionami. Zagnieżdżone scalanie to funkcja, która umożliwia scalanie danych hierarchicznych ze źródła danych do szablonu scalania w celu łatwego zapełnienia dokumentu. Zasadniczo dane hierarchiczne są reprezentowane jako zestaw elementów danych, a relacje hierarchiczne opisują, w jaki sposób elementy danych są ze sobą powiązane (jeden element danych jest rodzicem innego).

Aspose.Words umożliwia wykonanie operacji Mail Merge z zagnieżdżonymi regionami. Możesz użyć tej funkcji, jeśli masz źródło danych zorganizowane w strukturę podobną do drzewa i chcesz wykonać operację Mail Merge, aby wypełnić szablon danymi hierarchicznymi.

Co to jest zagnieżdżone Mail Merge

Region Mail Merge jest nazywany zagnieżdżonym, jeśli masz dwa lub więcej regionów Mail Merge, w których jeden z nich znajduje się wewnątrz drugiego w formie hierarchicznej. Zauważ, że Każdy region zawiera dane z jednej tabeli.

Najczęstszym przykładem zagnieżdżonego Mail Merge jest kolejność zawierająca kilka elementów, w których należy połączyć wiele tabel danych i przedstawić informacje w szablonie.

Poniższy rysunek pokazuje dwa zagnieżdżone regiony, w których region Order Mail Merge jest rodzicem regionu Item Mail Merge.

nested_mail_merge_with_regions

Jak przetwarzać Mail Merge z zagnieżdżonymi regionami

Dane do scalenia w szablon mogą pochodzić z różnych źródeł, głównie relacyjnych baz danych lub dokumentów XML. W naszym przykładzie użyjemy SQLite baza danych do przechowywania naszych danych i ładowania ich za pomocą niestandardowej implementacji źródła danych.

Poniższy obrazek pokazuje, w jaki sposób dane z tabeli Order przekazane do zagnieżdżonych regionów scalania zostaną połączone z Tabelą Item, a także dane wyjściowe wygenerowane podczas operacji scalania.

mail_merge_with_nested_regions

Jak widać z dokumentu wyjściowego, każde zamówienie z tabeli Order jest wstawiane do szablonu scalania ze wszystkimi powiązanymi elementami zamówienia z tabeli Item. Następne zamówienie zostanie wstawione wraz z ich pozycjami, aż wszystkie zamówienia i pozycje zostaną wyświetlone. Kolejność zagnieżdżania Mail Merge z regionami w szablonie musi być zgodna z relacjami danych między tabelami w źródle danych.

Jak tworzyć relacje danych z niestandardowego źródła danych

Zaimplementuj interfejs IMailMergeDataSource, aby tworzyć relacje w strukturze rodzic-dziecko niestandardowego źródła danych. Użyj metody GetChildDataSource, aby zwrócić odpowiednie dane potomne bieżącego rekordu nadrzędnego.

Poniższy przykład kodu pokazuje, jak wygenerować fakturę za pomocą zagnieżdżonego Mail Merge z regionami z SQLite baza danych z 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;
};