zoukankan      html  css  js  c++  java
  • 分栏报表制作攻略

    一、分栏的意义

    我们常常会遇到一些列数很少行数很多的报表,这种报表窄窄长长,打印在一张 A4 纸上,横向留出大片空白;或者行数很少,列数很多的报表,打印在 A4 纸上,纵向留出大片空白·····这些情况下不但浪费张纸而且不美观,不方便用户查阅。

    为了解决这种问题,我们提出了分栏的解决方案,把数据按照一定的规则分栏分块的显示在纸张上。下面我们来具体看一下润乾报表是如何解决分栏问题的。

    二、分栏的实现方法

    我们吧分栏大致分为三类:卡片分栏、行分栏、列分栏。我们按照分类看下不同类别下应该如何实现分栏效果。

    2.1 卡片分栏

    2.1.1 卡片分栏效果图

    2.1.2 卡片分栏实现步骤

    1. 绘制卡片报表,如下图所示:

    卡片式报表绘制时,注意主格的设置:选中 A 列设置左主格为 B2。

    这样才能保证报表数据在展现时的分块效果。

    2. 设置报表分栏属性

    在报表—报表属性—分页配置页面中设置分栏数,如下图所示:

    分栏数的配置规则是:纸张的宽度 / 报表的宽度。这样能保证最大程度利用纸张且保证数据展现的效果。

    至此,我们就配置完成了卡片分栏报表。在润乾报表中,我们只需要设置下分栏数就可以实现卡片报表的分栏效果。

    注意事项:分栏报表中不允许存在隐藏行;尽量避免在第二栏中涉及自动换行撑大单元格的情况。

    2.2 行分栏

    2.2.1 行分栏效果图

    行分栏也叫做横向分栏,也就是把数据行按照一定的规则拆到不同的栏中。

    2.2.2 实现方法

    这里有两种实现方法,一种是在报表单元格中通过表达式拆分,另外一种则是在数据集中吧数据拆分好。

    方法一:to()+valueat() 函数实现分栏

    数据集 ds1 直接从数据库表中取数,sql 语句是:

    SELECT 编号, 部门, 姓名 FROM 员工表

    重点在于单元格表达式的拆分处理。

    其中,A5 单元格表达式:=to(0,ds1.count()/3),报表要分成三栏,所以我们要算出来每一栏要对应多少行数据。

    B5 单元格表达式:=valueat(ds1.select( 编号),3*A5),从数据集集合中取出对应行的记录,按照三倍的规律取对应位置的数据返回。

    依次类推,F5 单元格表达式为:=valueat(ds1.select( 编号),3*A5+1)

    J5 单元格表达式为:=valueat(ds1.select( 编号),3*A5+2)

    PS:valueat 函数的取值从 0 开始。

    此方法有一个缺点:当数据量比较多的时候,valueat 的取数性能会相对降低。

    方法二:集算器脚本实现分栏

    为了解决方案 1 在大数据量下的性能问题,我们把数据的拆分处理在数据集中完成,在润乾报表中我们可以使用脚本数据集来实现这一过程。

    首先,在集算器设计器中进行脚本的取数调试,脚本配置如下:

    其中,A1:=connect(“demo”) 表示连接 demo 数据库;

    A2:=A1.query(“SELECT 编号, 部门, 姓名 FROM 员工表”) 表示从 demo 数据库中取出员工表的数据;

    A3:=A2.step(3,1) 表示每三条记录取第一条;

    B3:=A2.step(3,2)|[null] 表示每三条记录取第二条;

    C3:=A2.step(3,3)|[null] 表示每三条记录取第三条;

    A4:=A3.derive(B3(#). 编号: 编号 2,B3(#). 姓名: 姓名 2,B3(#). 部门: 部门 2,C3(#). 编号: 编号 3,C3(#). 姓名: 姓名 3,C3(#). 部门: 部门 3) 表示吧三部分的数据整合到一起,组合成一个完整的数据集返回。

    然后,在报表中新增集算器类型数据集,并加载编辑好的脚本文件,如下图所示:

    最后,按照常规报表取数生成报表文件:

    这种方法的优先在于,可以更加方便的对数据进行处理,在处理过程中不依赖数据库,而且也最大程度上减少了单元格的二次计算处理,提升了报表的性能。

    2.3 列分栏

    2.3.1 列分栏效果图

    当列数比较多,需要强制折行到下一行显示时,就是对应我们常说的列分栏需求。

    2.3.2 列分栏实现步骤

    实现的原理是,我们把数据按照一定的规则强制设置换行,比如上图的需求,需要每行显示六列数据,那么我们只需要按照这个规则算好需要分几行,然后吧数据填充进去就可以了,具体单元格表达式配置如下:

    其中,A1:=ds1.count(),用于计算此数据集内的数据个数。

    A2:=to(1, int(A1)/6+1),作为强制分行的扩展基础,int(A1)/6+1 用于计算一共需要扩展的行数,其中”6″是每行的数据列数

    B2:=(A2-1)*6,是每行的基数。

    D1:=if(A1<6,to(1,A1),to(1,6))  ,控制显示为 6 列数据, 数据够 6 列就换行

    D2:=ds1.select(name, #0==D1+B3,1) ,其中 D1+B3 分别递增,达到与每个行号进行匹配的目的,#0 表示取对应记录的行号。

    D3:=ds1.select(price,rownum==D1+B3,1)

    至此,就实现了列分栏的需求。

    三、总结

    简单的分栏需求,我们可以直接通过润乾报表设置栏数实现效果。

    复杂的分栏需求实现时,先明确分栏的规则,然后用报表工具内置的函数或者配置实现这个规则,最后填充数据。有润乾报表在,你的想法我来实现。

  • 相关阅读:
    C# 调试程序时如何输入命令行参数
    C# 连接和操作SQL SERVER数据库
    在C#中读写INI配置文件(转)
    Visual Studio 项目中添加include, lib, dll库文件(*.h,*.lib,*.dll)
    Android系统Recovery工作原理
    Windows服务创建及安装
    C# WinForm窗口最小化到系统托盘
    C#文件操作
    C# 调用Windows API实现两个进程间的通信
    Linux转发性能评估与优化-转发瓶颈分析与解决方式(补遗)
  • 原文地址:https://www.cnblogs.com/shiGuangShiYi/p/12088693.html
Copyright © 2011-2022 走看看