复杂报表介绍

功能介绍

2019版报表中心集中于解决“数据出口(输出)”的问题,提供数据统计、汇总、分析、打印、输出、预警等一体化、通用解决方案。报表中心数据可来自于OA标准模块、流程中心、应用中心所产生的数据,也可来自于MySQL、SQL Server、Oracle等类型第三方开发的业务系统数据。报表中心包含四种制作报表的方法,分别是明细表、统计表、图表以及复杂报表,其中:

  • 明细表适用于以多级表头形式罗列明细清单的报表应用场景,例如各类人员花名册、采购清单等,如下图所示:

  • 统计表适用于从横、纵两个方向组合多个维度(角度)统计数据的应用场景,例如人员统计表、销售统计表,如下图所示:

  • 图表适用于以图表形式展示统计数据的应用场景,目前支持柱状图、栈柱状图、条形图、栈条形图、曲线图、面积图、栈面积图、饼图、散点图、气泡图、雷达图、仪表盘、地图、混合图、甘特图等15种图表类型,如下图所示:

  • 复杂报表适用于用户根据管理需求自由绘制报表格式和数据展示形式的应用场景。

本手册重点介绍复杂报表定义方法,其他类型报表定义请参考《通达OA2019版报表中心使用手册》。

快速入门

复杂报表包括设计报表和使用报表两部分组成,设计报表又包括准备数据集和制作报表两部分。复杂报表操作步骤如下图所示:

设计报表

现以设计人员分析表为例,描述复杂报表的设计过程。人员分析表将按部门、分性别统计各个角色人员数量,有小计和合计,如下图所示:

准备数据集


依次点击 “报表中心” 》 “数据源管理”,进入数据源管理界面,如下图所示:

点击数据源“TD_OA”,进入该数据源数据集管理界面,如下图所示:

点击上图中的“新建数据集”,然后点中“SQL语句”,进入以SQL语句定义数据集界面,如下图所示:

在上述SQL语句编辑框中输入本次分析需要用到的SQL语句:

select UID as 人员UID,USER_ID as 登录名,USER_NAME as 真实姓名,if(SEX=0,'男','女') as 性别,USER_PRIV_NAME as 角色,(select DEPT_NAME from department

where DEPT_ID=user.DEPT_ID) as 所属部门 from user where DEPT_ID>0 order by DEPT_ID,SEX,USER_PRIV

数据集名称指定为“人员情况”,然后点击“保存”完成数据集定义。在定义数据集过程中,可以通过点击“预览”实时查看数据情况。

定义报表

依次点击“报表中心”》“报表管理”,进入报表管理界面,如下图所示:

选择分类“特性展示”,然后点击“新建报表”,系统弹出报表类型选择对话框,如下图所示:

点选“复杂报表”,进入复杂报表设计器界面,该设计器采取类EXCEL方式设计,操作方式亦与EXCEL类似,如下图所示:

工具栏包含的功能如下图:

设计表样

设计表样有两种方法,第一种是在复杂报表设计器里绘制,其操作方式与操作EXCEL类似;第二种方法是通过点击“导入表样”按钮导入已有的EXCEL文件。导入本章开头里所描述的“人员情况分析表”表样,如下图所示:

友情提示:复杂报表设计器兼容xls格式的EXCEL文件,但还不兼容xlsx格式的EXCEL文件。如果需要导入xlsx格式的EXCEL文件,请先转成xls格式。

定义数据列

从字段选择区中,选择数据集“人员情况”,然后把字段“角色”拖拽到单元格“D2”中,如下图所示:

数据列用蓝字英文中括号字段名称表示,如上图中的[角色]。字段放置好之后,接着我们来定义数据其他属性。选中单元格“D2”,然后点击工具栏上的“数据设置”,系统弹出数据设置对话框,如下图所示:

数据设置对话框包含基本、筛选、其他、单位换算三个页签,每个页签包含若干设置项。

先切换到基本页签(默认打开),这个页签包含数据集、字段以及分组、列表、汇总、无动作等数据处理方式。这里数据集为:“人员情况”,字段为:“角色”。数据处理方式解释如下:

  • 分组:把提取过来的数据进行分组显示,分普通分组、相邻分组以及自定义分组。普通分组指在整列范围之内进行相同值合并分组,类似于数据库group by操作;相邻分组仅相邻数据进行相同值合并分组;自定义分组可以在原始数据基础上进行二次加工,然后再进行普通分组。关于如何定义自定义分组,请参考后面章节。

  • 列表:把提取过来的数据依次罗列展示,不做任何加工处理。

  • 汇总:把原始数据进行汇总计算后再显示,汇总方式包括求和、求平均、最大值、最小值、求个数五种。

  • 无动作:不做任何事情,类似于未定义。

这里按默认设置,即普通分组。

切换至筛选页签,如下图所示:

这里可以定义数据筛选条件表达式以及是否“继承父格条件”选项。这里要提取所有人信息,所以筛选条件表达式不定义,保持空白。

在其他页签可以定义提取数据范围以及排序规则;单位换算页签可以定义数据单位换算规则。这里均保持默认设置即可。

接着定义【角色】数据扩展方式,点击工具栏“扩展设置”,如下图所示:

数据扩展方式包括纵向扩展(按行向下)、横向扩展(按列向右)、不扩展三种,这里指定为“横向扩展(按列向右)”。

最后定义【角色】父子格,点击工具栏上的“父子格”,如下图所示:

父子格包含“左父格”和“右父格”两种。每种父子格有三种设置,分别是无、默认以及自定义:

  • 无:无父子格关系。

  • 默认:位于单元格左边的最靠近且纵向扩展的单元格默认为该单元格的左父格;与此类似,位于单元格上方的最靠近且横向扩展的单元格默认为该单元格的上父格。

  • 自定义:指定具体单元格作为父格。能充当父格的单元格必须是定义了数据列且设置为纵向或横向扩展。

这里父子格按默认设置即可。关于父子格将在后面章节详细说明。

到此为止,单元格“D2”数据列设置完成,返回到设计器并把光标移到单元格“D2”上可以看到数据列定义信息,如下图所示:

接着设置单元格“B3”数据列,设置结果如下图所示:

单元格“C3”数据列设置结果如下图所示:

单元格“D3”是要统计同时满足“部门”-“性别”-“角色”这三个维度组合条件的人数,因此采取“求个数”汇总方式且不扩展,设置结果如下图所示:

单元格“E3”数据列设置结果如下图所示:

单元格“D4”是对部门维度一个小计,即统计满足“部门”-“角色”两个维度条件(不分性别)的人数,因此“部门”所在的单元格“B3”是左父格,“角色”所在的单元格“D2”是上父格。由于“部门”所在的单元格“B3”不在“D4”单元格的左边,因此左父格需要设置为“自定义”方式手动指定为左父格为“B3”,而上父格按默认设置即可。“D4”数据列设置结果如下图所示:

单元格“E4”数据列设置结果如下图所示:

单元格“D5”数据列设置结果如下图所示:

单元格“E5“数据列设置结果如下图所示:

至此,该报表主体已经定义完成。最后,在操作栏中输入报表名称为“人员情况分析表”,选择报表分类为“特性展示”,然后点击“保存”完成设计报表工作,如下图所示:

关闭报表设计器界面,返回到报表管理界面,可以看到刚才新建的报表,如下图所示:

使用报表

在使用报表之前,先分配好权限,点击上图中的权限设置图标,分配权限如下图所示:

依次点击“报表中心”》“我的报表”,从左边报表分类树里,找到要访问的报表并点击即可,如下图所示:

父子格

父子格概念

复杂报表定义的基本单元是单元格,单元格之间本身是没有关系的,为了建立起单元格之间的关系从而引入了“父子格”概念。父子格分左父格和上父格两种,父子格在子格一方设置,设置了父子格的单元格之间就构成了父子格关系。能作为父格的单元格需要具备以下条件:

  • 设置了数据列。

  • 设置了扩展方式,且扩展方式必须是横向扩展或纵向扩展之一。

父子格可选设置有以下三种:

  • 无:即该单元格无父格。

  • 默认:默认的左父格取位于单元格左边同一行的或者是合并的单元格能够覆盖该行的、最靠近且具备父格条件的单元格;默认的上父格取位于单元格上方同一列或者是合并的单元格能够覆盖该列的、最靠近且具备父格条件的单元格。注意:按行向下扩展的单元格才有默认左父格,按列向右扩展的单元格没有默认左父格;同理,按列向右扩展的单元格才有默认上父格,按行向下扩展的单元格没有默认上父格。

  • 自定义:手动指定父格。

父子格关系

父子格关系包含以下两层含义:

  • 扩展跟随关系:子格跟随父格的扩展而扩展。

  • 条件传递关系:子格的数据需要满足父格条件,即父格限制了子格能够取到的数据范围。

例子

为了进一步阐明父子格关系,现举例说明如下:

默认左父格关系

单元格“A1”、“B1”的左父格及上父格都按默认设置,那么“A1”没有左父格,也没有上父格;“B1”左父格是“A1”,没有上父格,运行该报表结果如下:

从运行结果可以看出:“B1”跟随“A1”的扩展而扩展,且继承了“A1”的条件。

自定义左父格关系

单元格“B2”的左父格自定义为单元格“A1”,该报表运行结果如下:

从运行结果可以看出:“B2”跟随“A1”的扩展而扩展,且继承了“A1”的条件。

无左父格关系

定义单元格“B2”左父格为无或者默认(由于“A1”和“B2”不在同一行,因此默认设置时“B2”实际上也是没有左父格的),运行报表后的结果如下:

从运行结果可以看出:“A1”和“B2”各自分别扩展;“B2”没有跟随“A1”的扩展而扩展,也没有继承“A1”的条件。

默认上父格关系

单元格“A1”、“A2”父子格均按默认设置,即“A2”的上父格为“A1”。运行该报表结果如下:

从运行结果可以看出:“A2”跟随“A1”的扩展而扩展,且继承了“A1”的条件。

自定义上父格关系

通过自定义单元格“B2”的上父格为单元格“A1”,使单元格“A1”和单元格“B2”之间构成上父子格关系。运行该报表结果如下:

从运行结果可以看出:“B2”跟随“A1”的扩展而扩展,且继承了“A1”的条件。

无上父格关系

根据设置单元格“B2”无上父格,即“A1”和“B2”没有形成上父子格关系。运行该报表结果如下:

从运行结果可以看出:“A1”和“B2”各自分别扩展;“B2”没有跟随“A1”的扩展而扩展,也没有继承“A1”的条件。

混合父格

其中,单元格“A1”纵向(按行向下)扩展,父子格默认设置;单元格“B1”横向(按列向右)扩展,左父格自定义为“A1”,父子格默认设置;单元格“C1”按行向下扩展,父子格默认设置。运行该报表结果如下:

自定义分组

复杂报表除了支持常规分组之外,还支持自定义分组。在定义数据列时把数据分组设置为“自定义”,然后可以通过点击“添加分组”来创建自定义分组。我们可以以角色号作为分组标准分成三组,分别为:角色小于等于10为一组,角色号介于10至20之间为二组,角色大于20为三组,如下图所示:

条件格式

复杂报表支持条件格式功能,即可通过设置条件来格式化单元格格式。设置的方法是:把光标移到数据列,然后点击工具栏的“条件格式”功能,即可设置条件格式,如下图所示:

条件格式由条件和格式组成,一个数据列可以设置多个条件格式,例如某报表销售额条件格式设置如下图:

表达式详解

单元格表达式

单元格表达式直接在单元格中定义,例如:=sum(A1:A2),类似MS Excel计算公式。当前版本支持以下函数:

ABS、ACOS、ACOSH、AND、ASIN、ASINH、ATAN、ATAN2、ATANH、AVERAGE、AVERAGEA、COS、COSH、COUNT、COUNTA、COUNTBLANK、COUNTIF、DATE、DAY、DOLLAR、EXP、FACT、INT、IF、LN、LOG、LOG10、MAX、MIN、MOD、MONTH、NOT、NOW、ODD、OR、PI、POWER、RADIANS、RAND、ROUND、ROUNDDOWN、ROUNDUP、SIGN、SIN、SINH、SQRT、SUM、SUMSQ、TAN、TANH、TIME、TODAY、TRUNC、YEAR、WEEKDAY、FALSE、TRUE、EVEN、TRIM、CEILING、FLOOR、CONCATENATE、DEGREES、FIXED、HOUR、MINUTE、SECOND、ISEVEN、ISODD、ISBLANK、ISNA、ISLOGICAL、ISERR、ISERROR、ISNONTEXT、ISNUMBER、ISTEXT、LEN、LEFT、RIGHT、MID、LOWER、UPPER、SUMIF、COUNTIF、AVERAGEIF、HLOOKUP、VLOOKUP、RANK

每个函数具体如何应用,请参考EXCEL函数帮助文档。

数据列筛选条件表达式

数据列筛选条件表达式由函数、算术运算符、关系运算符以及逻辑运算符构成。

  • 算术运算符包含:+、-、*、/、MOD(取余);

  • 关系运算符包含:=、\<>、\<、\<=、>=、>、LIKE(形如)、IN(属于)、NOTIN(不属于)、BETWEEN(介于)、ISNOTNULL(有值)、ISNULL(无值)

  • 逻辑运算符包含:&&(与)、||(或)、!(非)

  • 函数包含以下几大类:

    • 数值(含货币)函数

    • 日期和时间函数

    • 字符串函数

    • 集合函数

    • 转换函数

    • 类型不定函数

    • 系统函数

    • 常量

数值(含货币)函数

FLOOR(\<数值表达式>)

此函数返回数值表达式的整数部分。例如:FLOOR(125.34) 返回结果为:125。参数类型必须是数值型或者货币型。

ROUND(\<数值表达式>,整数)

此函数整数部分规定保留的小数点位数。例如:ROUND (125.256,2) 返回结果为:125.26。

RAND()

返回一个0至1之间随机数。

ABS(\<数值表达式>)

此函数返回数值表达式的绝对值。例如:ABS (-125) 返回结果为:125。参数类型必须是数值型或者货币型。

日期表达式

YEAR(\<日期表达式>)

此函数返回日期表达式的年份值。例如:YEAR(#2007.1.28#) 返回结果为:2007。

MONTH(\<日期表达式>)

此函数返回日期表达式的月份值。例如:MONTH(#2007.1.28#) 返回结果为:1。

DAY(\<日期表达式>)

此函数返回日期表达式的天数。例如:DAY(#2007.1.28#) 返回结果为:28。

QUARTER(\<日期表达式>)

此函数返回日期表达式的季度值。例如:QUARTER(#2007.1.28#) 返回结果为:1。

WEEK(\<日期表达式>)

此函数返回日期表达式的周数。例如:WEEK(#2007.1.28#) 返回结果为:4。

DAYOFWEEK(\<日期表达式>)

此函数返回日期表达式的星期数。注:星期日返回1,星期一返回2,依次类推。

例如:DAYOFWEEK (#2007.1.28#) 返回结果为:1

HOUR(\<日期表达式>)

此函数返回日期表达式的小时数。例如:HOUR(#2007.1.28 09:59:42#) 返回结果为:9

MINUTE(\<日期表达式>)

此函数返回日期表达式的分钟数。例如:MINUTE(#2007.1.28 09:59:42#) 返回结果为:59。

SECOND(\<日期表达式>)

此函数返回日期表达式的秒数。例如:SECOND(#2007.1.28 09:59:42#) 返回结果为:42。

THISDATE

此函数返回当前日期。

THISYEAR

此函数返回当前年份值。

THISQUARTER

此函数返回当前季度值。

THISMONTH

此函数返回当前月份值。

THISWEEK

此函数返回当前周数。

THISDAYOFWEEK

此函数返回当前星期数。注:星期日返回1,星期一返回2,依次类推

THISHOUR

此函数返回当前时间小时部分。

THISMINUTE

此函数返回当前时间分钟部分。

THISSECOND

此函数返回当前时间秒部分。

YEARBETWEEN(\<日期表达式1>,\<日期表达式2>)

此函数返回日期表达式1到日期表达式2的年份值。例如:YEARBETWEEN(#2005.07.03#,#2007.07.28#) 返回结果为:2。

MONTHBETWEEN(\<日期表达式1>,\<日期表达式2>)

此函数返回日期表达式1到日期表达式2的月份值。例如:MONTHBETWEEN(#2007.01.28#,#2007.07.28#) 返回结果为:6。

DAYBETWEEN(\<日期表达式1>,\<日期表达式2>)

此函数返回日期表达式1到日期表达式2的天数。例如:DAYBETWEEN(#2007.01.03#,#2007.01.28#) 返回结果为:25。

QUARTERBETWEEN(\<日期表达式1>,\<日期表达式2>)

此函数返回日期表达式1到日期表达式2的季度值。例如:QUARTERBETWEEN(#2007.01.03#,#2007.07.28#) 返回结果为:2。

WEEKBETWEEN(\<日期表达式1>,\<日期表达式2>)

此函数返回日期表达式1到日期表达式2的周数。例如:WEEKBETWEEN(#2007.01.03#,#2007.01.28#) 返回结果为:3。

HOURBETWEEN(\<日期表达式1>,\<日期表达式2>)

此函数返回日期表达式1到日期表达式2的小时值。

例如:HOURTWEEN(#2007.01.03 09:59:42#,#2007.01.24 10:59:42#) 返回结果为:1

MINUTEBETWEEN(\<日期表达式1>,\<日期表达式2>)

此函数返回日期表达式1到日期表达式2的分钟值。

例如:MINUTEBETWEEN(#2007.01.03 09:59:42#,#2007.01.24 10:59:42#) 返回结果为:60

SECONDBETWEEN (\<日期表达式1>,\<日期表达式2>)

此函数返回日期表达式的秒部分。例如:SECONDBETWEEN(#2007.1.28 09:59:42#) 返回结果为:42

ADDYEAR(\<日期表达式>,整数)

此函数返回日期表达式增加指定年数后的日期值。例如:ADDYEAR(#2005.07.03#,2) 返回结果为:#2007.07.03#。

ADDMONTH(\<日期表达式>,整数)

此函数返回日期表达式增加指定月数后的日期值。例如:ADDMONTH(#2007.07.03#,2) 返回结果为:#2007.09.03#。

ADDDAY(\<日期表达式>,整数)

此函数返回日期表达式增加指定日数后的日期值。例如:ADDDAY(#2005.07.03#,2) 返回结果为:#2005.07.05#。

ADDQUARTER(\<日期表达式>,整数)

此函数返回日期表达式增加指定季节数后的日期值。例如:ADDQUARTER(#2007.01.03#,2) 返回结果为:#2007.07.03#。

ADDWEEK(\<日期表达式>,整数)

此函数返回日期表达式增加指定周数后的日期值。例如:ADDWEEK(#2007.01.03#,3) 返回结果为:#2007.01.24#。

ADDHOUR(\<日期表达式>,整数)

此函数返回日期表达式增加指定小时后的日期值。例如:ADDHOUR(#09:59:42#,1) 返回结果为:#10:59:42#。

ADDMINUTE(\<日期表达式>,整数)

此函数返回日期表达式增加指定分钟后的日期值。例如:ADDMINUTE(#09:59:42#,2) 返回结果为:#10:01:42#。

ADDSECOND (\<日期表达式>,整数)

此函数返回日期表达式增加指定秒后的日期值。例如:ADDSECOND (#09:59:42#,1) 返回结果为:#09:59:43#。

字符串函数

CONCAT(\<字符串表达式1>,\<字符串表达式2>,...,\<字符串表达式n>)

此函数连接多个字符串。例如:CONCAT(“abc”,”def”,”g”) 返回结果为:”abcdefg”。

TRIM(\<字符串表达式>)

此函数截取字符串表达式左右两边多余空格。例如:TRIM(“ abc “) 返回结果为:”abc”。

LTRIM(\<字符串表达式>)

此函数截取字符串表达式左边多余空格。例如:LTRIM(“ abc “) 返回结果为:”abc “。

RTRIM(\<字符串表达式>)

此函数截取字符串表达式左边多余空格。例如:RTRIM(“ abc “) 返回结果为:” abc”。

SUBSTR(\<字符串表达式>,起始位,长度>)

此函数返回字符串表达式从[起始位]开始共[长度]个字符的子串。例如:SUBSTR(“abcd”, 2, 2) 返回结果为:”bc”。

STRLEN(\<字符串表达式>)

此函数返回字符串表达式所包含的字符个数。例如:STRLEN(“abcd你好”) 返回结果为:6。

LEFT(\<字符串表达式>,长度>)

此函数返回字符串表达式左边开始共[长度]个字符的子串。例如:LEFT(“abcd你好”, 5) 返回结果为:”abcd你”。

RIGHT(\<字符串表达式>,长度>)

此函数返回字符串表达式右边开始共[长度]个字符的子串。例如:左串(“abcd你好”, 3) 返回结果为:”d你好”。

STRPOS(\<字符串表达式1>,\<字符串表达式2>)

此函数返回字符串表达式1中首次出现字符串表达式2的位置,字符位置从1开始计数,未搜索到时返回0。 例如:STRPOS(“abcd你好”, “bcd”) 返回结果为:2。

REPLACE(\<待搜索的字符串表达式>,\<待查找的字符串表达式>,\<替换用的字符串表达式>)

此函数返回用替换用的字符串表达式替换待搜索的字符串表达式中出现的所有待查找的字符串表达式。例如:REPLACE(“abcdefghicde”,”cde”,”xxx”) 返回结果为:abxxxfghixxx。

REG(\<字符串表达式>,\<正则表达式>)

此函数返回字符串表达式是否满足正则表达式规则,满足返回1,否则返回0。例如:REG(“fo\no”, “\^fo\no$”) 返回结果为:1。

PINYINQUANMA(\<字符串表达式>)

返回\<字符串表达式>对应的拼音。 例如:PINYINQUANMA(“中国”),返回结果为:zhongguo。

PINYINJIANMA(\<字符串表达式>)

返回\<字符串表达式>对应的拼音简称。 例如:PINYINJIANMA(“中国”),返回结果为:zg。

集合函数

SET(\<表达式1>,\<表达式2>,\<表达式3>)

例如:集合(1,2,3,4),集合(”abc”,”cde”,”efg”)。

转换函数

STRTODATETIME (\<字符串表达式>)

把字符串表达式转换为日期型。

STRTOFLOAT(\<字符串表达式>)

把字符串表达式转换为数值型。

FLOATTOSTR(\<数值表达式>)

把数值表达式转换为字符型。

FLOATTODATETIME(\<数值表达式>)

把数值表达式转换为日期型。

DATETIMETOSTR(\<日期表达式>)

把日期表达式转换为字符型。

类型不定函数

IF THEN [ELSE] END

例如:IF 商品=“牛奶” THEN 0.02 ELSE 0.1 END,其中ELSE部分可以省略。

CASE IF cexpr1 THEN expr1 IF cexpr2 THEN expr2 [ELSE exprn] END

例如:CASE IF 商品=“牛奶” THEN 0.02

IF 商品=“面包” THEN 0.015

IF 商品=“电视” THEN 0.15

ELSE 0.1 END

GREATER (表达式1,表达式2)

返回表达式1、表达式2中的较大者。

LESS (表达式1,表达式2)

返回表达式1、表达式2中的较小者。

系统函数

LOGIN_UNIT

返回当前单位名称。

LOGIN_USER

返回当前登录系统的用户姓名。

LOGIN_DEPT

返回当前登录系统的用户所在的部门名称。

LOGIN_PRIV

返回当前登录系统的用户所在的角色名称。

WRITE_DEPT

返回当前数据的创建者所在部门名称。

WRITER

返回当前数据的创建者姓名。

WRITETIME

返回当前数据的创建日期。

SYSDATE

返回系统时间戳。

LOGIN_USER_ID

返回当前登录用户USER_ID。

LOGIN_DEPT_ID

返回当前登录用户所属部门DEPT_ID。

LONG_DEPT_NAME

返回当前登录用户所属部门长部门名称,例如:分公司一/财务部。

LOGIN_OTHER_PRIV

返回当前登录用户辅助角色ID。

LOGIN_UID

返回当前登陆用户UID。

常量

TRUE

FALSE

NULL

#2007.1.28#:

返回2007年1月28日。

#1.28#:

返回本年1月28日。注意:日期常量用"#” 引起来。

"张三”:

返回字符常量张三。注意:字符常量用””(英文半角双引号)引起来。

API接口

复杂报表除了提供上述标准化功能之外,还允许用户通过挂接自定义脚本插件以实现个性化报表需求。自定义脚本插件命名规则是XXX.php,其中XXX代表该报表的id(id可以通过查看编辑报表页面的地址而得到),存放路径为webroot\general\appbuilder\modules\report\plugin。用户自定义的脚本插必须实现以下函数:

/**

*这里实现个性化报表需求

*\@param $obj_custome_report 代表当前复杂报表对象

*\@return void

*/

function mydraw($obj_custom_report){

//按以下方式调用复杂报表接口

//$obj_custom_report->doCreateSheet(“我的报表”);

}

复杂报表处理引擎会在解析执行当前报表逻辑完成之后、最终输出报表之前判断本报表是否挂接有脚本插件,如果有,则包含该脚本文件并调用mydraw方法,并给它传递代表当前复杂报表对象的$obj_custom_report。复杂报表自定义脚本插件举例如下:

\<?
/**
*这里实现个性化报表需求
*\@param $obj_custome_report 代表当前复杂报表对象
*\@return void
*/
function mydraw($obj_custom_report){
//按以下方式调用复杂报表接口
//$obj_custom_report->doCreateSheet(“我的报表”);
$arr_align = ["horizontal" => "left", "vertical" => "center"];//对齐方式
$arr_border = ["style" => "thin", "color" => ["argb" => "FF000000"]];//
$arr_Borders = ["left"=>$arr_border, "right"=>$arr_border,"top"=>$arr_border,"bottom"=>$arr_border];// 边框
$arr_header = ["type"=>"solid", "color"=>["argb"=>"FF0000FF"]];//蓝色 表头背景色
$arr_odd = ["type"=>"solid", "color"=>["argb"=>"FF00FF00"]];//绿色 奇数行背景数
$arr_even = ["type"=>"solid", "color"=>["argb"=>"FFFFFF00"]];//绿色 偶数行背景色

//获得数据集所有数据
$arr_row = $obj_custom_report->doOpenDataset("人员情况");
if(!empty($arr_row)){
$i_col = 0;
foreach($arr_row[0] as $s_key => $s_val){ //输出表头

$obj_custom_report->doSetValue(0, $i_col, 1, iconv("GBK", "UTF-8", $s_key));
$obj_custom_report->doSetBorders(0, $i_col, 1, $arr_Borders);
$obj_custom_report->doSetFill(0, $i_col, 1, $arr_header);
$obj_custom_report->doSetAlign(0, $i_col, 1, $arr_align);
$i_col++;
}

$i_row = 2;
$i_prev_row = 2;
$s_prev_val = "";
foreach($arr_row as $row){//输出数据
$i_col = 0;
foreach($row as $s_val){
$obj_custom_report->doSetValue(0, $i_col, $i_row, iconv("GBK", "UTF-8", $s_val));
$obj_custom_report->doSetBorders(0, $i_col, $i_row, $arr_Borders);
if($i_row % 2 == 0){
$obj_custom_report->doSetFill(0, $i_col, $i_row, $arr_even);
}else{
$obj_custom_report->doSetFill(0, $i_col, $i_row, $arr_odd);
}
$obj_custom_report->doSetAlign(0, $i_col, $i_row, $arr_align);
if($i_col == 5){
if($s_prev_val != "" && $s_prev_val != $s_val){
if($i_prev_row \< $i_row - 1){
$obj_custom_report->doMergeCells(0, 5, $i_prev_row, 5, $i_row - 1);
}
$i_prev_row = $i_row;
}
$s_prev_val = $s_val;
}
$i_col++;
}
$i_row++;
}
if($i_prev_row \< $i_row - 1){
$obj_custom_report->doMergeCells(0, 5, $i_prev_row, 5, $i_row - 1);
}
}
}
?>

运行结果如下图所示:

复杂报表对象$obj_custom_report包含有丰富的接口供用户调用以实现个性化报表需求。复杂报表对象包含的API说明如下:

添加空白工作表

/**
* 添加空白工作表
* \@param string $sTitle
* \@param int $iSheetIndex 插入工作表位置(基于0)
* \@return MySheet 新工作表对象
*/
public function doCreateSheet($sTitle = "", $iSheetIndex = NULL)

拷贝工作表

/**
* 拷贝工作表
* \@param string $sSourceSheetName 待拷贝的工作表名称
* \@param string $sTargetSheetName 新工作表名称
* \@param int $iSheetIndex 插入工作表位置(基于0)
*/
public function doCopySheet($sSourceSheetName, $sTargetSheetName, $iSheetIndex = NULL)

删除工作表

/**
* 删除工作表
* \@param $iSheetIndex 工作表号(基于0)
*/
public function doRemoveSheet($iSheetIndex)

获得工作表号

/**
* 获得工作表号
* \@param $sSheetName 工作表名
* \@return int
*/
public function doGetSheetIndex($sSheetName)

获得工作表名

/**
* 获得工作表名
* \@param $sSheetName 工作表名
* \@return string
*/
public function doGetSheetName($iSheetIndex)

删除工作表

/**
* 删除工作表
* \@param $sSheetName 工作表名
*/
public function doRemoveSheetByName($sSheetName)

获得最大列号

/**
* 获得最大列号
* \@param $iSheetIndex 工作表号(基于0)
* \@return int
*/
public function doGetMaxColumn($iSheetIndex)

获得最大行号

/**
* 获得最大行号
* \@param $iSheetIndex
* \@return int
*/
public function doGetMaxRow($iSheetIndex)

获得单元格区间

/**
* 获得单元格区间
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@return array ["x1","y1","x2","y2"]
*/
public function doGetRegion($iSheetIndex, $iColumn = 0, $iRow = 1)

获得字体信息

/**
* 获得字体信息
* underline: none double doubleAccounting single singleAccounting
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@return array
*/
public function doGetFont($iSheetIndex, $iColumn = 0, $iRow = 1)

设置字体信息

/**
* 设置字体
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@param array $arrFont 字体信息,参考getFont
*/
public function doSetFont($iSheetIndex, $iColumn = 0, $iRow = 1, $arrFont = [])

获得对齐信息

/**
* 获得对齐方式
* 水平对齐:general left right center centerContinuous justify
* 垂直对齐:bottom top center justify
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@return array
*/
public function doGetAlign($iSheetIndex, $iColumn = 0, $iRow = 1)

设置对齐信息

/**
* 设置对齐方式
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@param array $arrFont 对齐方式,参考getAlign
*/
public function doSetAlign($iSheetIndex, $iColumn = 0, $iRow = 1, $arrAlign = [])

获得单元格边框

/**
* 获得单元格边框
* 对角线方向:const DIAGONAL_NONE = 0; const DIAGONAL_UP = 1; const DIAGONAL_DOWN = 2;const DIAGONAL_BOTH = 3;
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@return array
*/
public function doGetBorder($iSheetIndex, $iColumn = 0, $iRow = 1)

设置单元格边框

/**
* 设置单元格边框
* 对角线方向:const DIAGONAL_NONE = 0; const DIAGONAL_UP = 1; const DIAGONAL_DOWN = 2;const DIAGONAL_BOTH = 3;
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@param array $arrBorders: ["left","right","top","bottom","diagonal","diagonaldirection","allborders"]
*/
public function doSetBorders($iSheetIndex, $iColumn = 0, $iRow = 1, $arrBorders = [])

获得单元格填充方式

/**
* 获得单元格填充方式
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@return array
*/
public function doGetFill($iSheetIndex, $iColumn = 0, $iRow = 1)

设置单元格填充方式

/**
* 设置单元格填充方式
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@param array $arrFills 格式参考getFill
*/
public function doSetFill($iSheetIndex, $iColumn = 0, $iRow = 1, $arrFills = [])

获得单元格数据格式化方式

/**
* 获得单元格数据格式化方式
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@return array
* code值为:General、\@、0、0.00、#,##0.00、#,##0.00-、0%、0.00%、yyyy-mm-dd、yy-mm-dd、dd/mm/yy、d/m/y、d-m-y、d-m、m-y、mm-dd-yy、d-mmm-yy、d-mmm、mmm-yy、m/d/yy h:mm、d/m/y h:mm、h:mm AM/PM、h:mm:ss AM/PM、h:mm、h:mm:ss、mm:ss、h:mm:ss、i:s.S、h:mm:ss;\@、yy/mm/dd;\@、$#,##0.00-、$#,##0-、[$EUR ]#,##0.00-
*/
public function doGetNumberFormat($iSheetIndex, $iColumn = 0, $iRow = 1)

设置单元格数据格式化方式

/**
* 设置单元格格式化方式
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iRow 行号(基于1)
* \@param array $arrFormat
*/
public function doSetNumberFormat($iSheetIndex, $iColumn = 0, $iRow = 1, $arrFormat = [])

获得列宽度

/**
* 获得列宽度
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@return int
*/
public function doGetColumnWidth($iSheetIndex, $iColumn = 0)

设置列宽度

/**
* 设置列宽度
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param int $iWidth 宽度
*/
public function doSetColumnWidth($iSheetIndex, $iColumn = 0, $iWidth = 0)

获得行高度

/**
* 获得行高度
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iRow 行号(基于1)
* \@return int
*/
public function doGetRowHeight($iSheetIndex, $iRow = 1)

设置行高度

/**
* 设置行高度
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iRow 行号(基于1)
* \@param int $iWidth 宽度
*/
public function doSetRowHeight($iSheetIndex, $iRow = 1, $iHeight = 0)

获得列是否可视

/**
* 获得列是否可视
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@return boolean
*/
public function doGetColumnVisible($iSheetIndex, $iColumn = 0)

设置列是否可视

/**
* 设置列是否可视
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 列号(基于0)
* \@param boolean $bVisible 是否可视
*/
public function doSetColumnVisible($iSheetIndex, $iColumn = 0, $bVisible = false)

获得行是否可视

/**
* 获得行是否可视
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iRow 行号(基于1)
* \@return boolean
*/
public function doGetRowVisible($iSheetIndex, $iRow = 0)

设置行是否可视

/**
* 设置行是否可视
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iRow 行号(基于1)
* \@param boolean $bVisible 是否可视
*/
public function doSetRowVisible($iSheetIndex, $iRow = 0, $bVisible = false)

合并单元格

/**
* 合并单元格
* \@param $iSheetIndex 工作表号(基于0)
* \@param $iStartCol 起始列号(基于0)
* \@param $iStartRow 起始行号(基于1)
* \@param $iEndCol 终止列号(基于0)
* \@param $iEndRow 终止行号(基于1)
*/
public function doMergeCells($iSheetIndex, $iStartCol, $iStartRow, $iEndCol, $iEndRow)

取消合并单元格

/**
* 取消合并单元格
* \@param $iSheetIndex 工作表号(基于0)
* \@param $iStartCol 起始列号(基于0)
* \@param $iStartRow 起始行号(基于1)
* \@param $iEndCol 终止列号(基于0)
* \@param $iEndRow 终止行号(基于1)
*/
public function doUnmergeCells($iSheetIndex, $iStartCol, $iStartRow, $iEndCol, $iEndRow)

插入行

/**
* 插入行
* \@param $iSheetIndex 工作表号(基于0)
* \@param $iBefore 插入行位置(基于1)
* \@param $iNumRows 插入行数
*/
public function doInsertNewRowBefore($iSheetIndex, $iBefore = 1, $iNumRows = 1)

插入列

/**
* 插入列
* \@param $iSheetIndex 工作表号(基于0)
* \@param $iBefore 插入列位置(基于1)
* \@param $NumColumns 插入列数
*/
public function doInsertNewColumnBefore($iSheetIndex, $iBefore = 0, $NumColumns = 1)

删除行

/**
* 删除行
* \@param $iSheetIndex 工作表号(基于0)
* \@param $iRow 删除行位置(基于1)
* \@param int $iNumRows 删除行数
*/
public function doDeleteRow($iSheetIndex, $iRow, $iNumRows = 1)

删除列

/**
* 删除列
* \@param $iSheetIndex 工作表号(基于0)
* \@param int $iColumn 删除列位置(基于0)
* \@param int $iNumColumns 删除列数
*/
public function doDeleteColumn($iSheetIndex, $iColumn = 0, $iNumColumns = 1)

获得单元格数据

/**
* 获得单元格数据
* \@param $iSheetIndex 工作表号(基于0)
* \@param $iColumn 列号(基于0)
* \@param $iRow 行号(基于1)
* \@return mixed
*/
public function doGetValue($iSheetIndex, $iColumn, $iRow)

设置单元格数据

/**
* 设置单元格数据
* \@param $iSheetIndex 工作表号(基于0)
* \@param $iColumn 列号(基于0)
* \@param $iRow 行号(基于1)
* \@param mixed $pValue 数值
*/
public function doSetValue($iSheetIndex, $iColumn, $iRow, $pValue)

设置单元格日期时间数据

/**
* 设置单元格日期时间数据
* \@param $iSheetIndex 工作表号(基于0)
* \@param $iColumn 列号(基于0)
* \@param $iRow 行号(基于1)
* \@param $iYear 年
* \@param $iMonth 月
* \@param $iDay 日
* \@param $iHour 小时
* \@param $iMinute 分钟
* \@param $iSecond 秒
*/
public function doSetDateTimeValue($iSheetIndex, $iColumn, $iRow, $iYear, $iMonth, $iDay, $iHour, $iMinute, $iSecond)

获得本地数据库连接

/**
* 获得本地数据库连接
* \@return \yii\db\Connection
*/
public function doGetDb()

根据数据库连接操作数据库,常见方法举例如下:

$command = $connection->createCommand('SELECT * FROM post');

$posts = $command->queryAll();

$post = $command->queryOne();

$command = $connection->createCommand('UPDATE post SET status=1');

$command->execute();

$command = $connection->createCommand('SELECT * FROM post WHERE id=:id');

$command->bindValue(':id', $_GET['id']);

$post = $command->query();

获得数据源里配置的数据库连接

/**
* 获得第三方数据库访问链接功能
* \@param $s_sername 数据源名称
* \@param string $s_db 数据库名称
* \@return mixed|null 数据库连接
*/
public function doGetOtherDB($s_sername, $s_db = "")

获得参数值

/**
* 获得参数值
* \@return array
*/
public function doGetParams()

打开数据集(返回数据集所有数据)

/**
* 打开数据集
* \@param $s_dataset 数据集名称
* \@return array
*/
public function doOpenDataset($s_dataset)

results matching ""

    No results matching ""