作者 tangxvhui

更新excel导出

@@ -2,6 +2,7 @@ package adapter @@ -2,6 +2,7 @@ package adapter
2 2
3 type MeInfo struct { 3 type MeInfo struct {
4 UserId int64 `json:"userId"` //用户名称 4 UserId int64 `json:"userId"` //用户名称
  5 + CompanyLogo string `json:"companyLogo"` //图标
5 CompanyId int64 `json:"companyId"` //公司id 6 CompanyId int64 `json:"companyId"` //公司id
6 CompanyName string `json:"companyName"` //公司名称 7 CompanyName string `json:"companyName"` //公司名称
7 Phone string `json:"phone"` // 手机号 8 Phone string `json:"phone"` // 手机号
@@ -220,6 +220,7 @@ loop: @@ -220,6 +220,7 @@ loop:
220 UserId: userData.Id, 220 UserId: userData.Id,
221 CompanyId: companyData.Id, 221 CompanyId: companyData.Id,
222 CompanyName: companyData.Name, 222 CompanyName: companyData.Name,
  223 + CompanyLogo: companyData.Logo,
223 Phone: userData.Account, 224 Phone: userData.Account,
224 Name: userData.Name, 225 Name: userData.Name,
225 IsHrbp: isHrbp, 226 IsHrbp: isHrbp,
1 package service 1 package service
2 2
3 import ( 3 import (
  4 + "fmt"
  5 + "strings"
  6 +
4 "github.com/linmadan/egglib-go/core/application" 7 "github.com/linmadan/egglib-go/core/application"
5 "github.com/xuri/excelize/v2" 8 "github.com/xuri/excelize/v2"
6 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory" 9 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
@@ -30,49 +33,213 @@ func (srv *StaffAssessServeice) ExportUserAssess2V2(param *query.ExportUserAsses @@ -30,49 +33,213 @@ func (srv *StaffAssessServeice) ExportUserAssess2V2(param *query.ExportUserAsses
30 // 按照cycleId获取项目的指标项 33 // 按照cycleId获取项目的指标项
31 evaluationItemList, err := assessDao.SearchEvaluationItemUsed2(param.CompanyId, 34 evaluationItemList, err := assessDao.SearchEvaluationItemUsed2(param.CompanyId,
32 param.CycleId, param.OperatorId, hrbp, param.ExportUserId) 35 param.CycleId, param.OperatorId, hrbp, param.ExportUserId)
  36 + if err != nil {
  37 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  38 + }
33 // 按照项目获取填写的内容 39 // 按照项目获取填写的内容
34 - assessContentList, err := assessDao.SearchEvaluationItemUsed2(param.CompanyId, 40 + assessContentList, err := assessDao.SearchStaffAssessContent2(param.CompanyId,
35 param.CycleId, param.OperatorId, hrbp, param.ExportUserId) 41 param.CycleId, param.OperatorId, hrbp, param.ExportUserId)
  42 + if err != nil {
  43 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  44 + }
36 if err := transactionContext.CommitTransaction(); err != nil { 45 if err := transactionContext.CommitTransaction(); err != nil {
37 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 46 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
38 } 47 }
  48 + eData := newExportData3()
  49 + eData.FormatTableHead(evaluationItemList)
  50 + eData.FormatListValue(assessContentList)
  51 + xlsxFile := excelize.NewFile()
  52 + //设置默认的第一个sheet
  53 + sheetIndex := xlsxFile.GetActiveSheetIndex()
  54 + firstSheetName := xlsxFile.GetSheetName(sheetIndex)
  55 + cycleName := ""
  56 + if len(evaluationItemList) > 0 {
  57 + cycleName = evaluationItemList[0].CycleName
  58 + }
  59 + for k1, val := range eData.userProjcetMap {
  60 + for k2, val2 := range val {
  61 + // 根据员工名称 添加一个sheet
  62 + uname := eData.userIdName[k1]
  63 + if len(uname) == 0 {
  64 + continue
  65 + }
  66 + tableHeader, ok := eData.tableHeader[k1+val2]
  67 + if !ok {
  68 + continue
  69 + }
  70 +
  71 + newSheetName := uname + fmt.Sprintf("_%d", k2+1)
  72 + xlsxFile.NewSheet(newSheetName)
  73 + xlsxFile.SetCellStr(newSheetName, "B2", uname)
  74 + xlsxFile.MergeCell(newSheetName, "B2", "B4")
  75 + //填充第一列数据
  76 + xlsxFile.SetCellStr(newSheetName, "A1", tableHeader.Name)
  77 + xlsxFile.SetCellStr(newSheetName, "A2", cycleName)
  78 + xlsxFile.MergeCell(newSheetName, "A2", "A4")
  79 + xlsxFile.SetCellStr(newSheetName, "A5", "权重")
  80 + xlsxFile.MergeCell(newSheetName, "A5", "B5")
  81 + xlsxFile.SetCellStr(newSheetName, "A6", "评估标准")
  82 + xlsxFile.MergeCell(newSheetName, "A6", "B6")
  83 + // 日期
  84 + dayList := eData.userDayMap[eData.userDayKey(k1, val2)]
  85 + for ii, vv := range dayList {
  86 + //填写在第几行
  87 + axisNum := 7 + 3*ii
  88 + axis := fmt.Sprintf("A%d", axisNum)
  89 + xlsxFile.SetCellStr(newSheetName, axis, vv)
  90 + axisEnd := fmt.Sprintf("B%d", axisNum+2)
  91 + xlsxFile.MergeCell(newSheetName, axis, axisEnd) //单元格高度按三个单元格合并
  92 + }
  93 + allColNum := 0 //计算总共有多少列
  94 + //第一行
  95 + for _, v2 := range tableHeader.Child {
39 96
40 - return nil, nil 97 + //第二行
  98 + for _, v3 := range v2.Child {
  99 + //第三行
  100 + for _, v4 := range v3.Child {
  101 + allColNum++
  102 + //按列填充数据
  103 + colName, _ := excelize.ColumnNumberToName(allColNum + 2) //第3列开始
  104 + xlsxFile.SetCellStr(newSheetName, colName+"2", v2.Name) //分类
  105 + xlsxFile.SetCellStr(newSheetName, colName+"3", v3.Name) //加分项 得分项
  106 + xlsxFile.SetCellStr(newSheetName, colName+"4", v4.Name) // 评估项名称
  107 + //权重 填写第5行数据
  108 + k23 := eData.data23Key(k1, v2.Name, v3.Name, v4.Name)
  109 + xlsxFile.SetCellStr(newSheetName, colName+"5", eData.data3[k23])
  110 + //评估标准 填写第6行数据
  111 + xlsxFile.SetCellStr(newSheetName, colName+"6", eData.data2[k23])
  112 + //按日期填充评估的填写的值
  113 + for i5, v5 := range dayList {
  114 + k1 := eData.dataKey(k1, val2, v5, v2.Name, v3.Name, v4.Name)
  115 + //填写在第几行
  116 + axisNum := 7 + 3*i5
  117 + axis := fmt.Sprintf("%s%d", colName, axisNum)
  118 + if d, ok := eData.data[k1]; ok {
  119 + xlsxFile.SetCellStr(newSheetName, axis, d.String())
  120 + }
  121 + //单元格高度按三个单元格合并
  122 + axisEnd := fmt.Sprintf("%s%d", colName, axisNum+2)
  123 + xlsxFile.MergeCell(newSheetName, axis, axisEnd)
  124 + }
  125 + }
  126 + }
  127 + }
  128 + //
  129 + colName, _ := excelize.ColumnNumberToName(allColNum + 2)
  130 + xlsxFile.MergeCell(newSheetName, "A1", fmt.Sprintf("%s1", colName))
  131 + }
  132 + }
  133 + //删除默认的第一个sheet
  134 + xlsxFile.DeleteSheet(firstSheetName)
  135 + return xlsxFile, nil
41 } 136 }
42 137
43 // 处理原始数据,方便进行 excel导出 138 // 处理原始数据,方便进行 excel导出
44 type exportData3 struct { 139 type exportData3 struct {
45 - sheetList []string //excel的sheet列表  
46 - tableHeader map[string]*HeaderLevel //表头数据 140 + userIdName map[string]string //员工id对应的名字 id=>员工名称
  141 + userProjcetMap map[string][]string //员工的项目 员工id=>项目id
  142 + tableHeader map[string]*HeaderLevel //表头数据 key=员工id+项目id
  143 + userDayMap map[string][]string //每个员工对应的日期列表 key=员工id+项目id value= 日期列表
  144 + data map[string]*strings.Builder //每个员工表头对应的评估填写的数据 key=员工id+项目id+日期+表头
  145 + data2 map[string]string //每个员工评估项的标准描述 key=员工id+项目id+表头
  146 + data3 map[string]string //每个员工评估项的标准权重 key=员工id+项目id+表头
  147 +}
  148 +
  149 +func newExportData3() *exportData3 {
  150 + return &exportData3{
  151 + userIdName: map[string]string{},
  152 + userProjcetMap: map[string][]string{},
  153 + tableHeader: map[string]*HeaderLevel{},
  154 + userDayMap: map[string][]string{},
  155 + data: map[string]*strings.Builder{},
  156 + data2: map[string]string{}, data3: map[string]string{}}
47 } 157 }
48 158
49 func (e *exportData3) FormatTableHead(param []dao.DataEvaluationItemUsed2) { 159 func (e *exportData3) FormatTableHead(param []dao.DataEvaluationItemUsed2) {
50 - userNameMap := map[string]struct{}{} //员工名字过滤  
51 - userProjcetMap := map[string]map[string]string{}  
52 - userIdName := map[string]string{} //员工id=> 员工名称  
53 - sheetMap := HeaderLevel{} 160 + userNameMap := map[string]struct{}{} //员工名字过滤
  161 + projectIdMap := map[string]struct{}{} //项目id
54 for _, val := range param { 162 for _, val := range param {
55 - // child := sheetMap.addChild(val.TargetUserId)  
56 - // _ = child.addChild(val.EvaluationProjectId) 163 + //
57 if _, ok := userNameMap[val.TargetUserId]; !ok { 164 if _, ok := userNameMap[val.TargetUserId]; !ok {
58 - userProjcetMap[val.TargetUserId] = map[string]string{} 165 + e.userProjcetMap[val.TargetUserId] = []string{}
59 } 166 }
60 - userProjcetMap[val.TargetUserId][val.EvaluationProjectId] = ""  
61 - if _, ok := userIdName[val.TargetUserId]; !ok {  
62 - userIdName[val.TargetUserId] = val.TargetUserName  
63 - userNameMap[val.TargetUserName] = struct{}{} 167 + //处理一个员工多项目的情况
  168 + if _, ok := projectIdMap[val.EvaluationProjectId]; !ok {
  169 + e.userProjcetMap[val.TargetUserId] = append(e.userProjcetMap[val.TargetUserId], val.EvaluationProjectId)
64 } 170 }
  171 + //处理员工的名称
  172 + if _, ok := e.userIdName[val.TargetUserId]; !ok {
  173 + if _, ok := userNameMap[val.TargetUserName]; ok {
  174 + uname := fmt.Sprintf("%s(%d)", val.TargetUserName, len(userNameMap))
  175 + e.userIdName[val.TargetUserId] = uname
  176 + userNameMap[uname] = struct{}{}
  177 + } else {
  178 + e.userIdName[val.TargetUserId] = val.TargetUserName
  179 + userNameMap[val.TargetUserName] = struct{}{}
  180 + }
  181 + }
  182 + //每个员工对应的日期列表
  183 + key1 := val.TargetUserId + "+" + val.EvaluationProjectId
  184 + if _, ok := e.tableHeader[key1]; !ok {
  185 + e.tableHeader[key1] = &HeaderLevel{
  186 + Name: "个人绩效评估等级统计表",
  187 + Filter: map[string]int{},
  188 + Child: []HeaderLevel{},
  189 + }
  190 + }
  191 + child := e.tableHeader[key1].addChild(val.Category) //第一级,"分类"
  192 + weight := e.weightDesc(val.Weight)
  193 + child = child.addChild(weight) //第二级 '得分项' '加分项'
  194 + child.addChild(val.ContentName) //第三级 评估项名称
65 } 195 }
  196 +}
66 197
67 - for _, val := range sheetMap.Child { 198 +func (e *exportData3) FormatListValue(param []dao.DataStaffAssessContent2) {
  199 + userDay := map[string]struct{}{}
  200 + for _, val := range param {
  201 + weight := e.weightDesc(val.Weight)
  202 + key := e.dataKey(val.TargetUserId, val.EvaluationProjectId, val.BeginDay, val.Category, weight, val.ContentName)
  203 + e.data[key] = &strings.Builder{}
  204 + e.data[key].WriteString(val.Value + "\n") //填写的等级
  205 + for _, vv := range val.Remark {
  206 + e.data[key].WriteString(vv.Title + "\n")
  207 + e.data[key].WriteString(vv.RemarkText + "\n")
  208 + }
  209 + dayKey := val.TargetUserId + val.EvaluationProjectId + val.BeginDay
  210 + if _, ok := userDay[dayKey]; !ok {
  211 + userDay[dayKey] = struct{}{}
  212 + k := e.userDayKey(val.TargetUserId, val.EvaluationProjectId)
  213 + e.userDayMap[k] = append(e.userDayMap[k], val.BeginDay)
  214 + }
  215 + key23 := e.data23Key(val.TargetUserId, val.Category, weight, val.ContentName)
  216 + e.data2[key23] = val.PromptText
  217 + if val.Weight == 0 {
  218 + e.data3[key23] = ""
  219 + } else {
  220 + e.data3[key23] = fmt.Sprintf("%.2f%%", val.Weight)
  221 + }
  222 + }
  223 +}
68 224
  225 +func (e *exportData3) weightDesc(weight float64) string {
  226 + if weight == 0 {
  227 + return "加分项"
  228 + } else {
  229 + return "得分项"
69 } 230 }
70 } 231 }
71 232
72 -func (e *exportData3) FormatListValue(param []dao.DataStaffAssessContent2) { 233 +func (e *exportData3) dataKey(userId string, projectId string, beginDay string, category string, weight string, contentName string) string {
  234 + key := fmt.Sprintf("%s-%s-%s-%s-%s-%s", userId, projectId, weight, beginDay, category, contentName)
  235 + return key
  236 +}
73 237
  238 +func (e *exportData3) data23Key(userId string, category string, weight string, contentName string) string {
  239 + key := fmt.Sprintf("%s-%s-%s-%s", userId, weight, category, contentName)
  240 + return key
74 } 241 }
75 242
76 -func (e *exportData3) DataKey(userName string, projectId string, beginDay string, category string, weight string, contentName string) string {  
77 - return "" 243 +func (e *exportData3) userDayKey(userId string, projectId string) string {
  244 + return fmt.Sprintf("%s-%s", userId, projectId)
78 } 245 }
@@ -32,8 +32,8 @@ func (h *HeaderLevel) addChild(name string) (child *HeaderLevel) { @@ -32,8 +32,8 @@ func (h *HeaderLevel) addChild(name string) (child *HeaderLevel) {
32 } 32 }
33 33
34 type exportData struct { 34 type exportData struct {
35 - userName []string //员工的名称列表 ,对应excel文件的多个sheet  
36 - usrIdMap map[string]string 35 + userName []string //员工的名称列表 ,对应excel文件的多个sheet
  36 + usrIdMap map[string]string //员工id对应的名字
37 userDayMap map[string][]string //每个员工对应的日期列表 key=员工名称 value= 日期列表 37 userDayMap map[string][]string //每个员工对应的日期列表 key=员工名称 value= 日期列表
38 tableHeader map[string]*HeaderLevel //每个员工数据表格对应表头 key=员工名称 38 tableHeader map[string]*HeaderLevel //每个员工数据表格对应表头 key=员工名称
39 data map[string]*strings.Builder //每个员工表头对应的评估填写的数据 key=员工名称+日期+表头 39 data map[string]*strings.Builder //每个员工表头对应的评估填写的数据 key=员工名称+日期+表头
@@ -311,7 +311,7 @@ func (c *StaffAssessController) ExportUserAssess2() { @@ -311,7 +311,7 @@ func (c *StaffAssessController) ExportUserAssess2() {
311 userReq := middlewares.GetUser(c.Ctx) 311 userReq := middlewares.GetUser(c.Ctx)
312 paramReq.CompanyId = int(userReq.CompanyId) 312 paramReq.CompanyId = int(userReq.CompanyId)
313 paramReq.OperatorId = int(userReq.UserId) 313 paramReq.OperatorId = int(userReq.UserId)
314 - data, err := srv.ExportUserAssess2(paramReq) 314 + data, err := srv.ExportUserAssess2V2(paramReq)
315 if err != nil { 315 if err != nil {
316 c.Response(nil, err) 316 c.Response(nil, err)
317 return 317 return