一种多源数据引入数据模板的方法和装置
技术领域
本发明涉及一种多源数据引入数据模板的方法和装置,属于计算机信息处理技术领域。
背景技术
数据模板生成方法总体上可以分为两种类型。一种是静态数据。这类数据模板的布局样式和数据都是静态的,在利用生成工具设计数据模板时,直接将数据填入数据模板,得到的就是最终的结果。另一种是动态数据。这类数据模板布局样式和数据都是动态的,在利用生成工具设计数据模板时,填入的是数据引用,得到的是中间结果,运行时需要动态地从数据库等不同类型数据源中获取数据,并将组织好的数据自动填入数据模板,得到最终结果。
在动态数据模板生成方法中,主要基于两种模型:基于条带模型和基于网格模型。基于条带模型的数据模板生成方法,又称作控件模型(由基本控件堆砌而成),脱胎于西式数据模板,这种模型在处理一些布局不规则、样式复杂、引用计算关系复杂、非线性的具有中国特色的数据模板时会遇到较多的问题。基于网格模型的数据模板生成方法是对条带模型的改进,结合了中式数据模板的一些特点,在多数据来源、不规则的网格布局、列方向扩展等方面都提出了很好的解决方案。
本发明主要针对基于网格模型的动态数据模板。
对于复杂的中式数据模板来说,很多情况下数据来自于多个数据源(以下简称多源数据),无法简单的使用单一的数据模型(例如交叉模型)来解决。也就是说,从一个局部区域来看数据模板是规则的,可以归纳为某一种数据模型来处理,但是从整体来看数据模板是不规则的,用任何一种单一数据模型都无法处理。简称为:局部规则、整体不规则。
处理这类问题,传统方法有二种:
1.在主数据模板中引入子数据模板。
将某一个规则的区域当做单独的数据模板来设计,设计完成后将子数据模板嵌入主数据模板的某个单元格(指行列网格线交叉形成的最小单位矩形区域)或矩形区域。但是由于子数据模板和主数据模板高度独立,子数据模板的填充数据是运行时从数据源中动态获得,具有不确定性,会导致数据模板之间丢失原先存在的数据关联性和布局关联。
数据关联性,指的是两个数据模板之间具有一定的逻辑关系,两者的数据需要保持某种一致性。例如,数据模板A展示某公司的人事数据,而数据模板B展示该公司的财务数据,要求具有对应关系的人事和财务数据必须在一行上。在传统的数据模板引入方法中,如果数据源中保存了12个人的人事和财务信息,数据模板A按工号排序获取人事数据,数据模板B按银行卡号排序获取财务数据,当两个数据模板组合到一起之后,人事数据和财务数据的对应关系就乱了。
布局关联,指的是两个数据模板的位置关系需要保持某种一致性。例如数据模板设计时,数据模板A和数据模板B都是5行,在填充数据扩展完成之后,要求数据模板A和数据模板B的行数还是保持一致。在传统的数据模板引入方法中,如果数据模板A从数据源中获取了12条数据,数据模板B从数据源中获取了6条数据,这样数据模板B的下方就会出现6行的空白区域,破坏了数据模板整体布局的一致性。
此外,传统的多源数据引入方法还会导致原有的样式遭到破坏,例如网格线不对齐、行列数不一致等。甚至可能影响导出等数据模板的再利用功能,例如网格线对不齐的数据模板很难导出到Excel。
2.将焦点聚焦到单元格(指行列网格线交叉形成的最小矩形区域)。
打碎数据模型的概念,将数据模型的属性转移到单元格上,通过单元格的设置来完成整个数据模板的设计。这种方法虽然灵活性较高,但是降低了数据模板抽象程度,关注点太过于细节化,使数据模板设计繁琐化,即使一个简单的数据模板也需要设计大量的单元格属性,增加了数据模板设计的工作量,并且这种方法增加了数据源与数据模板扩展算法之间的耦合度。此外,这种方法仍然有破坏原有数据模板布局的可能。
发明内容
本发明的目的就是针对上述的不足,提供了一种新型的多源数据引入数据模板的方法,以处理局部规则、整体不规则的数据模板。针对传统处理方法的缺陷,本发明解决多源数据的引入对数据模板整体布局的破坏问题,实现数据模板间的布局对齐和数据关联性,提高数据模板的灵活性和可扩展性。
本发明提供的多源数据引入数据模板的方法基于复合型数据模板实现。复合型数据模板包括若干个子数据模板,每个子数据模板可归纳为某种单一数据模型,每个子数据模板的数据来自于不同的数据源。与传统的多源数据引入方法不同的是,复合型数据模板中所有的子数据模板都是平等的地位,没有主次之分。复合型数据模板本身相当于一张空白的网格画布,每个子数据模板都在这张画布的某个特定矩形区域内绘制,复合型数据模板只需要保存子数据模板之间的位置关系即可。
本发明引入职责链模式处理子数据模板之间的数据关联性,职责链模式是一种对象行为模式[GOF95]。在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。职责链可能是一条直线、一个环或者一个树结构的一部分。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配职责。
职责链模式本身并不创建出职责链,需要由复合型数据模板处理器来创建。复合型数据模板内的所有子数据模板的处理器,都看作是职责链上的一个对象节点,由复合型数据模板处理器按一定的次序组装成一条职责链。每个对象节点的职责,除了要处理子数据模板本身的扩展算法,还要处理与其他子数据模板的数据关联关系。
本发明提供的多源数据引入数据模板的方法,包括如下步骤:
1)复合型数据模板处理器创建子数据模板职责链,即提供扩展机制,可以通过灵活的配置来动态地重新组织链和分配职责;
2)复合型数据模板处理器从数据源获取原始数据,复合型数据模板处理器只在一开始与源数据交互一次,在处理器生成数据模板的过程中不再与源数据交互;
3)复合型数据模板处理器根据子数据模板N的数据关联(1<=N<=Max,Max为子数据模板个数)处理原始数据,生成子数据模板N实际的业务数据,设置数据关联属性后,这两个子数据模板的扩展区域内的匹配记录将相对各自扩展区域的起点产生相同的位置偏移。子数据模板数据关联后,可以设置基于整个连接结果集的字段排序、分组设置,这时各个子数据模板内的排序、分组设置不再生效;
4)复合型数据模板处理器将业务数据传入子数据模板N对应的单一数据模型处理器,由于传入子数据模板处理器的数据是处理过数据关联之后的业务数据,对子数据模板处理器本身来说,不用关心与其他子数据模板的数据关联关系,所以不会对子数据模板处理器本身的算法造成任何影响。一旦某一个子数据模板的扩展算法发生问题,可以很方便的使用本发明提供的扩展机制来替换;
5)单一数据模型处理器来填充数据,扩展生成子数据模板N;
6)循环步骤3)-5)步,按职责链的顺序依次处理每一个子数据模板,直到最后一个子数据模板处理完(N>Max);
7)复合型数据模板处理器对所有子数据模板重新排序,由于子数据模板处理器并不关心复合型数据模板的布局,而扩展后的子数据模板与扩展前相比,位置和大小都发生了变化,所以需要重新对复合型数据模板中的所有子数据模板排序,以便于处理数据模板的布局,即子数据模板之间的位置关系。排序的基本原则是:取子数据模板左上角单元格坐标;先比较行值,行值较小的排在前边;对于行值相同的,比较列值,列值较小的排在前边。有一种特例:对于有列方向扩展的子数据模板T1,如果子数据模板T2在T1的右边,即使T2的行号较小,也需要将T1排在T2的前面;
然后按排序后的顺序将所有子数据模板填充到复合型数据模板中,并依次处理子数据模板的布局关联,调整子数据模板的位置和大小。子数据模板设置高度对齐后,实际填充数据完成扩展后两个子数据模板的下边界位于同一行上,对于宽度对齐与此类似,实际填充数据完成扩展后,扩展后子数据模板的右边界位于同一列上。
上述步骤1)中所述的职责链上的每个节点的职责为:处理子数据模板本身的扩展算法和处理与其他子数据模板的数据关联关系。
上述步骤2)中的数据源包括数据库、Java对象、文本文件、XML文件以及自定义数据等等。
上述步骤3)中所述子数据模板数据关联包括如下方式:内连接(只显示关联匹配数据)、左外连接(完整显示左表数据、右表不匹配数据以空或指定符号代替)、右外连接(完整显示右表数据、左表不匹配数据以空或指定符号代替)、全外连接(完整显示左表、右表数据,不匹配数据以空或指定符号代替)。
上述步骤7)中所述子数据模板布局关联是通过设置子数据模板对齐属性实现的,子数据模板对齐包括高度对齐和宽度对齐。
上述步骤7)中按排序后的顺序处理每个子数据模板的布局关联,调整子数据模板的大小是通过如下步骤实现的:通过子数据模板对齐设置扩展“真空”区域的填充方式,包括扩展区域单元格填充、末行/列合并、起始格合并、等分行/列合并,其中,
扩展区域单元格填充是以子数据模板扩展区域的单元格形式填充新扩充的扩展“真空”区域,直至与另一子数据模板对齐;
末行/列合并是将最后扩展的行/列演变为合并单元格进而向下/右进行合并处理;
起始格合并是将所有扩展“真空”区域合并为一个大的合并单元格;
等分行/列合并是将新区域等分为几段,然后分别合并。
实现上述方法的多源数据引入数据模板德装置,包括:
一复合型数据模板,包括至少两个单一数据模型的子数据模板,所有子数据模板地位平等,且来自同一或不同的数据源;
一复合型数据模板处理器,用于职责链的创建、组装和消息传递,并负责把若干个子数据模板组装成一个复合型数据模板。
本发明提供的多源数据引入数据模板的方法,具有如下优点:
1.复合型数据模板的优点:
1)由于每个子数据模板都是基于复合型数据模板提供的网格画布,所以不会出现网格线对不齐等布局问题。
2)每个子数据模板只在其本身所属矩形区域内绘制,各子数据模板之间相对独立,可以采用合适的单一数据模型算法。
3)复合型数据模板内保存了子数据模板之间的位置关系,可以方便的处理子数据模板之间的布局关联,保持数据模板整体布局的一致性。
2.引入职责链模式的优点:
1)由于职责链上的对象节点之间是松耦合的,所以在解决了子数据模板的数据关联性问题的同时,子数据模板之间仍然是相对独立的,并没有增加其耦合度。
2)由于可以动态地重新组织链和分配职责,数据模板的灵活性和可扩展性大大提高。即使是数据模板生成工具暂未实现的数据模板模型,也可以通过灵活的配置来引入其他的解决方案,而不影响数据模板生成工具本身。
3)数据只作为输入参数,在生成数据模板的过程中不再与数据源交互,实现了数据源与业务逻辑的解耦。
即引入多源数据后不会影响复合型数据模板整体布局,不会影响子数据模板之间的数据关联性,复合型数据模板样式不因扩展而破坏,例如网格线对齐等,且可扩展性强,可以灵活配置子数据模板的处理器,实现了数据层与业务逻辑层的解耦。
附图说明
图1是本发明实施例中复合报表设计流程图;
图2是本发明实施例中引入子报表的流程图;
图3是本发明实施例中扩展导致真空区域的示意图;
图4是本发明实施例中复合报表设计状态参考图;
图5是本发明实施例中传统方法效果图;
图6是本发明实施例中扩展区域单元格填充效果图;
图7是本发明实施例中末行/列合并效果图;
图8是本发明实施例中起始格合并效果图;
图9是本发明实施例中等分行/列合并效果图。
具体实施方式
报表是数据模板的一种实例,下面以报表为例子对本发明的实施方式进行进一步解释、说明。其中,复合报表即为复合型数据模板的实例。
一种多源数据引入数据模板的方法,即一种子报表引入方法。一般来说需要首先对复合报表进行设计,这是容易实现的。
如图1所示,为复合报表设计的流程图。该流程开始于步骤101,选择复合报表模型,创建空白报表;报表模型是预先抽象好的,用户可以直接选择,并且在报表设计阶段也可以更改。
然后进入步骤102,根据报表局部规则性,建立多个子报表,即在一个报表中根据局部规则性建立多个子报表,每个子报表属于某种单一报表模型。
在建立子报表后,再进入步骤103,建立数据集,将相应数据集绑定到子报表中;数据集可以是多个,并且能够来自不同的数据源,包括但不仅限于数据库、Java对象、文本文件、XML文件以及自定义数据等。数据集的字段除从数据源直接获得外,并且能够通过其他字段计算获得(称为计算字段),以及自动生成获得(称为追加字段,比如序号生成,以及字段拼接等)。
在步骤104中检查是否还有其他未创建子报表,如果为是,则回到步骤102;如果为否,则进入下一步骤。
所谓绑定就是将数据集的字段设置到子报表所属的扩展区域中,扩展区域由子报表内的连续单元格组成,每个单元格和某一个字段建立一一对应的关系。同时设置扩展区域的扩展属性,包括扩展方向、扩展次数等。能够设置向下(行方向)、向右(列方向)扩展或交叉(行列方向同时)扩展,以及最少扩展次数、最大扩展次数等。
步骤104检查结果为是,进入步骤105,根据子报表间数据的业务关联关系,设置子报表数据关联;根据子报表间数据的业务关联关系,设置两个子报表间的数据关联。子报表数据关联的匹配类似SQL的内外连接,这种关联分为内连接(只显示关联匹配数据)、左外连接(完整显示左表数据、右表不匹配数据以空或指定符号代替)、右外连接(完整显示右表数据、左表不匹配数据以空或指定符号代替)、全外连接(完整显示左表、右表数据,不匹配数据以空或指定符号代替)4种方式。子报表间通过连接字段建立关联。一个子报表可以与多个子报表建立数据关联,并且连接字段不必强制绑定到报表中。
设置完成数据关联后,再设置子报表布局关联;即为保证报表整体布局的完整性,可以设置子报表对齐属性。该属性能够保证子报表数据集在填充数据形成实际报表后,仍然能够保持相互间设置的对齐关系,避免出现因为扩展而导致的报表“真空”区域。子报表对齐包括:高度对齐、宽度对齐2种方式。子表起始位置位于不同列上的子报表能够设置高度对齐属性,不同行上的子报表能够设置宽度对齐属性。同一子报表能够同时和不同的两个子报表分别设置高度对齐、宽度对齐属性。
完成上述步骤后,进入步骤106,将结果保存到报表模板,即完成了复合报表的设计。
完成复合报表的设计后,即进入本发明的引入子报表的步骤,具体来说如图2所示,包括:
本流程开始于步骤200,读取报表模板并初始化。
然后进入步骤201,处理表头,即标题区域。
然后进入步骤202,初始化复合报表处理器,并创建子报表职责链,即提供扩展机制,可以通过灵活的配置来动态地重新组织链和分配职责。
完成上述步骤后进入步骤203,从数据源获取原始数据,传入复合报表处理器,复合报表处理器只在一开始与源数据交互一次,在处理器生成报表的过程中不再与源数据交互。
然后进入步骤204,按职责链顺序处理每个子报表。
再进入步骤205,根据子报表N的数据关联(1<=N<=Max,Max为子报表个数)处理原始数据,生成子报表N实际的业务数据。设置数据关联属性后,这两个子报表的扩展区域内的匹配记录将相对各自扩展区域的起点产生相同的位置偏移。子报表数据关联后,可以设置基于整个连接结果集的字段排序、分组设置,这时各个子报表内的排序、分组设置不再生效。
例如,子报表A展示某公司的人事数据,而子报表B展示该公司的财务数据,在传统的子报表引入方法中,子报表A按工号排序获取人事数据,子报表B按银行卡号排序获取财务数据,这样人事数据和财务数据的对应关系就乱了。如果子报表A和子报表B之间设置了数据关联,以工号为关联字段的全外连接,并按照工号排序。那么,子报表A和子报表B都按照工号排序,同一个人的人事和财务信息都在同一行上,对于只在一个子报表中存在的信息,则另一个报表中以空行显示。
然后开始步骤206,将业务数据传入子报表N的处理器。由于传入子报表处理器的数据是处理过数据关联之后的业务数据,对子报表处理器本身来说,不用关心与其他子报表的数据关联关系,所以不会对子报表处理器本身的算法造成任何影响。一旦某一个子报表的扩展算法发生问题,可以很方便的使用本发明提供的扩展机制来替换。
然后进入步骤207,填充数据,扩展生成子报表N。
然后进入步骤208,由于需要循环直到最后一个子报表处理完(N>Max),故如果没有完成整个循环则回到步骤204;如果循环结束,则进入下一步骤。
步骤208循环完成后进入步骤209,对所有子报表重新排序。由于子报表处理器并不关心复合报表的布局,而扩展后的子报表与扩展前相比,位置和大小都发生了变化,所以需要重新对复合报表中的所有子报表排序,以便于处理报表的布局,即子报表之间的位置关系。排序的基本原则是:取子报表左上角单元格坐标;先比较行值,行值较小的排在前边;对于行值相同的,比较列值,列值较小的排在前边。有一种特例:对于有列方向扩展的子报表T1,如果子报表T2在T1的右边,即使T2的行号较小,也需要将T1排在T2的前面。
然后进入步骤2010,按排序后的顺序将所有子报表填充到复合报表中,调整子报表位置。
再开始步骤2011、2012,按排序后的顺序处理每个子报表的布局关联,调整子报表的大小。子报表设置高度对齐后,实际填充数据完成扩展后两个子报表的下边界位于同一行上,对于宽度对齐与此类似,实际填充数据完成扩展后,扩展后子报表的右边界位于同一列上。
例如,如图3所示,起始位置位于同一行的两个子报表,一个扩展了6行,一个扩展了12行。如果是传统的子报表引入方法,没有子表对齐属性,将会在扩展了6行的子报表下方出现6行的扩展“真空”区域,这部分区域没有任何设置,将破坏报表的整体布局。
子报表对齐能够设置扩展“真空”区域的填充方式,包括:扩展区域单元格填充、末行/列合并、起始格合并、等分行/列合并4种方式。如图4所示,是一种报表设计状态,报表设计时设置了子报表之间的“高度对齐”,并在后续描述了四种扩展“真空”区域的填充方式与传统方式的对比,图5为传统方法效果图。
如图6所示,扩展区域单元格填充就是以子报表扩展区域的单元格形式填充新扩充的扩展“真空”区域,直至与另一子报表对齐。
如图7所示,末行/列合并则是将最后扩展的行/列演变为合并单元格进而向下/右进行合并处理。
如图8所示,起始格合并就是将所有扩展“真空”区域合并为一个大的合并单元格。
如图9所示,等分行/列合并是将新区域等分为几段,然后分别合并。
然后进入步骤1013,由于需要使之循环直到最后一个子报表处理完(N>Max)。故检查循环是否完成,如果没有,则回到步骤2012;如果循环结束,则进入下一步骤。
步骤2013的检查结果为循环结束后,开始布置2014处理表尾,完成整个程序。