1. 报表配置

1.1. 配置入口

系统管理>报表设计

1.2. 报表介绍

报表主要由①输入模板、 ②展示模板、 ③报表数据(包含标签,开发中)两块组成,在实际应用的时候,又会涉及到、④权限、 ⑤缓存、 ⑥推送以及 ⑦定时任务,所以,在应用过程中,通常需要实施人员对数据库以及实际业务比较了解。

1.2.1. 输入模板

输入模板配置,是配置给报表传递参数的页面,类似业务单的查询,如下例:

<div style="width:100%;height:auto;margin-left:30px;;margin-top:30px;">
    <table class="tablesimpleline excel" style="width: 500px;">
        <tbody>
            <tr class="firstRow">
                <td style="text-align: right; width: 120px;" html="启动会主题">
                    启动会主题
                </td>
                <td name="qdkzt" editable="0" readonly="readonly" source="g_picksource_depart" style="" caption="启动会主题" type="string" datasource="启动会流程" pick="0"></td>
            </tr>
            <tr style="display:none">
                <td html="启动会主题" colspan="1" rowspan="1" style="text-align: right;">
                    启动会ordid
                </td>
                <td html="启动会主题" colspan="1" rowspan="1" name="qdkordid" editable="0" style="" caption="启动会ordid" type="int"></td>
            </tr>
        </tbody>
    </table>
    <div style="margin-top:20px">
        <button onclick="genReport()" type="button" class="btn btn-default" style="width:120px" html="生成报表">生成报表</button>
        <button onclick="downloadhtml()" type="button" class="btn btn-default" style="width:120px;margin-left:30px;" html="下载报表">下载报表</button>
    </div>
</div>
1. 根据条件生成报表,genReport();
2. 弹出报表,实现穿透。如:popReport(报表ID,标题,参数)
其中,第一个参数表示报表Id,第二个参数表示弹窗标题。参数怎么传递?
其中报表参数可以是JSON对象如:{username:"张三"}也可以是字符串如username=张三
3. downloadhtml为自定义实现前端下载的js代码

1.2.2. 展示模板

显示模板指的是将数据查询出来后,在系统中以显示模板定义的html的样式将数据显示出来的HTML代码。代码中需要注意一些关键属性,系统将解释这些属性,以便实现不同的显示效果。

模板样式 说明
表格式 当显示模板为表格时,只需将要显示的字段以‘{字段名}’的方式放置html代码中,
运行是系统就会自动赋值,最终呈现为数据表格,具体样式参见报表设计的显示界面。
图表式 固定模板格式(参见图表配置)

展示模板即报表的呈现形式, 报表类型主要分为:

(1) 普通报表(mytable,支持分和下载)

参考mytable

(2) 交叉报表 (选用模板)

核心属性:
table:
有cross属性则认为是交叉报表,
cross: 可能的值有 2,3_1,3_2,4 分别表示 二维,三维(横二纵一),三维(纵二横一),四维
dfield: 数据字段名称
vfields: 纵向字段名称
hfields: 横向数据字段

(3) 图表 (ebstype="chart" charttype="bar/pie/line")

关键属性:
id:如果数据源是SQL的结果,则需要在SQL中返回此id
ebstype: 如果这个属性值是"chart"则作为图表
caption:标题
charttype:图表类型 pie/line/bar
legend: 图列开关 yes
xfield: X轴字段名称
yfield: Y轴字段名称
dfield: 数据字段名称
source: 这个属性只有在选用交叉报表作为数据源的时候生效 格式为 交叉报表ID.[v|h|haggr|vaggr]
(垂直方向数据|水平方向数据|垂直方向聚集|水平方向聚集)

1.2.3. 报表数据

由于存在同一个页面有多个报表的情况,所以新增了一个字段 tableid(结果集需要是第一个字段),查询的时候需要绑定 前端的id到 tableiid上页面才能正常显示:如

select 'tb_xxx' tableid,* from mps_login

报表如需分页(只支持一维报表):使用伪命令“makeUpPagingSql”,也可使用全代码方式(建议)

makeUpPagingSql(
'tb_report1',                       --前端对象的ID
'cu_id',                            --主键
'cu_id,cu_callname,cu_mobile',      --要查询的字段列表
'mps_login',                        --表和查询条件
'cu_id',                            --排序字段
'mps_login where objid=cu_id order by cu_id', --后续页面数据源
1,                                  --每一页的大小
10                                  --最大页数
)

分页且包含多表多条件(尤其是条件复杂的时候),建议使用完全代码方式实现,即不用上述伪命令实现。实现方式只需包含示例中"一个table模板数据集包含以下代码"部分代码在”报表数据(sql)中“

注意,本方法是临时解决问题的办法,后续版本会优化本功能,从而不再以完全代码方式实现(2018-12-5);tableid 该字段必须是第一列。
create PROCEDURE [dbo].[report_11_data]
  @cmpid int,
  @branchid int,
  @userdpid int,
  @userotid int,
  @useruid int,
  /*@tableid 首次进入为_none_*/
  @tableid varchar(8000),
  /*@objids 下一页IDs,首次进入为_none_,*/
  @objids varchar(8000),
  /*@pagesize 每页数据数量,*/
  @pagesize int,
  ...... --自己的定义查询参数,这些参数在点击第n页时,不会传递过来,所以逻辑处理时需要判断
AS
BEGIN
  set nocount on

-->>>>>>>临时表,多个table模板数据集,系统配置时不需要“将公用临时表”放入系统配置
declare @dataIds table(objid int)
if @objids!='_NONE' and @objids!='_none_' and @objids!=''
insert into @dataI ds(objid)
select value from dbo.fn_split_int(@objids)
--<<<<<<<<<<<<<<<<<<

-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
--一个table模板数据集包含以下代码
--以下是我们写报表时的代码,只需将本代码块修改后放入”报表数据(SQL)“中即可
-->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
create table #temp (
            ord_id bigint ,
            ord_branch varchar(100),
            ord_date datetime,
            ord_creator varchar(100),
            ord_xzbm varchar(100),
            ord_xzmd varchar(100),
            ord_bmtr varchar(100)
        )
--没办法,复杂临时表查询时,暂时只能通过判断@objids= '_none_'写入,
--因为在点击下一页时后端不会传递需要的所有的自定义参数
if(@objids= '_none_')
begin  
    insert into #temp (ord_id,ord_branch,ord_date,ord_creator,ord_xzbm,ord_xzmd,ord_bmtr)
    select ord_id,ord_branch,ord_date,ord_creator,ord_xzbm,ord_xzmd,ord_bmtr
    from order_247
    where ord_status != '已作废'
    and charindex('临',ord_no) = 0
    and ({qry_fgs} = '' or ord_branch = {qry_fgs})
    and ({qry_creator} = '' or ord_creator = {qry_creator})
    and (ord_date >= {qry_date1} + ' 00:00:00' and ord_date <= {qry_date2} + ' 23:59:59')   
    order by ord_id desc  
end

--@tableid 指要加载数据的table的ID属性值
if @tableid='tb_report1'
begin

  --若是下载,前端自动传入pagesize = 10000
  if @pagesize=10000
  begin
       select * from #temp
  end
  --若是分页,
  --1.若是首次加载,则@objids ='_none_'
  --2.若是下一页操作,则前端会自动传入nextpage的ID,如:objids = "ord_id,ord_id,ord_id,ord_id"
  if @objids!='_none_'
  begin
        --注意,这儿用的是物理表order_247,不是临时表
        select  ord_id,ord_branch,ord_date,ord_creator,ord_xzbm,ord_xzmd,ord_bmtr
        from order_247,@dataIds
        where objid= ord_id
        order by ord_id desc  

     return
  end
end

--若是分页,且首次加载,即@objids ='_none_',执行以下取数据逻辑
--获取总数
select  count(*)  dataCount from #temp

--获取分页最多显示的数量
select  top 200 ord_id as dataIds
  from #temp
  order by ord_id desc

--获取第一页显示的数量
select  top 20 'tb_report1' tableid ,*
from #temp
order by ord_id desc
end
--<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
--一个table模板数据集包含以下代码
--<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
END

1.2.4. 报表权限

待完善文档

1.2.5. 报表缓存

待完善文档

1.2.6. 报表推送

待完善文档

1.2.7. 定时任务

待完善文档

1.3. 菜单入口

1.3.1. 单独报表入口

​ /commons/rpt_{rpt_id},其中{rpti_d}指某个报表的ID

1.3.2. 统一报表入口

​ /sys/report/report_category.html

1.3.3. 报表索引入口

​ /sys/report/report_index.html

注意,此刻需要在模块首页中模板中设置如下内容手机端才能正常使用(待后续优化)

<div addbyebs="true" ebstype="flowicon">
    <br/>
</div>

1.4. 报表打印

只支持单页打印,即本职是调用浏览器打印功能

显示模板-js

//Print.js
(function(window,document){var Print=function(dom,options){if(!(this instanceof Print))return new Print(dom,options);this.options=this.extend({noPrint:'.no-print',onStart:function(){},onEnd:function(){}},options);if((typeof dom)==="string"){this.dom=document.querySelector(dom);}else{this.dom=dom;}
this.init();};Print.prototype={init:function(){var content=this.getStyle()+this.getHtml();this.writeIframe(content);},extend:function(obj,obj2){for(var k in obj2){obj[k]=obj2[k];}
return obj;},getStyle:function(){var str="",styles=document.querySelectorAll('style,link');for(var i=0;i<styles.length;i++){str+=styles[i].outerHTML;}
str+="<style>"+(this.options.noPrint?this.options.noPrint:'.no-print')+"{display:none;}</style>";return str;},getHtml:function(){var inputs=document.querySelectorAll('input');var textareas=document.querySelectorAll('textarea');var selects=document.querySelectorAll('select');for(var k in inputs){if(inputs[k].type=="checkbox"||inputs[k].type=="radio"){if(inputs[k].checked==true){inputs[k].setAttribute('checked',"checked")}else{inputs[k].removeAttribute('checked')}}else if(inputs[k].type=="text"){inputs[k].setAttribute('value',inputs[k].value)}}
for(var k2 in textareas){if(textareas[k2].type=='textarea'){textareas[k2].innerHTML=textareas[k2].value}}
for(var k3 in selects){if(selects[k3].type=='select-one'){var child=selects[k3].children;for(var i in child){if(child[i].tagName=='OPTION'){if(child[i].selected==true){child[i].setAttribute('selected',"selected")}else{child[i].removeAttribute('selected')}}}}}
return this.dom.outerHTML;},writeIframe:function(content){var w,doc,iframe=document.createElement('iframe'),f=document.body.appendChild(iframe);iframe.id="myIframe";iframe.style="position:absolute;width:0;height:0;top:-10px;left:-10px;";w=f.contentWindow||f.contentDocument;doc=f.contentDocument||f.contentWindow.document;doc.open();doc.write(content);doc.close();this.toPrint(w,function(){document.body.removeChild(iframe)});},toPrint:function(w,cb){var _this=this;w.onload=function(){try{setTimeout(function(){w.focus();typeof _this.options.onStart==='function'&&_this.options.onStart();if(!w.document.execCommand('print',false,null)){w.print();}
typeof _this.options.onEnd==='function'&&_this.options.onEnd();w.close();cb&&cb()});}catch(err){console.log('err',err);}}}};window.Print=Print;}(window,document));

/*打印指定内容,div_report_display未要打印的对象*/
function printContent(){
    Print('#div_report_display', {
        onStart: function () {
          console.log('onStart', new Date())
        },
        onEnd: function () {
          console.log('onEnd', new Date())
        }
      })
}

results matching ""

    No results matching ""