上文介绍了打造您自己的开发语言,这篇我们利用自定义开发语言设计灵活报表。本系统基于ureport
上二次开发,使用它可以完成任意复杂的中国式报表。类似Excel的方式以极简方式开发自定义报表,本文详细介绍了常见的几类报表,包含不限于复杂表头报表,查询报表,图表结合,数据钻取报表,分组小计合计报表,预警报表,套打等。
单元格之间存在依赖关系,对于任意一个单元格都可以设置它的左父格与上父格。单元格父格是可选的,默认情况下,单元格的左父格就是其最近左边与其位于同一行的单元格;上父格则是其最近上方与其位于同一列的的单元格。如果一个单元格位于第一行,那默认它就没有上父格,同样,如果位于第一列,默认它就没有左父格。
任意单元格在绑定数据集中某个字段时,如果这个字段有一条以上的数据,那么单元格就可以展开以显示这些数据。对于父格而言,父格展开时会带动子格一起展开,如父格向下展开,则带其下所有子格及子格的子格一起向下展开;同时,如果子格中绑定的数据集与父格中数据集同属一个,则子格中的数据将受父格限制。子格绑定的数据集字段数据在展开时,同样也会带动其下子格一起展开,而当前子格的父格如与子格处于同一行或列,则会将父格拉大。
利用上述迭代单元格的特性,我们就可以制作出各种复杂的报表样式,掌握了这一报表计算模型的特点,是开发报表的前提。
采用antlr4
自定义词法和语法
•类型:数字,字符串和布尔型•运算符:+,-,(如果是字符串,则表示重复次数),/,%(取余),like(包含),not like(不包含),in(在列表里),not in(不在列表里)•逻辑运算符:&&(and),||(or),not(!)•支持三元表达式:A1>1000 ? "正常值" : "低值"
•内置函数•常用函数:count,sum,avg,max,min,row(取行号,从1开始),column(取列号,从1开始),order(对列表排序),list(列表函数),param(取外部参数值),emptyparam(判断参数是否为空),formatdate(日期格式化),formatnumber(数字格式化)•分页函数:所谓分页相关函数,是指这些函数是在分页的时候进行计算,比如计算当前页有多少条记录、当前页某个单元格值累加后是多少、平均值是多少、最大值是多少等等,包括pcount,psum,pmax,pmin,page,pages•数学函数:chn(数字转中文),rmb(数字转中文人民币),median(求中位数),mode(众数),vara(求方差),stdevp(求标准差)•日期函数:day,month,year,week等•字符串函数:indexof,length,lower,repalce,substring,json等
支持在单元格返回true,false语法:listof("abc","b")>=1
增加其他有用函数:如range
,dateCal
,http
等
修复了条件bug:支持增加like,not like条件:支持类似数据库的%,如ab%为开始匹配,如果输入ab则等价于%ab%
按需扩展语法:为了增强报表表现力,增加条件表达式,扩展return语法等
前端增加快捷键
•数据预警:机构名带“银行”两次字体颜色标绿•报表查询:可以按机构名模糊查询•图形统计:加入一个饼图按省份统计机构个数•数据钻取模拟:给机构名加上链接,如果带“银行”两字跳到baidu,其他跳到bing网站并传参(ID值非当前单元格的值)
使用表达式定义一个静态列表list('北京','上海','浙江')
或使用动态列表(采用select),选择数据展开向右即可。
这时,底下展开的数据可以使用单元格坐标拿到表头数据,然后指定select拿到动态数据
分组报表定义比较简单,定义需要分组的数据集,然后定义针对数据集的分组使用group函数即可,如下图:
•定义分组
•定义数据
•最后效果
小计与合计的设置比较简单,主要指定对应的左父或上父即可针对这批数据序列算sum,count等操作
通过数据的不同展开方向来定义,在标题栏的列上使用向右展开数据,在第一列使用group向下展开数据,交叉点位置就可以使用group来获取上方数据和左边数据的交叉点来获取,如下图:
•定义标题栏的动态列
•定义动态行
•定义交叉点的位置数据
•最后效果
如果需要定义同步环比报表,需要理解单元格引用,单元格坐标,因为环比一般是针对上个月数据/本月数据,本单元格数据可以通过#或单元格坐标获取,但上个月数据只能通过针对当前单元格的引用来完成。以下是单元格引用语法:
A1(直接写类似Excel的单元格坐标即可),但要注意,被引用的单元格是否在同行或同列中,如果不在,则可能会产生多个值,用逗号隔开(找这个单元格和引用的单元格共同的左父对应下的多个值) 为了实现更复杂的单元格引用,我们可以使用单元格坐标,语法如下:单元格名称[Li:li,Li-1:li-1,…;Ti:ti,Ti-1:ti-1…]{条件...}
•$单元格:在单元格名称前加$符号,表示取相对于目标单元格的单元格的值,比如:C2[A2:-1]{B2==$B2}
表示,A2单元向上一格数据的C2单元格的值(可能多个,在分组中),同时,取当前单元格B2的值和定位后C2单元格对应的B2单元格的值
•&单元格:如&A2,指的是相对于当前单元格 A2 单元格展开后的序号,可以采用“&单元格名称”的方式标记某个单元格展开后的序号,需要注意的是,使用“&单元格名称”来标记目标单元格展开后的序号时,当前单元格必须是目标单元格的子格或间接子格•#:表达式取当前单元格值,比如给单元格配置链接传递参数时,可以使用这个符号,#.属性名表示取当前行属性名对应的值
。
综上所述,我们对ureport的语法进行了加强,大大增强了报表的表现力,随着报表开发需求的多样性,未来还会加入更多功能,也会整合认证。有了它,开发业务报表大大降低。未来还会加入报表定期发送,预报指标预警等功能。
•脚本开发工具的设计与实现•为SDP提供本地Python编程能力•两种方式破解图片验证码•利用binlog进行MySQL数据闪回•NLP — 文本分类和BIO实体标注•异地异构数据同步传输平台的设计与实现•各种形状印章的去除
欢迎关注我的公众号“Sumslack”,原创技术文章第一时间推送。