package service import ( "fmt" "strings" "github.com/linmadan/egglib-go/core/application" "github.com/xuri/excelize/v2" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/query" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/dao" ) // 员工绩效-综合管理-导出绩效-个人 func (srv *StaffAssessServeice) ExportUserAssess2V2(param *query.ExportUserAssess2Commad) (*excelize.File, error) { transactionContext, err := factory.CreateTransactionContext(nil) if err != nil { return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) } if err := transactionContext.StartTransaction(); err != nil { return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) } defer func() { _ = transactionContext.RollbackTransaction() }() hrbp, err := srv.getHRBP(transactionContext, param.CompanyId, param.OperatorId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } assessDao := dao.NewStaffAssessDao(map[string]interface{}{ "transactionContext": transactionContext, }) // 按照cycleId获取项目的指标项 evaluationItemList, err := assessDao.SearchEvaluationItemUsed2(param.CompanyId, param.CycleId, param.OperatorId, hrbp, param.ExportUserId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } // 按照项目获取填写的内容 assessContentList, err := assessDao.SearchStaffAssessContent2(param.CompanyId, param.CycleId, param.OperatorId, hrbp, param.ExportUserId) if err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } if err := transactionContext.CommitTransaction(); err != nil { return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) } eData := newExportData3() eData.FormatTableHead(evaluationItemList) eData.FormatListValue(assessContentList) xlsxFile := excelize.NewFile() //设置默认的第一个sheet sheetIndex := xlsxFile.GetActiveSheetIndex() firstSheetName := xlsxFile.GetSheetName(sheetIndex) cycleName := "" if len(evaluationItemList) > 0 { cycleName = evaluationItemList[0].CycleName } for k1, val := range eData.userProjcetMap { for k2, val2 := range val { // 根据员工名称 添加一个sheet uname := eData.userIdName[k1] if len(uname) == 0 { continue } tableHeader, ok := eData.tableHeader[eData.tableHeaderKey(k1, val2)] if !ok { continue } newSheetName := uname + fmt.Sprintf("_%d", k2+1) xlsxFile.NewSheet(newSheetName) xlsxFile.SetCellStr(newSheetName, "B2", uname) xlsxFile.MergeCell(newSheetName, "B2", "B4") //填充第一列数据 xlsxFile.SetCellStr(newSheetName, "A1", tableHeader.Name) xlsxFile.SetCellStr(newSheetName, "A2", cycleName) xlsxFile.MergeCell(newSheetName, "A2", "A4") xlsxFile.SetCellStr(newSheetName, "A5", "权重") xlsxFile.MergeCell(newSheetName, "A5", "B5") xlsxFile.SetCellStr(newSheetName, "A6", "评估标准") xlsxFile.MergeCell(newSheetName, "A6", "B6") // 日期 dayList := eData.userDayMap[eData.userDayKey(k1, val2)] for ii, vv := range dayList { //填写在第几行 axisNum := 7 + 3*ii axis := fmt.Sprintf("A%d", axisNum) xlsxFile.SetCellStr(newSheetName, axis, vv) axisEnd := fmt.Sprintf("B%d", axisNum+2) xlsxFile.MergeCell(newSheetName, axis, axisEnd) //单元格高度按三个单元格合并 } allColNum := 0 //计算总共有多少列 //第一行 for _, v2 := range tableHeader.Child { //第二行 for _, v3 := range v2.Child { //第三行 for _, v4 := range v3.Child { allColNum++ //按列填充数据 colName, _ := excelize.ColumnNumberToName(allColNum + 2) //第3列开始 xlsxFile.SetCellStr(newSheetName, colName+"2", v2.Name) //分类 xlsxFile.SetCellStr(newSheetName, colName+"3", v3.Name) //加分项 得分项 xlsxFile.SetCellStr(newSheetName, colName+"4", v4.Name) // 评估项名称 //权重 填写第5行数据 k23 := eData.data23Key(k1, v2.Name, v3.Name, v4.Name) xlsxFile.SetCellStr(newSheetName, colName+"5", eData.data3[k23]) //评估标准 填写第6行数据 xlsxFile.SetCellStr(newSheetName, colName+"6", eData.data2[k23]) //按日期填充评估的填写的值 for i5, v5 := range dayList { k1 := eData.dataKey(k1, val2, v5, v2.Name, v3.Name, v4.Name) //填写在第几行 axisNum := 7 + 3*i5 axis := fmt.Sprintf("%s%d", colName, axisNum) if d, ok := eData.data[k1]; ok { xlsxFile.SetCellStr(newSheetName, axis, d.String()) } //单元格高度按三个单元格合并 axisEnd := fmt.Sprintf("%s%d", colName, axisNum+2) xlsxFile.MergeCell(newSheetName, axis, axisEnd) } } } } // colName, _ := excelize.ColumnNumberToName(allColNum + 2) xlsxFile.MergeCell(newSheetName, "A1", fmt.Sprintf("%s1", colName)) } } //删除默认的第一个sheet xlsxFile.DeleteSheet(firstSheetName) return xlsxFile, nil } // 处理原始数据,方便进行 excel导出 type exportData3 struct { userIdName map[string]string //员工id对应的名字 id=>员工名称 userProjcetMap map[string][]string //员工的项目 员工id=>项目id tableHeader map[string]*HeaderLevel //表头数据 key=员工id+项目id userDayMap map[string][]string //每个员工对应的日期列表 key=员工id+项目id value= 日期列表 data map[string]*strings.Builder //每个员工表头对应的评估填写的数据 key=员工id+项目id+日期+表头 data2 map[string]string //每个员工评估项的标准描述 key=员工id+项目id+表头 data3 map[string]string //每个员工评估项的标准权重 key=员工id+项目id+表头 } func newExportData3() *exportData3 { return &exportData3{ userIdName: map[string]string{}, userProjcetMap: map[string][]string{}, tableHeader: map[string]*HeaderLevel{}, userDayMap: map[string][]string{}, data: map[string]*strings.Builder{}, data2: map[string]string{}, data3: map[string]string{}} } func (e *exportData3) FormatTableHead(param []dao.DataEvaluationItemUsed2) { userNameMap := map[string]struct{}{} //员工名字过滤 projectIdMap := map[string]struct{}{} //项目id过滤 for _, val := range param { // if _, ok := e.userProjcetMap[val.TargetUserId]; !ok { e.userProjcetMap[val.TargetUserId] = []string{} } //处理一个员工多项目的情况 if _, ok := projectIdMap[val.EvaluationProjectId]; !ok { e.userProjcetMap[val.TargetUserId] = append(e.userProjcetMap[val.TargetUserId], val.EvaluationProjectId) projectIdMap[val.EvaluationProjectId] = struct{}{} } //处理员工的名称 if _, ok := e.userIdName[val.TargetUserId]; !ok { if _, ok := userNameMap[val.TargetUserName]; ok { //员工重名 uname := fmt.Sprintf("%s(%d)", val.TargetUserName, len(userNameMap)) e.userIdName[val.TargetUserId] = uname userNameMap[uname] = struct{}{} } else { e.userIdName[val.TargetUserId] = val.TargetUserName userNameMap[val.TargetUserName] = struct{}{} } } //每个员工对应的日期列表 key1 := e.tableHeaderKey(val.TargetUserId, val.EvaluationProjectId) if _, ok := e.tableHeader[key1]; !ok { e.tableHeader[key1] = &HeaderLevel{ Name: "个人绩效评估等级统计表", Filter: map[string]int{}, Child: []HeaderLevel{}, } } child := e.tableHeader[key1].addChild(val.Category) //第一级,"分类" weight := e.weightDesc(val.Weight) child = child.addChild(weight) //第二级 '得分项' '加分项' child.addChild(val.ContentName) //第三级 评估项名称 } } func (e *exportData3) FormatListValue(param []dao.DataStaffAssessContent2) { userDay := map[string]struct{}{} for _, val := range param { weight := e.weightDesc(val.Weight) key := e.dataKey(val.TargetUserId, val.EvaluationProjectId, val.BeginDay, val.Category, weight, val.ContentName) e.data[key] = &strings.Builder{} e.data[key].WriteString(val.Value + "\n") //填写的等级 for _, vv := range val.Remark { e.data[key].WriteString(vv.Title + "\n") e.data[key].WriteString(vv.RemarkText + "\n") } dayKey := val.TargetUserId + val.EvaluationProjectId + val.BeginDay if _, ok := userDay[dayKey]; !ok { userDay[dayKey] = struct{}{} k := e.userDayKey(val.TargetUserId, val.EvaluationProjectId) e.userDayMap[k] = append(e.userDayMap[k], val.BeginDay) } key23 := e.data23Key(val.TargetUserId, val.Category, weight, val.ContentName) e.data2[key23] = val.PromptText if val.Weight == 0 { e.data3[key23] = "" } else { e.data3[key23] = fmt.Sprintf("%.2f%%", val.Weight) } } } func (e *exportData3) weightDesc(weight float64) string { if weight == 0 { return "加分项" } else { return "得分项" } } func (e *exportData3) dataKey(userId string, projectId string, beginDay string, category string, weight string, contentName string) string { key := fmt.Sprintf("%s-%s-%s-%s-%s-%s", userId, projectId, weight, beginDay, category, contentName) return key } func (e *exportData3) data23Key(userId string, category string, weight string, contentName string) string { key := fmt.Sprintf("%s-%s-%s-%s", userId, weight, category, contentName) return key } func (e *exportData3) userDayKey(userId string, projectId string) string { return fmt.Sprintf("%s-%s", userId, projectId) } func (e *exportData3) tableHeaderKey(targetUserId, evaluationProjectId string) string { return targetUserId + "-" + evaluationProjectId }