一个传统的报表制作过程可能是这样的:
在TSS中,过程是这样:
两相对比,第一种比较原始,需要多人参与,用到多种工具,过程多次重复,实时性、准确性、安全性等缺乏保障;第二种方式只需一个浏览器,和一个懂业务、会写SQL和做网页的数据分析员,且一次开发完成,长期可用,对管理人员来说也更方便,数据实时可见,查询方便且更安全,准确性也更有保障。 当然这只是有BI工具和没有BI工具的简单对比,市面上有众多的BI工具,下面看TSS的报表具体有哪些特色。
TSS报表可以以以下多种形式存在:
报表分组的作用是对多个报表进行分类,方便查找,避免单一目录下报表数量过多。
右键点击报表分组,选择【新增报表(服务)】。
查询脚本可以是一个可运行的SELECT SQL语句,但也不只是SQL,其内容格式支持Freemarker模板引擎,可以根据传递过来的不同查询条件及当前登录的用户、组织、角色等信息,来动态的解析生成最终可被执行的SQL语句,起到控制查询逻辑,及过滤数据(即控制数据行级权限)的作用。
通常,直接把通过测试运行的SQL复制过来即可,需注意select出来字段的别名不能有重名,否则在分页查询时会出错。查询脚本可以和查询条件有机组合使用,以满足不同的查询需求。
下面以具体例子来演示,先看看可以用做过滤数据用户信息(更多参考:登录用户会话信息)有哪些:假设某用户账号为XX00123,所属组织架构为:X物流公司/ 浙江分公司/ 杭州分拨,拥有角色:分拨经理。
名称 类型 值 说明 userCode String XX00123 用户账号 userName String 金石 用户名称 userRoles List [12] 用户拥有的角色ID列表; _userRoles 逗号分隔的字符串 userRoleNames List [分拨经理] 用户拥有的角色ID列表; _userRoleNames 逗号分隔字符串 userGroup String 杭州分拨 用户所在组 现在假设有一张表(tbl_kq),记录了所有分拨层级员工的考勤信息,字段包括: staff(考勤员工), group(所属组织), worktime(工作时长) , workday(工作日), creator(录入人)1、统计每天的考勤人数
Select t.workday 工作日, count(distinct t.staff) 考勤人数 from tbl_kq t group by t.workday2、分拨经理查看本分拨员工考勤日报
Select t.workday 工作日, count(distinct t.staff) 考勤人数 from tbl_kq t where t.group = '${userGroup}' -- 数据只看本分拨 and <#if 分拨经理??> 1=1 <#else> 1=0 </#if> -- 要求查询人拥有【分拨经理】角色,没有则无法查看 group by t.workday3、总公司的薪资人员可以按不同查询条件查询考勤数据,具体查询条件有:param1(日期从) 、param2(日期到)、param3(员工)
<#if param3??> -- 如果查询条件param3(员工)不为空,则查该员工考勤明细 Select t.staff 员工, t.workday 工作日, sum(t.worktime) 工作时长 from tbl_kq t where t.staff = '${ param3}' and t.workday >= ${param1} and t.workday <= ${param2} group by t.workday <#else> -- 查汇总数据 Select t.workday 工作日, t.group 分拨, count(distinct t.staff) 考勤人数, sum(worktime) 工作时长 from tbl_kq t where t.workday >= ${param1} and t.workday <= ${param2} group by t.workday, t.group </#if>4、匹配条件直接用通配符: ?
Select t.workday 工作日, t.group 分拨, count(distinct t.staff) 考勤人数, sum(worktime) 工作时长 from tbl_kq t where t.workday >= ? and t.workday <= ? and t.staff = ? -- ?号的顺序与param1(日期从) 、param2(日期到)、param3(员工)编号一致 group by t.workday, t.groupFreemarker模板引擎参考Freemarker常用写法,更多请谷歌百度。
报表通常要支持不同的查询条件,以查询不同时间空间范围里数据。TSS支持在线配置参数,配置好的参数可以和报表查询脚本无缝组合,联合起来查询各种报表。为能更方便的配置参数,TSS设计了以下参数定义编辑器: 点击“报表参数”下方的【配置】按钮,即可弹出上面编辑器,右键点击“查询参数列表”,选【新建参数】即可开始开始定义新参数,完成后“参数参数列表”下方的列表里会多出一个节点项,如需要修改,直接鼠标单击要修改的节点。下表将逐个解释参数定义编辑器里属性的作用:
属性 | 说明 | 备注 |
---|---|---|
参数名称 | 显示在网页表格或表单的标签位置 | |
参数编码 | 支持自定义查询编码,默认为param1、param2…… | |
参数类型 | 目前支持的类型有:字符串、数字、日期、日期时间、隐藏,隐藏字段用来存放一些固定的条件。默认为“字符串。 | 日期和日期时间,界面输入框为时间选择器。其中日期类型的默认值支持相对写法,today-n,n为数字,表示今天往前n天。 |
是否必填 | 选是,则参数要求必填,参数输入框后面会出现一个红色的星号 | |
默认值 | 打开查询表单查询时,参数输入框默认显示该值 | 建议:对于必填的参数,设置一个默认值,可以引导使用者如何正确填写参数。 |
校验正则 | 对输入参数值有要求的字段,可以通过定制一个JS的正则表达式,对值进行校验,比如电子邮件等;校验不通过的,输入框下方将会出现提示气泡,提醒用户改正 | |
出错提示 | 结合上面的正则校验,在提示气泡显示个性化的内容 | |
宽度、高度 | 定义查询参数输入框的高和宽,如右边效果图显示,每个条件输入框,都可以有不同的宽度和高度。注:通常只正对字段类型为“字符串”的字段。 | |
下拉列表 | 输入固定字段信息时,需要从列表中选择。列表的选项如果是固定的,可以直接在定义里输入,格式如:1|2,A|B,显示的是A、B选项,选中的值为1、2; | 如果列表选项非固定,而是来自某种数据配置表,则需要通过数据服务从数据库里把列表数据取出来,需要事先在报表模块里建立一个数据服务。注:select字段的别名要求为id|value|code、name|text |
是否多选 | 上面下拉列表默认是单选,如果需要多选,则此处打勾,效果见右边截图。 | |
联动方法 | 当下拉选择是多级时,比如省、市、区,此时需要在不同的下拉列表间进行联动,这里的联动方法,是指当前下拉列表选择完成后,自动触发方法加载下一级联动下拉列表,联动方法可以自行在页面控制脚本里定义,也可以使用通用的联动方法getNextLevelOption | getNextLevelOption(^param2^,718,^param1^) loc:下一级联动的参数编码 718:下一级联动对应的数据服务ID param1:该数据服务需要接受一个名为param1的参数,此参数值即为上一级值 |
最后,所有参数定义完成后,不要忘记点编辑器左下角的【完成编辑】,点完成后定义内容才会输出到“报表参数”这个编辑框,参数定义编辑器也自动关闭。可以反复点“报表参数”下方的【配置】按钮,来打开参数定义编辑器进行编辑。 删除参数用右键点击要删除的参数,然后点【删除】。也可以直接在“报表参数”的文本内容里直接删除该参数对应的配置行。
报表(或分组)创建完成正式启用后,还需要把权限开放给特定的角色。右键选中新建的报表节点,点击【授予角色】,打开把报表授给角色的界面,出来一个二维授权矩阵图,左侧列表是系统的角色列表,矩阵的顶部维度是“报表”资源的“权限操作项”,如果需要把当前数据表的部分操作权限授给特定角色,在它们交汇的勾选框里打上勾即可,如果要取消授权,则在已勾选的框再次点击一下,即可去掉勾,完成后点击【保存授权】,界面会刷新出最新的授权结果。 注:因报表是和报表分组组成的一个树形组织结构,为了保证树结构的完整性,对报表分组也同样需要进行授予角色操作,报表分组的“查看报表”权限授给和报表一样的角色。 如授权比较混乱,需要重新梳理,可以点【清除已授权限】,即可清除该报表资源的所有授权信息,然后重新开始勾选授权。
报表权限项分为: 查看报表、维护报表、删除报表、停用|启用:
报表和数据表,都支持导入导出,这样可以方便将开发好的报表从一个环境复制到另一个环境(比如从开发测试环境复制到正式环境)。导出时,可以单个报表导出,也可以导出整个分组下的所有报表。
数据服务的查询请求发送到BI服务器后,会被转发到数据库端运行,完成后返回结果给应用服务器,应用服务器再把数据发布成功JSON格式传递给报表页面。这其中有些服务的数据很多报表都可能用到,而且频次很高,如果反复被发送到数据库去查询,造成资源浪费。针对这类情况,可以在应用服务器端对数据进行缓存。
报表数据通常对实时性要求不高,延后几分钟一般感觉不出来。TSS设置了多档时长的数据缓存策略,默认对数据采取3分钟缓存策略(以数据服务的地址及查询条件做Key进行缓存),即一份数据被查询到应用服务器后,它会在应用服务器的缓存里上存活3分钟,这3分钟内如果再有相同查询条件的请求过来,则直接从缓存里获取该数据,不用再从数据库里查询一边。而3分钟后,数据被销毁,此后再有新请求过来,会重新获取一份最新的数据,继续缓存3分钟,循环往复。如此可以为数据库挡掉很多查询请求,而用户也能更快的从缓存中获取到数据。可以通过查看系统《缓存管理》模块里数据缓存池的命中率来评估缓存策略是否有效,及如何调整。
数据缓存后被后面请求命中需要满足条件:它们查询的是同一个数据服务且参数条件完全一致。如果参数有不一样,那就是两份不同的数据。所以BI对每个数据服务默认是针对参数条件进行缓存。但有些情形下,就算条件一致,不同的人查询出来的结果却可能不一样。这种情形下,需要对数据按【用户+参数】进行缓存,这类数据服务在发送请求时,需要多传递一个参数uCache='true'。第三种情形是对数据有实时性要求,希望每次获取的数据都是最新的,这种情况就不宜再使用缓存了。请求时,需要多传递一个参数noCache='true'。
新建好一个带报表脚本的报表后,它就已经具备获取数据的能力,TSS提供了一个默认的Grid表格展示页,双击报表节点,打开查询条件框,输入条件点击【查询】,显示如下图。数据是分页显示的,一页50行,滚动条滚动到底部时,会自动加载下一页,也可以使用右上角的翻页按钮逐页查看,可以导出查询结果到Excel。
一个带报表脚本的报表,其数据可以查询展示成Grid表格,也可以导出成Excel,同时它也是一个独立的数据服务(或者叫API接口,报表节点右键菜单里【测试数据服务】专门用测数据服务),在BI系统里的HTML页面、BI外其它系统,被授权后,即可以通过访问报表数据服务获取数据。
HTML页面通过JS AJAX访问报表数据服务的方式有两种JSON和JSONP,前者JSON用在单一BI系统访问,后者JSONP可用在多个BI系统并存时,相互之间的跨域访问。跨域访问,除了JSONP之外,也可以使用后台语言(JAVA等)发请求到BI系统,进行访问。
数据服务调用更多详细的说明参考: TSS API接口
除了上面默认展示及导出两种查看数据方式外,TSS还支持自定义基于HTML5编写的展示模板。HTML5网页里可以方便的通过AJAX请求获取一个或多个数据服务的数据,然后进行集中加工处理分析,最终结果在图表控件(Echarts、EasyUI等任选)里展示出来。TSS默认集成了Echarts(2、3版本)、EasyUI(1.5.2)等可视化组件,如果需要使用其它的组件,直接把组件包上传到BI环境下,然后即可引用。
定制好的展示HTML5页面及其额外所需的组件包(JS、CSS、图片等),都可以通过【TSS资源上传模块】上传到BI服务器。点击【上传附件】, 弹出资源上传界面完成上传后,再点【选择页面】,将刚上传的展示模板页面选中。设置完展示页面后,再次查询报表展现的将是设定的定制页面。
当定制页面只需要访问一个数据服务时,可直接把SQL和HTML5页放在一个报表里,打开报表前会先去执行SQL查询,获取到的数据放在框架页(reporter.html或report_portlet.html)的全局变量里globalValiable.data,定制页面且嵌在框架页的iframe里,可以通过parent.globalValiable.data的方式获取到已查询到的数据。查询参数同时存在globalValiable.queryParams里,定制页里可以获取这些参数,然后发送新的查询请求。可在定制页里这么写:
var globalValiable = window.parent.globalValiable, data, params; if(globalValiable && globalValiable.queryParams) { params = globalValiable.queryParams; data = globalValiable.data; }当定制页面需要访问多个数据服务,此时,定制页面所在的报表只能写一个报表脚本,这种情形可以考虑把数据服务和定制页面分离开,即先创建多个数据服务,再由定制页面自主发送请求去获取各个数据服务的数据。页面里如何获取数据参考如下:
var data1, data2, data3, data4, params = {}; URL_DATA_1 = '/tss/api/json/100'; URL_DATA_2 = '/tss/api/json/101'; URL_DATA_3 = '/tss/api/json/102'; URL_DATA_4 = '/tss/api/json/103'; // 发送数据请求一 $.getJSON(URL_DATA_1, params, function(data) { data1 = data; params = data1[0]; /* 发送数据请求二 (注意: 请求二是在请求一响应成功并返回数据后才发送) * 这种场景适合:当请求二需要以请求一的返回数据作为其参数条件时 */ $.getJSON(URL_DATA_2, params, function(data) { data2 = data; show2(data1, data2); }); } }); // 发送数据请求三 $.getJSON(URL_DATA_3, params, function(data) { data3 = data; data3 && data4 && show34(); // show34方法需要等请求三和请求四都成功返回数据后才执行 }); // 发送数据请求四(注意: 请求三是和请求四并行发送) $.getJSON(URL_DATA_4, params, function(data) { data4 = data; data3 && data4 && show34(); // show34方法需要等请求三和请求四都成功返回数据后才执行 });
不同于市面上很多报表BI类软件强调的拖拽式开发报表,TSS侧重于为开发者提供服务,允许开发者完全自主去定制任意形式的可视化效果,开发者使用合适的图表控件(Echarts、D3、HighCharts、EasyUI等),结合TSS的后端能力,可以做出不受任何限制的报表,只需要开发者有一定JS代码基础。我们的案例库里也提供了多种模板供开发者借鉴参考。
通常用户访问报表的方式是找到相应的功能报表目录,打开输入查询条件然后查询,然后再打开下一个报表再输入条件查询,当报表个数不多且各自查询条件迥异时,这种从功能打开报表的行为比较合理。
当有很多类似查询条件的报表,分别查询各个不同的指标分析(比如一个物流公司有货量指标、营收指标、质量指标等),此时如果还用上面方式就很痛苦了:当希望横向对比一下某几个指标的趋势时,需要多次打开多个报表,逐个输入相同的查询条件。这时如果可以先设定条件,然后再逐个打开各个指标报表,这些报表自动复用开始设定的查询条件,这样指标间来回切换则会很方便。而且各个报表页始终共享一份参数条件,参数条件发生改变,刷新各个页面即自动更新数据。
我们姑且称第一种为纵向打开,第二种为横向打开,横向打开要求各个报表页从一个统一的查询界面获取查询条件。TSS里,通过报表框架页report_portlet.html打开报表时,每个报表可以设置是否需要使用通用查询条件(默认使用 more/bi_condition.html),且可以单独指定通用查询条件页面地址。通用查询条件界面效果如下图: 右边为固定的时间条件,比较通用,左侧为具体业务所需的空间分布类查询条件,最多支持六个维度。通用查询条件里的条件不是越多越好,相对生僻不通用的条件可以单独放在报表页内,然后组合通用条件及自身特有的条件完成数据查询。
单个报表如需引用通用查询条件框里的值,则需要在设置报表自身的“参数配置”时引入,写法如: 此处表示“开始日期”这个查询条件,优先使用通用查询框里的“日期从”的值,即_day1,如果_day1没有值,则默认使用 today-30。_day2是“日期到”的值。周、月、季度、年的从和到的值写法分别为 _week1|_week2、_month1|_month2、_season|_season2、_year1|_year2,左侧空间组织类从上到下分别为 _g1、_g2、_g3、_g4……。也可以在发起AJAX请求时,直接读取通用查询框里的条件值(存在Cookie里),如:tssJS.Cookie.getValue(“_day1”)。
TSS支持在移动端录入和展示数据,开发好的数据报表可直接在移动端展示(目前支持HTML5和微信小程序)。将配置项【移动端浏览】设置为“支持”,则报表自动在移动端(小程序或H5)的报表目录里展示。
如需定制开发移动端,基本开发方式和开发一个PC端展示的报表定制页类似,具体示例参考 mobile 目录下的例子。
通过页面report_portlet.html,TSS的报表支持从邮件、文章、菜单链接、第三方系统等各类入口快速打开,且可设置默认打开的查询条件,示例如下:
http://www.boubei.com/tss/modules/dm/report_portlet.html?id=501& param1=today-10
其中id为报表的ID,param1为打开初始参数。考虑到系统迁移,报表ID可能会变化,可使用报表的编码替代ID来打开:
http://www.boubei.com/tss/modules/dm/report_portlet.html?rpcode=reportxxx& param1=today-10
可选参数refresh,如果打开的报表是个看板,此参数可支持自动刷新看板,单位(分钟)
http://www.boubei.com/tss/modules/dm/report_portlet.html?rpName=报表名称& param1=today-10&refresh=3
数据表兼顾展示和录入功能,某种程度上也是一个报表(录入型报表),所以在组织报表的目录结构时,可以考虑把录入型报表也放在报表的目录里展示,实现目录的统一。右键点击报表分组,选择按钮【新增录入表链接】,选择相应的数据表。这样当这个报表菜单被打开时,会自动切换到数据录入页。
注:需要额外多做一次授权,把录入页的链接的查看权限授予相应角色。
报表开发完成后,除了用户主动登陆BI进行访问外,也可以由系统或用户主动把数据推送给其它用户。TSS目前支持多种数据分发和共享方式。
对于访问频次高的报表,可以加入到收藏夹,后续使用直接从收藏夹打开报表。操作如下:
可以点击右侧工具栏里的点赞/差评按钮对某个功能进行评价。
当使用者在浏览报表的过程中发现报表数据有异常、或者有更好的改进建议,可以进行异常反馈。管理员可以看到使用者对当前报表的反馈意见,进而完善报表。