Mail Merge С региони

Можете да създадете различни региони във вашия шаблон, за да има специални области, които можете просто да попълните с вашите данни. Използвайте Mail Merge С региони, ако искате да вмъкнете таблици, редове с повтарящи се данни, за да направите документите си динамично да растат, като зададете тези региони във вашия шаблон.

Можете да създавате вложени (Детски) региони, както и да обединявате региони. Основното предимство на използването на този тип е динамично увеличаване на частите вътре в документа. Вижте повече подробности в следващата статия “вложени Mail Merge С региони”.

Как да се изпълни Mail Merge С региони

Mail Merge регион е специфична част в документ, която има начална и крайна точка. И двете точки са представени като Mail Merge полета, които имат конкретни имена “TableStart:XXX” и “TableEnd:XXX”. Цялото съдържание, включено в регион Mail Merge, ще се повтаря автоматично за всеки запис в източника на данни.

Aspose.Words ви позволява да изпълнявате Mail Merge с региони, като използвате един от методите ExecuteWithRegions, които приемат IMailMergeDataSource потребителски източник на данни.

Следващият пример за код показва как да се изпълни Mail Merge с региони от базата данни с 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;
};

Можете да забележите разликата между документа, преди да изпълните Mail Merge С региони:

mail_merge_with_regions_template

И след изпълнение Mail Merge С региони:

mail_merge_with_regions_execute

Ограничения на Mail Merge С региони

Има някои важни точки, които трябва да имате предвид при извършване на Mail Merge С региони:

  • Началната точка TableStart:Orders и крайната точка TableEnd:Orders трябва да бъдат в един и същ ред или клетка. Например ако стартирате област за обединяване в клетка на таблица, трябва да завършите областта за обединяване в същия ред като първата клетка. Името на полето за обединяване трябва да съответства на името на колоната във вашето DataTable. Освен ако не зададете нанесени полета, Mail Merge С региони няма да успее за всяко Обединено поле, което има име, различно от името на колоната.
  • Aspose.Words за C++ поддържа само IMailMergeDataSource и IMailMergeDataSourceRoot базирани източници на данни. За разлика от .NET и Java, C++ няма общоприета междуплатформена API за работа с бази данни (като ADODB, ODBC или JDBC). За да работите с конкретен източник на данни, трябва да внедрите интерфейс IMailMergeDataSource или IMailMergeDataSourceRoot.

Ако някое от тези правила е нарушено, ще получите неочаквани резултати или може да се хвърли изключение.