Aspose.wordsMailMerge之RegionMailmerge
上⼀篇我⼤致介绍了什么是Mail merge以及怎么通过Aspose使⽤基本的mail merge。本篇将进⼀步讲解它的更强⼤的功能–Region Mail Merge。
在上⼀篇中,我们已经了解到Mail merge可以实现把⽂档⾥的Merge field替换成数据。在最后,我举了个例⼦,讲解了最基本的Mail merge。
那么问题来了:
什么是Region Mail Merge?
它和上⼀篇的实例的区别在哪?
要怎么使⽤Region Mail Merge?
好,带着问题来开始往下看吧。
什么是Region Mail Merge
Region Mail Merge,翻译成中⽂的意思差不多是:区域邮件合并。先根据字⾯意思猜下⼤概是:选择⽂
档的部分区域进⾏邮件合并。OK,其实根据字⾯意思猜的是正确的。
不过在Aspose官⽹,它给出的例⼦往往会误导读者,以为Region Mail Merge是⽤来重复添加数据的。
举个例⼦来讲,如下图是模板⽂档:
然后它的最后Mail merge结果是:
上⾯的图⽚就是官⽹的图⽚,从图⽚和⽂字表述中,我得出Region Mail Merge就是区域重复Merge。葡萄种植技术
事实上,我的这个最初的理解是错误的。重复这个概念是⼀直存在于Mail merge的。也就是说,默认就有重复这个技能。
我们再回到上⼀篇的例⼦来看看。
在上⼀篇中,我有提到moveNext,这个是⽤来决定需要重复⼏次merge。
OK,我们就来重复⼀下看看,我把moveNext的代码稍作修改:
class MyMailMergeDataSource implements IMailMergeDataSource {
int index = 0;
boolean once = true;
int repeatCount = 2;
......
@Override
public boolean moveNext() throws Exception {
if (repeatCount > 0) {
repeatCount--;
index = 0;
return true;
}
return false;
}
代码很简单,我们直接看效果:
下⾯看不到,只能截取部分,不过不影响,⾄少看到重复的效果了。
从这个结果,不难退出,它的重复是针对整个⽂档的。我们可以对照看下DOM树:
OK,产⽣了两个Section,也就是说是针对整个Section重复的。 阿尼
看到这⾥,就很清晰了,重复的概念是⼀直存在的。那官⽹给的⿁讲解,⿁例⼦是⼲嘛呢!
扯远了~~,继续往下。莫少聪老婆
使⽤Region Mail Merge
既然已经清楚了Region Mail Merge的功能,那么我们就可以开⼯了。
⽐⽅说现在头给你了个任务,需要创建⼀个⽂档,它需要某部分区域重复的添加很多相同类型的数据,就如我上⾯贴的官⽹的那两张图⽚。
那么要怎么弄呢?还是和上篇讲的流程⼀样,先是创建模板。
创建模板
那怎么创建模板呢?既然是区域Mail Merge,那肯定需要标识符吧。
对的!区域mail merge,需要在模板⾥建⽴标识符,这样Aspose才能识别出来。标识符就是TableStart:XXX和TableEnd:XXX,这个XXX指的是TableName,如果上⼀篇看得仔细,那可能会联想到有个⽅法getTableName,对了,就是那个。TableName前后要⼀致。
很简单吧,我就直接上图了:
这⾥,我限定了两个区域。
第⼀个是在第⼀个表格的⼀⾏数据⾥。它的TableName是NormalTable。
第⼆个是包含整个表格。它的TableName是XTable。
这⾥需要指出的是,Aspose⾥虽然取名叫TableName,但实际上它不单单只能使⽤在表格上,它可以使⽤在任何你想限定的区域,只要在同⼀个Section⾥,不要被我的例⼦给忽悠了。我只是举了个表格
的例⼦
然后在这些限定区域⾥,我都创建了四个Merge field。偷懒了,上⾯的和下⾯的都⼀样的。
这⾥需要指出⼀下TableStart和TableEnd标识符的使⽤范围。照片大小怎么改到20k
这两个标识符必须在同⼀个Section⾥。正常情况下,我们的⽂档只有⼀个Section,除⾮像我上⾯尝试修改的例⼦的那样,才会出现两个或多个Section。
如果标识符定义在表格⾥,那它们必须在同⼀⾏⾥。
标识符可以嵌套使⽤。这个在后⾯会再讲。
标识符要成对出现,并且它们的名称要⼀致。
ok,模板已经创建完了。接着就是写代码了。
代码实现
在官⽹,它给的介绍和例⼦都是涉及到java的数据库的,这个数据库在android端是⽆法使⽤的,所以对我们Android开发没有⽤。不过,我会稍微讲下,过⼀遍。
要执⾏区域邮件合并,需要⽤到MailMerge().executeWithRegions()这个⽅法。它接受如下数据类型。
IMailMergeDataSource我们已经了解了,那么其他⼏个呢?官⽹只讲了上⾯两个,也对,第三个在最基本的Mail merge已经涉及到过。java端的数据源
DataSet
涂议嘉抄袭
说到这个,我们还要从ResultSet说起。使⽤过java的数据库的猿们肯定知道ResultSet,没错,它是java.sql.ResultSet,是个接⼝。它是⽤来访问数据库表⽤的。
那DataSet和ResultSet什么关系呢?好吧,我们还要从DataTable说起。DataTable是Aspose⾥的,它抽象成数据表。然后
呢,DataTable包含⼀个ResultSet。
⽽DataSet可以包含多个DataTable。也即是说,DataSet⾥包含了多个区域需要Merge的数据源。
DataTable
上⾯讲到,DataTable⾥包含ResultSet。并且DataTable就是⼀个区域的数据源。也即是说,DataTable⾥维护⼀个TableName,定义它所属的是哪个Region。
ok,这两个的基本概念就是这样。它们是⽤来把数据库⾥的数据抽象到区域Mail merge的数据源。我贴些代码⽰例:
public void executeWithRegionsDataTable() throws Exception
{
Document doc = new Document(getMyDir() + "MailMerge.ExecuteWithRegions.doc");
int orderId = 10444;
// Perform several mail merge operations populating only part of the document each time.
// Use DataTable as a data source.
// The table name property should be set to match the name of the region defined in the document.
com.aspose.words.DataTable orderTable = getTestOrder(orderId);
com.aspose.words.DataTable orderDetailsTable = getTestOrderDetails(orderId, "ExtendedPrice DESC");
doc.save(getMyDir() + "MailMerge.ExecuteWithRegionsDataTable Out.doc");
}
private static com.aspose.words.DataTable getTestOrder(int orderId) throws Exception
{
java.sql.ResultSet resultSet = MessageFormat.format(
"SELECT * FROM AsposeWordOrders WHERE OrderId = {0}", String(orderId)));
return new com.aspose.words.DataTable(resultSet, "Orders");
}
private static com.aspose.words.DataTable getTestOrderDetails(int orderId, String orderBy) throws Exception
{
StringBuilder builder = new StringBuilder();
builder.MessageFormat.format(
"SELECT * FROM AsposeWordOrderDetails WHERE OrderId = {0}", String(orderId)));
if ((orderBy != null) && (orderBy.length() > 0))
{
builder.append(" ORDER BY ");
builder.append(orderBy);
}
java.sql.ResultSet resultSet = String());
return new com.aspose.words.DataTable(resultSet, "OrderDetails");
溜冰鞋十大品牌
}
/**
* Utility function that creates a connection, command,
* executes the command and return the result in a DataTable.
*/
private static java.sql.ResultSet executeDataTable(String commandText) throws Exception
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");// Loads the driver
// Open the database connection.
String connString = "jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb)};" +