示例说明
该示例背景:电子表格中存在一个下拉多选参数,用户导出excel时,不管用户在浏览端有没有勾选参数值,导出时需要将所有的数据一并导出并按照发货城市不同存放在不同的Sheet页中。(比如用户只勾选了天津,导出时,导出所有城市的数据,每个城市一个sheet)
注:最好城市就是左父格
使用宏代码实现前的效果如下:
实现思路:导出Excel时,将城市参数的值设为所有城市(通过在客户端宏中重写buildParamsInfo ),然后使用服务端宏将一个sheet按城市名拆分成多个sheet,sheet页中只保留对应城市的数据。
使用宏代码实现后的效果如下:
版本及客户端说明
1.smartbi版本:V9
2.客户端:PC
3.浏览器:IE11、谷歌浏览器(Chrome)
设置方法
1、首先在电子表格设计器(Microsoft Office Excel)中,创建电子表格报表。
2、在浏览器中,切换到“分析展现”页面,在左侧的资源树上找到对应的电子表格报表,右键该节点“编辑宏”进入报表宏编辑界面。
3、使用客户端宏将excel导出时的城市参数值设为所有城市:在报表宏界面新建客户端模块。在弹出的新建模块对话框中,选择对象为spreadSheetReport、事件为onRender、并把下面宏代码复制到代码编辑区域。
4、使用服务端宏将一个sheet按城市名拆分成多个sheet:在报表宏界面新建服务端模块。在弹出的新建模块对话框中,选择对象为spreadSheetReport、事件为onBeforeOutput、并把下面宏代码复制到代码编辑区域。
客户端宏类型
类型 | 对象 | 事件 |
---|---|---|
ClientSide | spreadsheetReport | onRenderReport |
客户端宏代码
/** * 当是导出excel时,将城市的参数值设为所有城市,这样导出的数据才是全部城市的数据 * */ function main(spreadsheetReport) { if (spreadsheetReport.exportMenu) { spreadsheetReport.exportMenu.onCloseUp.unsubscribe(spreadsheetReport.doExportMenuCloseUp, spreadsheetReport); } //重写doExportMenuCloseUp方法,添加标示 spreadsheetReport.doExportMenuCloseUp_old0224 = spreadsheetReport.doExportMenuCloseUp; spreadsheetReport.doExportMenuCloseUp = function(exportType) { //debugger; this.exportZhi = "EXCEL2007"; this.doExportMenuCloseUp_old0224(exportType); } //重新注册新的事件 if (spreadsheetReport.exportMenu) { spreadsheetReport.exportMenu.onCloseUp.subscribe(spreadsheetReport.doExportMenuCloseUp, spreadsheetReport); } //重写buildParamsInfo,组合参数 spreadsheetReport._old_buildParamsInfo = spreadsheetReport.buildParamsInfo; spreadsheetReport.buildParamsInfo = function(fromButton) { //debugger; if (!this.params) return null; var ps = this._old_buildParamsInfo(fromButton); if (!ps) return; for (var i = 0; i < ps.length; i++) { //拼参数值,将多个参数传给服务端 if (this.exportZhi == "EXCEL2007" && ps[i].name == "发货城市") { var id = ps[i].id; var parameterPanelId = this.paramPanelObj.clientId; var a = this.paramPanelObj.getParamStandbyValue(id, parameterPanelId); var val = ""; var disVal = ""; for (var j = 0; j < a.length; j++) { val += "," + a[j][0]; disVal += "," + a[j][1]; }; val = val.substring(1); disVal = disVal.substring(1); ps[i] = { id: ps[i].id, name: ps[i].name, value: val, displayValue: disVal } } } this.exportZhi = null; return ps; } }
服务端宏类型
类型 | 对象 | 事件 |
---|---|---|
ServerSide | spreadsheetReport | onBeforeOutput |
服务端宏代码
/** *执行逻辑: * 1,根据城市参数,将每个城市创建一个sheet,并且获取其在原始报表中的起始/结束行 * 2,原始报表sheet内容copy到目标城市所在sheet,并删除初目标城市之外的数据 */ function main(spreadsheetReport) { spreadsheetReport.cacheable = false; //判断导出类型是否为Excel if (spreadsheetReport.outputType != "EXCEL2007") return; var cells = spreadsheetReport.workbook.worksheets.get(0).cells; var sourWorkbook = spreadsheetReport.workbook.worksheets.get(0); var rows = cells.rows.count; var columns = cells.getMaxDataColumn(); var paras = spreadsheetReport.getParameterDisplayValue("发货城市"); //logger.debug("参数:" + paras); var vals = paras.split(","); var worksheets = spreadsheetReport.workbook.worksheets; if (vals.length > 0) { for (var i = 0; i < vals.length; i++) { var target_worksheet = worksheets.add(vals[i].replace('\'', '').replace('\'', '')); var startRowNum = 0; var endRowNum = 0; var arr = new Array(); for (var j = 0; j < rows; j++) { for (var k = 0; k < columns; k++) { if(endRowNum > 0){ break; } var cell2 = worksheets.get(0).cells.getCell(j, k); if (!cell2.getValue()) { continue; } if (cell2.getValue()) { var val = cell2.getValue(); var val2 = vals[i]; for (var n = 0; n < vals.length; n++) { if (arr.length <1 && val == vals[n]) { //所有分组的起始位置,便于拿到第一个分组的起始位置; arr.push(j); break; } } //获取指定城市名的起始行 if ((val == val2)) { startRowNum = j; var cell = spreadsheetReport.sheets[0].getCell(j, k); var range = worksheets.get(0).cells.get(cell.getCellPosition()).mergedRange; if (range && range.getRowCount() > 1) { endRowNum = j + range.getRowCount(); } else { endRowNum = j + 1; } break; } } } } //将源sheet拷贝到目标城市所在sheet,并且删除其他城市的数据 target_worksheet.copy(sourWorkbook); for (var m = target_worksheet.cells.rows.count; m >= 0; m--) { if (m > endRowNum - 1 || (m >= arr[0] && m < startRowNum)) { target_worksheet.cells.deleteRow(m); } } } spreadsheetReport.workbook.worksheets.removeAt(0); } }
关键对象总结
- 单元格的扩展属性,可通过mergedRange获取扩展的行数。
- 可通过deleteRow()方法删除sheet页上的行记录,一般最好从后面开始删。
- 通过spreadsheetReport.workbook.worksheets.removeAt()删除某个sheet。
- 创建sheet:spreadsheetReport.workbook.worksheets.add(sheetName)
- 将一个sheet页内容copy到另一个sheet:target_worksheet.copy(sourceSheet);
资源下载
报表资源:migrate.xml