示例说明
该示例背景:电子表格中存在一个下拉多选参数,不管用户在浏览端有没有勾选参数值,导出时是导出下拉参数所有参数值对应的数据(比如用户只勾选了山西省,导出时,导出所有省份的数据,每个省份一个sheet),还需要满足下面规则:同一个省份的数据是挨在一起的(最好省份就是左父格)
如下图所示:
实现思路:获取城市参数所有参数值,通过在客户端宏中重写buildParamsInfo 方法拼接参数值,服务端宏接收相应拼接的参数值,一个参数值对应一个sheet页,sheet页中只保留对应参数值的记录
最终实现效果如下:
版本及客户端说明
1.smartbi版本:V6.0
2.客户端:PC
3.浏览器:IE11、谷歌浏览器(Chrome)
设置方法
1、首先在电子表格设计器(Microsoft Office Excel)中,创建电子表格报表。
2、在浏览器中,切换到“定制 -> 宏管理”页面,在左侧的资源树上找到对应的电子表格报表,双击该节点进入报表宏编辑界面。
3、在报表宏界面新建客户端模块。在弹出的新建模块对话框中,选择对象为spreadSheetReport、事件为onRender、并把下面宏代码复制到代码编辑区域。
4、在报表宏界面新建服务端模块。在弹出的新建模块对话框中,选择对象为spreadSheetReport、事件为onBeforeOutput、并把下面宏代码复制到代码编辑区域。
宏类型
类型 | 对象 | 事件 |
---|---|---|
ClientSide | spreadsheetReport | onRender |
宏代码
function main(spreadsheetReport) { //重写doExportMenuCloseUp 方法,添加标示 spreadsheetReport.doExportMenuCloseUp = function(exportType) { //debugger; this.exportZhi = "EXCEL2007"; var typeId = (exportType && typeof exportType == "string") ? exportType : (this.exportMenu ? this.exportMenu.selectedId : null); if (!typeId) return; this.elemReportId.value = this.queryId; if (this.params && this.params.length > 0) { var ps = this.buildParamsInfo(true); if (!ps) return; if (util.encode) { this.elemParams.name = "paramsInfoEncode"; this.elemParams.value = util.coder.encode(encodeURIComponent(lang.toJSONString(ps))); } else { this.elemParams.value = lang.toJSONString(ps); } } this.elemType.value = typeId; this.elemClientId.value = this.clientId; this.elemRefreshForm.submit(); } //重写buildParamsInfo,组合参数 spreadsheetReport.buildParamsInfo = function(fromButton) { //debugger; if (!this.params) return null; var ps = []; for (var i = 0; i < this.params.length; i++) { var id = spreadsheetReport.params[i].id; var parameterPanelId = spreadsheetReport.paramPanelObj.clientId; var a = spreadsheetReport.paramPanelObj.getParamStandbyValue(id, parameterPanelId); if (this.hiddenParamValues && this.hiddenParamValues[this.params[i].id]) continue; var value; var displayValue; if (this.paramPanelObj) { value = this.paramPanelObj.getParamValue(this.params[i].id); if (value == "") value = this.paramPanelObj.getParamTagByParamId(this.params[i].id).param.value; if (value == "") { var noNull = lang.parseJSON(this.params[i].componentDefine).noNull; if (!noNull) { this.refreshing = false; this.showMaskDiv(false); if (fromButton) { alert("${Thereportparametercannotbenull}${Colon}" + (this.params[i].alias || this.params[i].name)); } return; } } displayValue = this.paramPanelObj.getParamDisplayValue(this.params[i].id); } else { value = this.params[i].value; displayValue = this.params[i].displayValue; } //拼参数值,将多个参数传给服务端 if (spreadsheetReport.exportZhi == "EXCEL2007" && this.params[i].name == "城市") { 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.push({ id: this.params[i].id, name: this.params[i].name, value: val, displayValue: disVal }); } else { ps.push({ id: this.params[i].id, name: this.params[i].name, value: value, displayValue: displayValue }); } } if (this.hiddenParamValues) { for (var id in this.hiddenParamValues) { var v = this.hiddenParamValues[id]; ps.push({ id: id, name: id.substring(id.lastIndexOf('.') + 1), value: v[0], displayValue: v[1] }); } } this.exportZhi = "undefined"; return ps; } }
宏类型
类型 | 对象 | 事件 |
---|---|---|
ServerSide | spreadsheetReport | onBeforeOutput |
宏代码
function main(spreadsheetReport) { spreadsheetReport.cacheable = false; if (spreadsheetReport.outputType != "EXCEL2007") return; var cells = spreadsheetReport.workbook.worksheets.get(0).cells; var sourWorkbook = spreadsheetReport.workbook.worksheets.get(0); //var zhi = cells.get(2, 1); var rows = cells.rows.count; var columns = cells.getMaxDataColumn(); logger.debug(cells.getMaxDataColumn()); //获取传过来的参数 var paras = spreadsheetReport.getParamsInfo(); var parasObj = eval("(" + paras + ")"); var arr = new Array(); logger.debug("参数名称:" + parasObj[0].name); var vals = ""; for (var m = 0; m < parasObj.length; m++) { if (parasObj[m].name == "城市"){ vals = parasObj[m].displayValue.split(","); } } var worksheets = spreadsheetReport.workbook.worksheets; if (vals.length > 0) { //创建多个sheet页 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++) { var cell2 = spreadsheetReport.workbook.worksheets.get(0).cells.getCell(j, k); if (!cell2.getValue()) { continue; } if (cell2.getValue()) { var val = cell2.getValue(); var val2 = vals[i].substring(1, vals[i].length - 1); //判断单元格值等于传过来参数值的某一个; if ((val == val2)) { startRowNum = j; var cell = spreadsheetReport.sheets[0].getCell(j, k); logger.debug("j:" + j + ",跨行:" + cell.getRowSpan() + "--" + cell.getCellPosition()); var range = spreadsheetReport.workbook.worksheets.get(0).cells.get(cell.getCellPosition()).mergedRange; if (range && range.getRowCount() > 1) { endRowNum = j + range.getRowCount(); } else { endRowNum = j + 1; } } for (var n = 0; n < vals.length; n++) { if (val == vals[n].substring(1, vals[n].length - 1)) { //所有分组的起始位置,便于拿到第一个分组的起始位置; arr.push(j); } } } } } 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); } } } //删除第一个多余的sheet spreadsheetReport.workbook.worksheets.removeAt(0); } }
关键对象总结
- 单元格的扩展属性,可通过mergedRange获取扩展的行数。
- 可通过deleteRow()方法删除sheet页上的行记录,一般最好从后面开始删。
- 通过removeAt()删除某个sheet。
资源下载:migrate2.xml