您的位置:首页 > 编程语言 > ASP

Aspose.words Mail Merge初识

2015-09-09 11:07 681 查看
转载请注明:

/article/1363986.html

上一篇Aspose.words编程指南之DocumentBuilder二我把DocumentBuilder给收尾了。通过前面几篇的介绍,同志们应该对Aspose.words有了一定的了解,并且可以实现基本的文档了。但是,事实上,我们在产生文档时,一般不是通过代码一行行去写的,这样会吐血生亡的。我们一般是通过事先准备好的一些文档模板,在这些基础上进行替换改变来产生文档。本篇开始,就来讲解下office里很重要的一个特性:Mail Merge怎么通过Aspose.words来实现。

什么是Mail merge

常常用office生成大量文档的同志们肯定或多或少接触过Mail merge。MailMerge中文翻译过来是:邮件合并。

那么它是干啥的?其实它的用途可大了。

如果你是文秘人员,那么常常会遇到用一个模板生成多个\多份文档、邮件、通知的情况,文档中除了个别关键字字段(如,名字、编号、或者日期等),其余内容都是同样的。这种情况下,如果单个生成文档(打开,添加/修改关键字段,保存),则费时费力,而且容易出错。

Mail Merge就是给上述情况带来福音的。该功能允许一个文档模板从一个数据源中提取关键字段,替换模板中的内容,生成多个文档。特别适用于通知、群发邮件、证书的生成。这个数据源可以是Excel,可以是Access数据库。

那么问题来了,在Aspose.words里是否也支持Mail Merge呢?答案是肯定的,但是!有一些功能没有,也就是只支持绝大部分。不过它支持的功能够我们用了就行。

Aspose Mail Merge

Aspose里的Mail Merge在android平台支持的功能是最少,其他平台都多一些,不过一般够我们开发使用了。

它同office一样,也需要一个模板,这个模板的格式不定,可以是doc、rtf、docx等等。

它的数据源就多了,可以是数据库里的,可以是文件里的,可以是动态获取的,等等等等。

基本步骤

在Android端执行一个Mail merge的步骤大致分为4步:

1.需要提供模板,这个模板你可以通过代码去实现,也可以通过offce或者WPS去做好,格式可以随你定。

2.在这些模板里,把想插入数据的地方用Merge Field插入。

3.在代码端加载你需要使用的模板,然后执行Mail Merge操作。它会把你指定的数据和指定的Merge field进行替换。

4.保存文档,格式随你定。

IMailMergeDataSource

在写代码之前,需要先讲下这个接口。从字面上的意思可以猜到,这个接口是用来给Mail merge提供数据的。

事实上也是如此,你要实现一个稍微复杂一点的Mail Merge,一般是要涉及到这个接口。

当然,不用到它也是可以的,如下代码展示了最简单的情况:

// Open an existing document.
Document doc = new Document(getMyDir() + "MailMerge.ExecuteArray.doc");

// Fill the fields in the document with user data.
doc.getMailMerge().execute(
        new String[] {"FullName", "Company", "Address", "Address2", "City"},
        new Object[] {"James Bond", "MI5 Headquarters", "Milbank", "", "London"});

doc.save(getMyDir() + "MailMerge.ExecuteArray Out.doc");


如果你的需求只限于这样,那用这个就够了。但事实上,我们常常遇到的情况是,某些Merge field要插入的数据有多行,还有要插入一些图片。这样的话,这个方案就不行了。

好,我们继续看IMailMergeDataSource。

我们实现这个接口之后,会发现有四个方法需要实现。我分别来讲下:

getTableName()

Aspose使用这个name去和Mail Merge的Region name去匹配,一样就用这个数据源。只有用到Mail merge的region时才需要设置。

getChildDataSource

这个,顾名思义是子数据源的意思,在嵌套mail merge里要用到。

getValue

它是用来把merge field和数据关联的。这个方法很重要,它有两个参数String field和Object[] objects。第一个参数是Merge field的名称,第二个参数是传给这个merge field的数据。

moveNext

这个是用来决定需要重复几次merge。

看到这里,估计很多童鞋们还是有点不懂。没事,接下去通过代码再来讲解一下。

实例

我们首先需要一个模板,这里,我自己随便用WPS编辑了个模板,上图:



从图中可以看到一些带尖括号的字段,这些就是Merge field,中文翻译一下就是合并域。

我可以通过alt+f9查看它的详细代码:



如果Merge field这块不是很了解的朋友,可以网上去找些相关资料补补。

接着,开始写代码了。

public class MailMergeActivity extends FragmentActivity {
    ......
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mail_merge);

        new Thread(new MailMergeTask()).start();
    }

    private class MailMergeTask implements Runnable {

        @Override
        public void run() {
            try {
                Document doc = new Document(MyApplication.filePath
                    + File.separator + "TestMailMerge.doc");
                doc.getMailMerge().execute(new MyMailMergeDataSource());
                doc.save(MyApplication.filePath + File.separator
                        + "MailMergeActivity.doc");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


先是加载一个模板,我传的是一个字符串,指向的是sd卡某个文件夹里的TestMailMerge.doc。

然后通过doc.getMailMerge().execute()这个方法来执行Mail merge。

我们接着看下MyMailMergeDataSource的实现:

public class MailMergeActivity extends FragmentActivity {
    private static final String[] DATAS = new String[] {
            "职工", "身体不适,在住院", "10", "领导", 
            "隔壁老王", "2015", "09", "09"
    };
    ......

    class MyMailMergeDataSource implements IMailMergeDataSource {
        int index = 0;
        boolean once = true;

        @Override
        public String getTableName() throws Exception {
            return null;
        }

        @Override
        public boolean moveNext() throws Exception {
            if (once) {
                once = !once;
                return true;
            }
            return false;
        }

        @Override
        public boolean getValue(String field, Object[] objects) throws Exception {
            if (field.equals("Image")) {
                Bitmap bitmap = MyApplication.decodeSampleBitmapResource(
                        getResources(), R.drawable.a, 200, 300
                );
                objects[0] = bitmap;

            }else {
                objects[0] = DATAS[index++];
            } 
            return true;
        }

        @Override
        public IMailMergeDataSource getChildDataSource(String s) throws Exception {
            return null;
        }
    }
}


稍微来分析下代码。我偷懒创建了一个静态的字符串数组。

然后在实现接口里,配了两个变量:index和once。一个是用来做静态数组的游标,另一个是用来限制这次merge的重复次数。我这里设置只merge一次。

这里,不涉及regions mail merge和嵌套mail merge,所以getTableName和getChildDataSource都返回null就行了。

最后的结果如下:



这样,Mail merge就完成了。这里只是merge一次,如果是多次的话,就会有很多同样内容的出现。

说好的图片呢?别急,这只是给你看下直接附bitmap给object会发生什么现象。下一篇Aspose.words Mail Merge之Region Mail merge将讲解区域邮件合并,有兴趣就点吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: