1. 概述编辑
在 FineReport 报表进行数据展示或图表展示时,经常会用到「排序」功能。一般在数据展示中应用比较多,图表中也会稍微涉及到一点。
本文将介绍 FineReport 支持的各类排序,以及对排序的各种应用进行简单介绍。
2. 三种排序方式对比编辑
FineReport 支持的三种排序类型分别为:数据集中的排序、高级排序、扩展后排序。这三种排序优缺点如下表所示:
注:高级排序是在报表执行前进行排序,扩展后排序是报表执行后再进行排序。
排序类型 | 功能简介 | 优点 | 缺点 |
---|---|---|---|
数据集中的排序 | 通过在数据集中写 SQL 语句,直接在数据库查询时排序 | 性能最佳 | 1)所有计算都必须要在数据库中做,会导致 SQL 很复杂,难以维护 2)有些计算是无法用 SQL 完成的 |
高级排序 | 报表根据某「数据列」设置公式和排列顺序进行排序。相当于扩展前排序,依赖于「数据列」 | 1)性能中等 2)可以基于「数据列」利用公式做一些稍微复杂些的排序 | 公式必须依赖于「数据列」,并且会导致公式的二次计算 |
扩展后排序 | 支持前两种排序,也支持对包含各类计算的扩展后的报表进行排序 | 最为灵活,满足目前所有的排序需求 | 由于在扩展完成后进行排序,会对所有格子的位置进行调整,因此性能最差 |
结论:
从性能方面考虑:数据集中的排序>高级排序>扩展后的排序。
从覆盖场景方面考虑:扩展后的排序>高级排序>数据集中的排序。
2.1 数据集中的排序
数据集中的排序是指通过 SQL 直接在数据库查询时排序,详情请参见:数据集中的排序
例如:
升序:SELECT * FROM 销量 order by 销量
降序:SELECT * FROM 销量 order by 销量 desc
2.2 高级排序
「高级排序」是指:报表根据某「数据列」设置的公式和排列顺序进行的排序。相当于扩展前排序,依赖于「数据列」。
高级排序必须在「最父格」单元格设置,例如 C1 单元格的左父格是 B1,B1 单元格的左父格是 A1,那么 A1 即为「最父格」。详情请参见:高级排序
相关排序方案:
方案 | 使用场景 | 原理梳理 |
---|---|---|
高级排序-数据列顺序 | 根据数据集中某一列数值进行排序 | 根据数据集中的数值,直接排序 |
高级排序-自定义顺序 | 根据数据集中的字符串字段进行排序 | 用switch或INDEX公式进行排序 相当于给每个字符串对应一个数值,根据对应后的数值进行排序 |
2.3 扩展后排序
考虑到性能问题,建议在「高级排序」无法实现的情况下再使用「扩展后排序」。
扩展后排序的使用场景较为灵活,本文从实现原理出发,将以下方案大致分为四类:简单扩展后排序、通过参数传递实现扩展后排序、通过手动构建数组实现扩展后排序、数值类型转换后实现扩展后排序。
2.3.1 简单扩展后排序
方案 | 使用场景 | 原理梳理 |
---|---|---|
按分组汇总结果排序 | 对于分组报表,有各种小计、合计、以及列表一起存在的。希望按照各个分组逐层进行排序 | 在相应的左父格上设置扩展后排序即可达到排序目的 |
2.3.2 通过参数传递实现扩展后排序
方案 | 使用场景 | 原理梳理 |
---|---|---|
点击某一列标题改变排序 | 点击标题实现升序和降序交换显示 | 通过添加超级链接-动态参数&在单元格扩展后排序中添加公式实现:
|
多列动态排序 | 希望多个列可以实现点击后变换升序降序的功能 | 同上 |
横向扩展列多列排序 | 点击列标题,可对该列进行升降排序,而列标题是根据字段横向扩展得来的 | 获取点击列的所有值,在销售员的单元格属性中,设置扩展后排序,销售员根据点击列的所有值进行排序 |
2.3.3 通过手动构建数组实现扩展后排序
方案 | 使用场景 | 原理梳理 |
---|---|---|
利用内置数据集实现自定义排序 | 通过 高级排序-自定义顺序 可以直接在公式里面逐个定义每个数据项的顺序,但数据项较多时,会使公式阅读起来困难且不易维护。这时可以通过使用「内置数据集」来自定义顺序 | 在内置数据集中定义好数据项顺序,通过数据集函数获取值,再通过inarray()函数返回单元格值在内置数据集中的位置,实现排序效果: |
扩展后多列按先后排序 | 希望先按照 A 进行排序,再按照 B 进行排序 类似于 SQL 语句中order by A,B | 1)字符类型数据: 通过INARRAY(字符, SORTARRAY(UNIQUEARRAY(扩展的所有字符)))获得排序位置 2)数值类型数据: 将多个需要排序的数值果经过运算处理得出一个新的数值,最后按照新数进行排序 |
分组内排序互不干扰 | 希望在同一张报表中,可以实现分组动态排序且互不影响的效果: 如当点击华东的销量时,华东的销量改变排序,华北的销量不受到影响;当点击华北的销量时,华北的销量改变排序,华东的销量不受到影响 | 1)根据「地区」的数量定义成一个数组长度,用数组中的元素存储对应分组的升降序(正数 1 为升序,负数 -1 为降序) 2)当点击销量时,先删除数组中点击位置对应的值,再将变为相反数的值插入到数组中对应的位置 3)设置扩展后排序,先获取点击位置对应的数组中的值,再乘以「销量」所在分组中单元格的值,按正负数的升序改变排序 |
2.3.4 数值类型转换后实现扩展后排序
方案 | 场景 | 原理梳理 |
---|---|---|
多级项目符号排序 | 对多级项目符号进行排序: | 多级项目符号是将多个数字用「 . 」隔开的字符串,通过将字符串转化成可以排序的数字,即可实现排序 |
扩展后中文按拼音排序 | 希望按照中文的拼音先后顺序进行排序 | 使用StringPinyin函数将中文转化为拼音,再按照拼音进行「扩展后排序」 |
汉字数字排序 | 对中文汉字的「序号」进行排序 | 方案一:数据很少时,可以使用高级排序-自定义顺序。也可利用内置数据集实现,详情请参照文档:利用内置数据集实现自定义排序 方案二:在「扩展后排序」中添加公式。用 numto() 公式将阿拉伯数字转化为汉字数字,再将汉字数字与对应的阿拉伯数字联系起来 注:方案二只适用于汉字数字从「一」开始且数字连续的场景。 |
3. 图表排序编辑
FineReport 报表一般包括纯粹的数据展示、图表展示和控件展示,排序一般应用在数据展示中比较多,但是图表中也会稍微涉及到一点,那么在图表中的排序需要注意以下几点:
1)图表数据来源于「数据集」,故对图表排序就需要对数据集中的数据进行排序,则需要使用 数据集中的排序。
2)图表数据来源于单元格,故对图表排序就是对单元格中的数据进行排序,即可以 高级排序 和 扩展后排序。
3)图表排序还提供接口,详细示例请查看 [新]图表排序接口。
4. 其他排序相关内容编辑
4.1 JS 实现排序效果
方案 | 使用场景 | 原理梳理 |
---|---|---|
JS实现决策报表中点击标题排序 | 决策报表实现排序效果 | 给单元格添加超链接,超链接中 JS 动态改变参数值,报表数据列根据参数值实现升序或降序排列 |
JS实现填报自动生成序号并排序 | 在填报录入数据时,希望序号可以自动生成,且新增或删除数据行时,序号不会断开 | 在加载结束事件中,利用前端 JS 接口实现每次插入删除行后重新计算序号的效果 |
JS实现不刷新页面进行排序功能 | 希望在填报页面,对于修改后但未入库的值实现点击标题进行排序的效果 若使用扩展后排序,点击标题时会刷新页面,无法保留刚刚填报后的数据 | 通过 JavaScript 来排序,对页面上的位置进行调整 |
4.2 其他排序效果
方案 | 使用场景 | 原理梳理 |
---|---|---|
扩展后排序重新编号 | 在对报表进行扩展后排序(按「牛奶」销量排序)之后,若直接使用单元格插入公式 seq() 或者 &cell 这两种方法获取序号,序号的顺序是乱序的 | 需要在数据排序结束后,对序号所在单元格附新值,根据排序后的结果添加序号。文档中所使用的方法: 方法一:设置 条件属性 新值 方法二:设置公式形态 方法三:添加加载结束事件,利用 JavaScript 代码解决 |
排序添加动态箭头 | 点击标题可以动态排序的情况下,想要在标题上设置「箭头」以体现当前是哪一列排序,是升序还是降序: | 在条件属性中通过公式进行判断,给单元格赋新值(HTML标签)实现排序箭头的效果: |