润乾报表动态显示或者增加列的三种实现方式

开发报表期间,有时会遇到这样的需求,在列表类的报表中想动态的显示某些字段。

本文就来讨论一下如何实现上面的需求,大致可以分为两种方法,一是在设计报表时把所有的列都设置好,用隐藏列属性控制列的显示或者隐藏,二是用API的方式动态的增加列,用来显示需要显示的字段。

下面分别说一下两种方式的实现方法

一.可以使用润乾的datasetName.field( stringExp )及datasetName.fieldName( intExp )实现动态列报表

1、 使用eval(),通过动态解析并计算表达式,实现列的扩展;
2、 使用ds.colCount(),获得数据集的列数;
3、 使用ds.fieldName(),根据列号取数据集的列名。
使用这三个函数就能实现客户的需求了,具体做法如下:
我们使用demo中的“订单”这张表为例,SQL语法为:SELECT * FROM 订单,表中的单元格写法如图:
 润乾报表动态显示或者增加列的三种实现方式_第1张图片
最终调整单元格大小后,预览如下图:
 润乾报表动态显示或者增加列的三种实现方式_第2张图片

 二.在设计报表模板时,把所有的字段都设置好,用隐藏列属性根据条件控制列的显示或者隐藏。

如下报表


报表中含有10列,显示了10个字段,前4列是常规列,后6列是活动列。设置一个参数showColID,参数类型为字符串组,此参数用来接收需要显示列的列号,在隐藏列属性里写表达式“if(str(col()) in (@showColID),false,true)”。这个表达式只设置在5,6,7,8,9,10列的第一行中单元格的隐藏列属性就可以了,不用给每一列的所有单元格设置,那样会影响效率。

参数showColID的值为“6,8,9”,显示效果如下

润乾报表动态显示或者增加列的三种实现方式_第3张图片

此方法的优点:只在报表中设置,不用写程序就可以实现,实现方法比较简单容易。数据量大时可以启用缓存。

缺点:活动列中的字段默认情况下在数据集中要全部查询出来。只适用于上图中网格式报表,如果报表中含有卡片式表头,或者是行式报表,用上面方法就不能实现了。

二.API方法

如果是行式报表,上面的方法就不能实现,因为行式报表不支持隐藏列;或者是含有卡片式表头的普通报表,用上面的方法也不能实现,隐藏行后表头的内容有可能也被隐藏了。

如下面报表

润乾报表动态显示或者增加列的三种实现方式_第4张图片

实现原理:

先说一下含有卡片式表头的普通报表如何动态显示某些列呢?卡片式表头做在一个子表里,用嵌入式方式引用子报表,用API提供的方法增加列,用来显示需要显示的字段,这样数据区的宽度会增加,而卡片式表头区的宽度并没有增加,把数据区增加的宽度平均分配给卡片式表头区的每一列,这样就可以保持表头区和数据区宽度相同。

实现方法:

首先设计一个报表模板,只设计常规列就可以。

润乾报表动态显示或者增加列的三种实现方式_第5张图片

动态显示的列名、字段名、字段类型通过json方式传递给jsp,如下"{\"colAddField\" : [{\"dataSetName\" : \"ds1\",\"dataType\" : str,\"colAndField\" : \"货主邮政编码,货主邮政编码\"}, {\"dataSetName\" : \"ds1\",\"dataType\" : number, \"colAndField\" : \"运货费,运货费\"},{\"dataSetName\":\"ds1\" ,\"dataType\" : str, \"colAndField\":\"雇员ID,雇员ID\"}]}"

写个报表处理类,在类中用上面说的原理来实现增加列,如下

public static void  setReportDefine(ReportDefine rd,String colAndFieldStr) throwsJSONException{

       if(colAndFieldStr.length()>0){

           //设置报表单位为毫米

           rd.setUnit(ReportDefine.UNIT_MM);

           //得到A1单元格的颜色值

           CellLocation locationA1 = CellLocation.parse("A1");

           INormalCell cellA1 = rd.getCell(locationA1.getRow(), (short)locationA1.getCol());

           int colorValue = cellA1.getBBColor();

          

           int startRow = 2;                   //数据区开始行

           float numberColWidth = 25;         //数值型数据列宽

           float strColWidth = 30;            //字符串型数据列宽

           String numberShowFormat = "#0.00";  //数值型数据显示格式

           float addColTotalWidth = 0;        //所有增加列宽的总和

          

           JSONObject jsonObj = null;//Json对象

           JSONArray jsonArr = null;

           try {

              jsonObj = new JSONObject(colAndFieldStr);

              jsonArr = jsonObj.getJSONArray("colAddField");

           } catch (JSONException e) {

              e = new JSONException("传入的JSON数据格式错误");

           }

           int colNum = rd.getColCount();

           for(int i=0; i

              JSONObject tempObj = null;

              tempObj = jsonArr.getJSONObject(i);

              String colType = tempObj.get("dataType").toString(); //列类型

              //增加一列

              rd.addCol();

   

              INormalCell descCell = rd.getCell(startRow, (short)(colNum + i + 1));

              IByteMap colWidthByteMap = new ByteMap();

              colWidthByteMap.put(IColCell.WIDTH, numberColWidth);

              String tmpStr = tempObj.get("colAndField").toString();

              descCell.setValue(tmpStr.substring(0, tmpStr.indexOf(",")));

              IByteMap exp2 = new ByteMap();

              exp2.put(INormalCell.VALUE,tempObj.get("dataSetName") + "." + tmpStr.substring(tmpStr.indexOf(",")+1, tmpStr.length()));

             

              INormalCell fieldCell = rd.getCell(startRow + 1, (short)(colNum + i + 1));

              fieldCell.setExpMap(exp2);

             

              //设置列宽和单元格显示表达式

              IColCell newCol = rd.getColCell((short)(colNum + 1 + i));

              if("number".equals(colType)){

                  newCol.setColWidth(numberColWidth);

                  fieldCell.setFormat(numberShowFormat);

                  addColTotalWidth = addColTotalWidth + numberColWidth;

              }else if("str".equals(colType)){

                  newCol.setColWidth(strColWidth);

                  addColTotalWidth = addColTotalWidth + strColWidth;

              }

              //给新增加的列设置边框,并且设置内容水平对齐方式为居中

              descCell.setHAlign(INormalCell.HALIGN_CENTER);

              descCell.setLBStyle(INormalCell.LINE_SOLID);  //左边框

              descCell.setLBColor(colorValue);

              descCell.setTBStyle(INormalCell.LINE_SOLID);  //上边框

              descCell.setTBColor(colorValue);

              descCell.setBBStyle(INormalCell.LINE_SOLID);  //下边框

              descCell.setBBColor(colorValue);

              descCell.setRBStyle(INormalCell.LINE_SOLID);  //右边框

              descCell.setRBColor(colorValue);

             

              fieldCell.setHAlign(INormalCell.HALIGN_CENTER);

              fieldCell.setLBStyle(INormalCell.LINE_SOLID); //左边框

              fieldCell.setLBColor(colorValue);

              fieldCell.setTBStyle(INormalCell.LINE_SOLID); //上边框

              fieldCell.setTBColor(colorValue);

              fieldCell.setBBStyle(INormalCell.LINE_SOLID); //下边框

              fieldCell.setBBColor(colorValue);

              fieldCell.setRBStyle(INormalCell.LINE_SOLID); //右边框

              fieldCell.setRBColor(colorValue);

           }

          

           //处理子报表,给子报表平均增加列宽

           SubReportMetaData subReportMd = rd.getSubReportMetaData();

           int subReportNum = subReportMd.getSubReportCount();

           Context cxt = Context.getInitCtx();

           ServletContext application = cxt.getApplication();

           //得到存放报表的文件路径

           String reportPath = application.getRealPath(Context.getMainDir());

           if(subReportNum!=0){

              

              Area area = rd.getCell(1, (short)1).getMergedArea();

              area.setEndCol(rd.getColCount());

             

              SubReportConfig subReportConfig = subReportMd.getSubReportConfig(0);

              String reportUrl = subReportConfig.getURL();

              ReportDefine rdI = null;

               try {

                  //读取子报表

                  rdI = (ReportDefine) ReportUtils.read(reportPath + "/" + reportUrl);

              } catch (Exception e) {

                  e.printStackTrace();

              }

              //设置报表单位为毫米

              rdI.setUnit(ReportDefine.UNIT_MM);

             

              //给子报表平均增加列宽

              int subRdColNum = rdI.getColCount();

              for(int j=1; j<=subRdColNum; j++){

                  IColCell tempCol = rdI.getColCell((short)j);

                  float tempColWidth = tempCol.getColWidth();

                  tempCol.setColWidth(addColTotalWidth/subRdColNum + tempColWidth);

              }

             

              subReportConfig.setURLType(SubReportConfig.TYPE_CUSTOM);

              subReportConfig.setSubReportDefine(rdI);


你可能感兴趣的:(润乾报表)