以文本方式实现Word文档报表的解决方案(二)
上篇http://www.cnblogs.com/Yjianyong/archive/2011/01/10/1931132.html
简要说明了方案的实现框架,接下来继续继续讲解方案的实现。
该报表方案主要不是更多的使用Word中强大的功能,而是更多地把用户的数据插入到模板中合适的地方,使用XML方式保存的Word文档,我们就可以脱离Office的框架,服务器端并不需要安装Office组件。
该方案以 --Property-- 为替代的标识,公式就用--=Func()--为标识,--符号必须成对出现,否则会产生不可预料的后果。
模板中使用到的公式有:
循环集合:
=Loop(Entity.Collection)
=Loop(Entity.Collection, PropertyName)
参数:
表示实体的集合属性 如 Entity.Collection 或单独的Collection(使用默认的实体)。
PropertyName:表示集合元素的属性名称。取值时,使用该属性的ToStirng()方法。为””时表示,取值时使用集合元素的ToString()方法,如字符串实体可以使用该形式
=Loop(参数1, PropertyName, Lenght)
Length: 增加一个循环的元素个数。
上三个公式是每个元素输出一行。
=Loop(参数1, PropertyName, Length , SplitCharacters)
SplitCharacters: 表示分隔的字符,显示的集合元素输出为同一行。
=Loop(参数1, PropertyName, startIndex, Length , SplitCharacters)
startIndex:起止的序号,从1开始算起。
SplitCharacters: 表示分隔的字符,显示的集合元素输出为同一行。
条件选择:
=IIF(Property == 条件, 真时的内容, 假时的内容)
比较条件可为 =或==、>、<、>=、<=、!= = 和 ==是一样
条件可以写 True,False Boolean类型、数字类型 和 字符串类型,先对布尔类型和数字类型对比,字符串可以不需要 ”” 符号,真和假时显示的内容都为字符串。
可以多条件,使用 && 或 || 中间不能使用括号分隔条件
条件判断:
=IfContains(Entity.Collection, propertyName, Content , ShowCharTrue, ShowCharFalse)
判断集合是否包含 Content 内容,如果包含即显示ShowCharTrue,否则显示ShowCharFalse。
包含判断:
=In(Entity.Collection, propertyName, {内容1, 内容2, …… })
以默认的空格分隔。
=In(Entity.Collection, propertyName, {内容1, 内容2, …… },SplitChar, NoneItemContent)
判断Collection有多少个项和{内容1, 内容2, …… }相同,返回 包含项的 序号,使用 SplitChar分隔,NoneItemContent为完全没有匹配时显示的内容,只比较字符串
格式化输出:
=Format(Property, FormatString)
对数字和日期进行格式化输出,使用ToString(formatString)。
实现中使用到的类:
ReportHelper 该类提供唯一开发者的入口方法 ReportBuild ,对指定的模板进行分析,逐字节分析出 -- 中间的字符串,最终产生一个正确结果的文本流 等
静态类 TxtFileEncoding 正确读取文本的编码(从网上摘录合并而成,网上有些做法实际并没有完全能够识别UTF-8的编码),
静态类 WordAnalyzer 对ReportBuild类获取的字符串,分析出用户设定的标识(因为Word文档可以在中间等不定的位置插入字体、字号等XML标志),并调用公式工具得到实际的输出文本内容。
静态类 FormulaUtility 实现方案中的公式,输出正确的结果。
WordAnalyzer 和 FormulaUtility 可以以插件的方式实现,增加扩展的灵活性,本方案没有采用些做法。
方案的协作图:
本期就说到这,下期对原码中的注意点作说明,并附上原码,大家一起把该报表做得更好。