package excel import ( "encoding/json" "errors" "eta/eta_api/models/data_manage" excelModel "eta/eta_api/models/data_manage/excel" "eta/eta_api/models/data_manage/excel/request" "eta/eta_api/utils" "fmt" "github.com/xuri/excelize/v2" "strconv" "time" ) // GetBalanceExcelData 将表格信息转化成指标数据 func GetBalanceExcelData(excelDetail *excelModel.ExcelInfo, lang string) (newDataMap map[int]map[int]request.MixedTableCellDataReq, allRows, allCols int, err error, errMsg string) { var result request.MixedTableReq err = json.Unmarshal([]byte(excelDetail.Content), &result) if err != nil { err = errors.New("表格json转结构体失败,Err:" + err.Error()) return } newData, tmpErr, tmpErrMsg := GetMixedTableCellData(result, lang) if tmpErr != nil { errMsg = "获取失败" if tmpErrMsg != `` { errMsg = tmpErrMsg } err = errors.New("获取最新的数据失败,Err:" + tmpErr.Error()) return } allRows = len(newData) allCols = 0 newDataMap = make(map[int]map[int]request.MixedTableCellDataReq) for r, row := range newData { tmp := len(row) if tmp > allCols { allCols = tmp } colMap := make(map[int]request.MixedTableCellDataReq) for c, col := range row { colMap[c] = col } newDataMap[r] = colMap } return } func GetBalanceExcelChartList(excelInfo *excelModel.ExcelInfo, lang string) (list []*data_manage.ChartInfoView, mappingListMap map[int][]*excelModel.ExcelChartEdb, dataListMap map[int][]*data_manage.EdbDataList, err error, errMsg string) { dataListMap = make(map[int][]*data_manage.EdbDataList) // 相关联指标 mappingListTmp, err := excelModel.GetExcelChartEdbMappingByExcelInfoId(excelInfo.ExcelInfoId) if err != nil { errMsg = "获取失败" err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", err.Error()) return } charInfoIds := make([]int, 0) mappingListMap = make(map[int][]*excelModel.ExcelChartEdb, 0) if excelInfo.BalanceType == 1 { for _, mapping := range mappingListTmp { mappingListMap[mapping.ChartInfoId] = append(mappingListMap[mapping.ChartInfoId], mapping) } //查询库里是否有值 chartDataList, e := excelModel.GetExcelChartDataByExcelInfoId(excelInfo.ExcelInfoId) if e != nil { err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", e.Error()) return } if len(chartDataList) > 0 { for _, v := range chartDataList { tmp := &data_manage.EdbDataList{ EdbDataId: v.ExcelChartDataId, EdbInfoId: v.ExcelChartEdbId, DataTime: v.DataTime, DataTimestamp: v.DataTimestamp, Value: v.Value, } dataListMap[v.ExcelChartEdbId] = append(dataListMap[v.ExcelChartEdbId], tmp) } } } else { newExcelDataMap, excelAllRows, excelAllCols, e, msg := GetBalanceExcelData(excelInfo, lang) if e != nil { err = e errMsg = msg return } for _, mapping := range mappingListTmp { mappingListMap[mapping.ChartInfoId] = append(mappingListMap[mapping.ChartInfoId], mapping) er, ms := GetBalanceExcelEdbData(mapping, newExcelDataMap, dataListMap, excelAllRows, excelAllCols) if er != nil { utils.FileLog.Info(fmt.Sprintf(" 获取图表,指标信息失败 Err:%s, %s", er.Error(), ms)) continue } } } for k, _ := range mappingListMap { charInfoIds = append(charInfoIds, k) } list = make([]*data_manage.ChartInfoView, 0) if len(charInfoIds) > 0 { chartInfoList, e := data_manage.GetChartInfoViewByIdList(charInfoIds) if e != nil { errMsg = "获取失败" err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", e.Error()) return } list = chartInfoList } return } // GetBalanceExcelEdbData 将表格信息转化成指标数据 func GetBalanceExcelEdbData(excelEdbMappingItem *excelModel.ExcelChartEdb, newMixedTableCellDataListMap map[int]map[int]request.MixedTableCellDataReq, dataListMap map[int][]*data_manage.EdbDataList, allRows, allCols int) (err error, errMsg string) { var dateList, dataList []string // 日期序列 { _, startColumnName, endColumnName, startNum, endNum, isAll, isRow, isColumn, tmpErr, tmpErrMsg := GetSheetStr(excelEdbMappingItem.DateSequence) if tmpErr != nil { errMsg = tmpErrMsg err = tmpErr return } startNum = startNum - 1 endNum = endNum - 1 // 选择行的数据 if isRow { // 因为是选择一行的数据,所以开始行和结束行时一样的 //endNum = startNum - 1 // 开始列名、结束列 var startColumn, endColumn int if isAll { // 结束列(其实也就是整列的个数) endColumn = allCols - 1 } else { tmpStartColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName) if tmpErr != nil { errMsg = "列名异常:" + startColumnName err = errors.New(errMsg) return } tmpEndColumn, tmpErr := excelize.ColumnNameToNumber(endColumnName) if tmpErr != nil { errMsg = "列名异常:" + endColumnName err = errors.New(errMsg) return } startColumn = tmpStartColumn - 1 endColumn = tmpEndColumn - 1 } // 最大列数,如果设置的超过了最大列数,那么结束列就是最大列数 maxCol := allCols if endColumn > maxCol { endColumn = maxCol - 1 } // 长度固定,避免一直申请内存空间 //dateList = make([]string, endColumn-startColumn+1) dateList = make([]string, 0) i := 0 for currColumn := startColumn; currColumn <= endColumn; currColumn++ { currCell, ok := newMixedTableCellDataListMap[startNum][currColumn] if !ok { errMsg = fmt.Sprintf("第%d列,第%d行数据异常", currColumn, startNum) err = errors.New(errMsg) return } dateList = append(dateList, currCell.ShowValue) //dateList[i] = currCell.ShowValue i++ } } else if isColumn { // 选择列的数据 if isAll { // 选择一整列的话,结束行得根据实际情况调整(其实也就是整个sheet有多少行) endNum = allRows - 1 } startColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName) if tmpErr != nil { errMsg = "列名异常:" + startColumnName err = errors.New(errMsg) return } startColumn = startColumn - 1 // 最大行数,如果设置的超过了最大行数,那么结束行就是最大行数 maxRow := allRows if endNum > maxRow { endNum = maxRow - 1 } // 长度固定,避免一直申请内存空间 //dateList = make([]string, endNum-startNum+1) fmt.Println("startNum:", startNum, "endNum:", endNum) dateList = make([]string, 0) i := 0 for currRow := startNum; currRow <= endNum; currRow++ { currCell, ok := newMixedTableCellDataListMap[currRow][startColumn] if !ok { errMsg = fmt.Sprintf("第%d列,第%d行数据异常", currRow, startColumn) err = errors.New(errMsg) return } dateList = append(dateList, currCell.ShowValue) //dateList[i] = currCell.ShowValue i++ } } } // 数据序列 { _, startColumnName, endColumnName, startNum, endNum, isAll, isRow, isColumn, tmpErr, tmpErrMsg := GetSheetStr(excelEdbMappingItem.DataSequence) if tmpErr != nil { errMsg = tmpErrMsg err = tmpErr return } startNum = startNum - 1 endNum = endNum - 1 // 选择行的数据 if isRow { // 开始列名、结束列 var startColumn, endColumn int if isAll { // 结束列(其实也就是整列的个数) endColumn = allCols - 1 } else { tmpStartColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName) if tmpErr != nil { errMsg = "列名异常:" + startColumnName err = errors.New(errMsg) return } tmpEndColumn, tmpErr := excelize.ColumnNameToNumber(endColumnName) if tmpErr != nil { errMsg = "列名异常:" + endColumnName err = errors.New(errMsg) return } startColumn = tmpStartColumn - 1 endColumn = tmpEndColumn - 1 } // 最大列数,如果设置的超过了最大列数,那么结束列就是最大列数 maxCol := allCols if endColumn > maxCol { endColumn = maxCol - 1 } // 长度固定,避免一直申请内存空间 //dataList = make([]string, endColumn-startColumn+1) dataList = make([]string, 0) i := 0 for currColumn := startColumn; currColumn <= endColumn; currColumn++ { currCell, ok := newMixedTableCellDataListMap[startNum][currColumn] if !ok { errMsg = fmt.Sprintf("第%d列,第%d行数据异常", startColumn, currColumn) err = errors.New(errMsg) return } dataList = append(dataList, currCell.ShowValue) //dataList[i] = currCell.ShowValue i++ } } else if isColumn { // 选择列的数据 if isAll { // 选择一整列的话,结束行得根据实际情况调整(其实也就是整个sheet有多少行) endNum = allRows - 1 } startColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName) if tmpErr != nil { errMsg = "列名异常:" + startColumnName err = errors.New(errMsg) return } startColumn = startColumn - 1 // 最大行数,如果设置的超过了最大行数,那么结束行就是最大行数 maxRow := allRows if endNum > maxRow { endNum = maxRow - 1 } // 长度固定,避免一直申请内存空间 //dataList = make([]string, endNum-startNum+1) dataList = make([]string, 0) i := 0 for currRow := startNum; currRow <= endNum; currRow++ { currCell, ok := newMixedTableCellDataListMap[currRow][startColumn] if !ok { errMsg = fmt.Sprintf("第%d列,第%d行数据异常", currRow, startColumn) err = errors.New(errMsg) return } dataList = append(dataList, currCell.ShowValue) //dataList[i] = currCell.ShowValue i++ } } } //fmt.Println(dateList, dataList) //fmt.Println("日期序列结束") // 将excel中的日期、数据系列处理 //newDateList, newDataList, err, errMsg := excel2.HandleEdbSequenceVal(dateList, dataList) newDateList, newDataList := dateList, dataList if err != nil { err = fmt.Errorf(" 处理日期和数据系列失败 %s", err.Error()) return } newDataMap := make(map[int]float64, len(newDataList)) for i, v := range newDataList { if v != "" { val, e := strconv.ParseFloat(v, 64) if e != nil { err = fmt.Errorf(" 处理日期和数据系列失败 %s", e.Error()) return } newDataMap[i] = val } } //组装成excelEdbData list := make([]*data_manage.EdbDataList, 0) for i, v := range newDateList { val, ok := newDataMap[i] if !ok { continue } // todo 处理DataTimestamp dataTime, e := time.ParseInLocation(utils.FormatDate, v, time.Local) if e != nil { err = errors.New("time.Parse Err:" + e.Error()) return } timestamp := dataTime.UnixNano() / 1e6 tmp := &data_manage.EdbDataList{ EdbDataId: i, EdbInfoId: excelEdbMappingItem.ExcelChartEdbId, DataTime: v, DataTimestamp: timestamp, Value: val, } list = append(list, tmp) } dataListMap[excelEdbMappingItem.ExcelChartEdbId] = list return } // 根据chartInfoId获取单个图表信息 func GetBalanceExcelChartSingle(chartInfoId, ChartEdbId int, lang string) (mappingListTmp []*excelModel.ExcelChartEdb, dataListMap map[int][]*data_manage.EdbDataList, err error, errMsg string) { // 相关联指标 if chartInfoId == 0 && ChartEdbId == 0 { err = fmt.Errorf(" 获取图表,指标信息失败 Err:chartInfoId和ChartEdbId不能同时为空") return } if chartInfoId == 0 { chartEdb, e := excelModel.GetExcelChartEdbById(ChartEdbId) if e != nil { err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", e.Error()) return } chartInfoId = chartEdb.ChartInfoId } mappingListTmp, err = excelModel.GetExcelChartEdbMappingByChartInfoId(chartInfoId) if err != nil { errMsg = "获取失败" err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", err.Error()) return } if len(mappingListTmp) <= 0 { errMsg = "获取失败" err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", err.Error()) return } // 查询所有子表 excelInfoId := mappingListTmp[0].ExcelInfoId excelInfo, err := excelModel.GetExcelInfoById(excelInfoId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "表格不存在" err = fmt.Errorf(errMsg) return } errMsg = "查询子表失败" err = fmt.Errorf(" 查询子表失败图表,指标信息失败 Err:%s", err.Error()) return } dataListMap = make(map[int][]*data_manage.EdbDataList) if excelInfo.BalanceType == 1 { //查询库里是否有值 chartDataList, e := excelModel.GetExcelChartDataByChartInfoId(chartInfoId) if e != nil { err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", e.Error()) return } if len(chartDataList) == 0 { err = fmt.Errorf(" 获取图表,指标数据不存在") return } for _, v := range chartDataList { tmp := &data_manage.EdbDataList{ EdbDataId: v.ExcelChartDataId, EdbInfoId: v.ExcelChartEdbId, DataTime: v.DataTime, DataTimestamp: v.DataTimestamp, Value: v.Value, } dataListMap[v.ExcelChartEdbId] = append(dataListMap[v.ExcelChartEdbId], tmp) } return } // 获取图表详情 newExcelDataMap, excelAllRows, excelAllCols, err, errMsg := GetBalanceExcelData(excelInfo, lang) if err != nil { return } for _, mapping := range mappingListTmp { er, msg := GetBalanceExcelEdbData(mapping, newExcelDataMap, dataListMap, excelAllRows, excelAllCols) if er != nil { utils.FileLog.Info(fmt.Sprintf(" 获取图表,指标信息失败 Err:%s, %s", er.Error(), msg)) continue } } return } // TransferBalanceExcelContentToStatic 将平衡表动态表的内容转换为静态表的格式 func TransferBalanceExcelContentToStatic(excelDetail *excelModel.ExcelInfo, lang string) (newContent string, err error) { var mixedTableReq request.MixedTableReq err = json.Unmarshal([]byte(excelDetail.Content), &mixedTableReq) if err != nil { err = errors.New("表格json转结构体失败,Err:" + err.Error()) return } cellRelationConf := mixedTableReq.CellRelation //config := mixedTableReq.Data // 单元格关系配置x信息 cellRelationConfMap := make(map[string]request.CellRelationConf) cellRelationConfList := make([]request.CellRelationConf, 0) cellRelationConfNewList := make([]request.CellRelationConf, 0) if cellRelationConf != `` { err = json.Unmarshal([]byte(cellRelationConf), &cellRelationConfList) if err != nil { return } for _, v := range cellRelationConfList { if v.Type == request.EdbDT || v.Type == request.InsertDataDT || v.Type == request.PopInsertDataDT || v.Type == request.InsertEdbCalculateDataDT || v.Type == request.DateCalculateDataDT { } else { cellRelationConfNewList = append(cellRelationConfNewList, v) } } } cellRelationConfByte, err := json.Marshal(cellRelationConfNewList) if err != nil { err = fmt.Errorf("cellRelationConf json转结构体失败,Err:%s", err.Error()) return } cellRelationConf = string(cellRelationConfByte) newData, tmpErr, tmpErrMsg := GetMixedTableCellData(mixedTableReq, lang) if tmpErr != nil { err = errors.New(tmpErrMsg + "获取最新的数据失败 ,Err:" + tmpErr.Error()) return } for r, row := range newData { for c, cell := range row { // todo 系统日期类型,原先是不可编辑,转成静态表之后是否变成可编辑 cell.EdbInfoId = 0 if cell.DataType != request.FormulateCalculateDataDT { //除了公式计算,其他类型都转成自定义类型 cell.DataType = request.CustomTextDT //除了计算公式的关联关系被保留,其余绑定关系都删除 if _, ok := cellRelationConfMap[cell.Uid]; ok { delete(cellRelationConfMap, cell.Uid) } } if cell.DataTime != "" { cell.DataTimeType = request.CustomDateT } cell.Value = cell.ShowValue row[c] = cell } newData[r] = row } var newMixedTableReq request.MixedTableReq newMixedTableReq.CellRelation = cellRelationConf newMixedTableReq.Data = newData newMixedTableByte, err := json.Marshal(newMixedTableReq) if err != nil { err = fmt.Errorf("newData json转结构体失败,Err:%s", err.Error()) return } newContent = string(newMixedTableByte) return } func SyncBalanceEdbData(excelInfo *excelModel.ExcelInfo, balanceTableData [][]request.MixedTableCellDataReq) (err error) { tmpMappingList, e := excelModel.GetExcelChartEdbMappingByExcelInfoId(excelInfo.ExcelInfoId) if e != nil { err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", err.Error()) return } if len(tmpMappingList) == 0 { return } excelDataMap := make(map[int][]*data_manage.EdbDataList) excelEdbMap := make(map[int]*excelModel.ExcelChartEdb) excelAllRows := len(balanceTableData) excelAllCols := 0 newExcelDataMap := make(map[int]map[int]request.MixedTableCellDataReq) for r, row := range balanceTableData { tmp := len(row) if tmp > excelAllCols { excelAllCols = tmp } colMap := make(map[int]request.MixedTableCellDataReq) for c, col := range row { colMap[c] = col } newExcelDataMap[r] = colMap } for _, mapping := range tmpMappingList { excelEdbMap[mapping.ExcelChartEdbId] = mapping er, msg := GetBalanceExcelEdbData(mapping, newExcelDataMap, excelDataMap, excelAllRows, excelAllCols) if er != nil { utils.FileLog.Info(fmt.Sprintf(" 获取图表,指标信息失败 Err:%s, %s", msg, er.Error())) continue } } // 批量更新图表数据 err = excelModel.BatchUpdateChartEdbData(excelInfo.ExcelInfoId, excelEdbMap, excelDataMap) if err != nil { err = fmt.Errorf(" 批量更新图表数据失败 Err:%s", err.Error()) return } return } // GetBalanceExcelInfoOpButton 获取ETA平衡表格的操作权限 func GetBalanceExcelInfoOpButton(sysUserId, parentSysUserId int, haveOperaAuth bool, parentExcelInfoId int) (button excelModel.ExcelInfoDetailButton) { // 如果没有数据权限,那么直接返回 if !haveOperaAuth { return } //非管理员角色查看其他用户创建的表格,可刷新、另存为、下载表格; button.RefreshButton = true button.CopyButton = true button.DownloadButton = true if sysUserId == parentSysUserId { button.OpButton = true button.RefreshEdbButton = true button.OpWorkerButton = true button.DeleteButton = true } else { obj := new(excelModel.ExcelWorker) workerList, err := obj.GetByExcelInfoId(parentExcelInfoId) if err == nil { for _, v := range workerList { if v.SysUserId == sysUserId { button.OpButton = true button.RefreshEdbButton = true button.DeleteButton = true break } } } } return }