feat: 配置数据导出Excel
This commit is contained in:
@@ -2,7 +2,9 @@ package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/ctx"
|
||||
@@ -147,6 +149,42 @@ func (s *PtNeConfigDataController) Contrast(c *gin.Context) {
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 配置数据导出Excel
|
||||
//
|
||||
// GET /export
|
||||
func (s *PtNeConfigDataController) Export(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
Student string `form:"student"` // 教师携带学生账号查询
|
||||
}
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
loginUser, _ := ctx.LoginUser(c)
|
||||
currentUserName := loginUser.User.UserName
|
||||
for _, v := range loginUser.User.Roles {
|
||||
// if v.RoleKey == "admin" {}
|
||||
if v.RoleKey == "teacher" {
|
||||
// 查看学生数据
|
||||
if querys.Student != "" {
|
||||
currentUserName = querys.Student
|
||||
}
|
||||
}
|
||||
// if v.RoleKey == "student" {}
|
||||
}
|
||||
|
||||
fileName := fmt.Sprintf("%s_config_data_%d.xlsx", currentUserName, time.Now().Unix())
|
||||
filePath, err := s.ptNeConfigDataService.ExportToExcel(currentUserName, fileName)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(fmt.Sprintf("exprot err: %s", err.Error())))
|
||||
return
|
||||
}
|
||||
c.FileAttachment(filePath, fileName)
|
||||
}
|
||||
|
||||
// 网元参数配置信息
|
||||
//
|
||||
// GET /
|
||||
|
||||
@@ -32,6 +32,11 @@ func Setup(router *gin.Engine) {
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewPtNeConfigData.Contrast,
|
||||
)
|
||||
neConfigDataGroup.GET("/export",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigData", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewPtNeConfigData.Export,
|
||||
)
|
||||
neConfigDataGroup.GET("",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewPtNeConfigData.Info,
|
||||
|
||||
@@ -36,4 +36,7 @@ type IPtNeConfigDataService interface {
|
||||
|
||||
// ApplyToNe 参数应用到网元
|
||||
ApplyToNe(paramUser, neType string) error
|
||||
|
||||
// ExportToExcel 导出网元的全部配置项数据
|
||||
ExportToExcel(operaUserName, fileName string) (string, error)
|
||||
}
|
||||
|
||||
@@ -3,14 +3,19 @@ package service
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
|
||||
"be.ems/src/framework/constants/uploadsubpath"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neModel "be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"be.ems/src/modules/practical_training/model"
|
||||
"be.ems/src/modules/practical_training/repository"
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
// NewPtNeConfigDataService 实例化服务层
|
||||
@@ -302,3 +307,155 @@ func (r *PtNeConfigDataService) ApplyToNe(paramUser, neType string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExportToExcel 导出网元的全部配置项数据
|
||||
func (r *PtNeConfigDataService) ExportToExcel(operaUserName, fileName string) (string, error) {
|
||||
confs := r.neConfigService.SelectNeConfigByNeType("*")
|
||||
datas := r.ptNeConfigDataRepository.SelectList(model.PtNeConfigData{CreateBy: operaUserName})
|
||||
return r.writeSheet(confs, datas, fileName)
|
||||
}
|
||||
|
||||
// writeSheet 写入表格
|
||||
func (r *PtNeConfigDataService) writeSheet(sheetData []neModel.NeConfig, cellData []model.PtNeConfigData, fileName string) (string, error) {
|
||||
f := excelize.NewFile()
|
||||
defer f.Close()
|
||||
|
||||
// 设置颜色填充
|
||||
styleType, _ := f.NewStyle(&excelize.Style{Fill: excelize.Fill{
|
||||
Type: "pattern",
|
||||
Pattern: 1,
|
||||
Color: []string{"F0F806"}, // RRGGBB 格式的
|
||||
}})
|
||||
styleRow, _ := f.NewStyle(&excelize.Style{Fill: excelize.Fill{
|
||||
Type: "pattern",
|
||||
Pattern: 1,
|
||||
Color: []string{"D0CECE"}, // RRGGBB 格式的
|
||||
}})
|
||||
styleMore, _ := f.NewStyle(&excelize.Style{Font: &excelize.Font{
|
||||
Color: "4472C4",
|
||||
VertAlign: "center",
|
||||
}})
|
||||
// 网元工作簿行计数
|
||||
sheetNameRows := make(map[string]int)
|
||||
|
||||
for _, sd := range sheetData {
|
||||
_ = json.Unmarshal([]byte(sd.ParamJson), &sd.ParamData)
|
||||
// 取到对应数据
|
||||
var data model.PtNeConfigData
|
||||
for _, cell := range cellData {
|
||||
if cell.NeType == sd.NeType && cell.ParamName == sd.ParamName {
|
||||
data = cell
|
||||
break
|
||||
}
|
||||
}
|
||||
if err := json.Unmarshal([]byte(data.ParamJson), &data.ParamData); err != nil || len(data.ParamData) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
sheetName := sd.NeType
|
||||
// 创建一个工作表
|
||||
f.NewSheet(sheetName)
|
||||
// 设置工作表上宽度为 20
|
||||
// f.SetColWidth(sheetName, "B", "C", 20)
|
||||
sheetRows := 1
|
||||
if v, ok := sheetNameRows[sheetName]; ok && v != 0 {
|
||||
sheetRows = v
|
||||
}
|
||||
// 合并标题单元格
|
||||
f.MergeCell(sheetName, fmt.Sprintf("A%d", sheetRows), fmt.Sprintf("C%d", sheetRows))
|
||||
f.SetCellStyle(sheetName, fmt.Sprintf("A%d", sheetRows), fmt.Sprintf("C%d", sheetRows), styleType)
|
||||
// 标题
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("A%d", sheetRows), sd.ParamDisplay)
|
||||
sheetRows += 1
|
||||
|
||||
// fmt.Println(sheetName, " ========= ", sd.ParamDisplay, " ==== ", sd.ParamType, len(data.ParamData))
|
||||
itemData := []*[]any{}
|
||||
|
||||
if sd.ParamType == "list" {
|
||||
itemData = append(itemData, &[]any{"Key", "Value"})
|
||||
for _, v := range sd.ParamData {
|
||||
name := v["name"].(string)
|
||||
value := v["value"]
|
||||
// 取到对应数据
|
||||
for _, dv := range data.ParamData {
|
||||
value = dv[name]
|
||||
}
|
||||
itemData = append(itemData, &[]any{v["display"], value})
|
||||
}
|
||||
}
|
||||
|
||||
if sd.ParamType == "array" {
|
||||
rowTitle := []any{} // 行头
|
||||
rowData := make([][]any, len(data.ParamData)) // 行数据
|
||||
for _, v := range sd.ParamData {
|
||||
rowTitle = append(rowTitle, v["display"])
|
||||
name := v["name"].(string)
|
||||
// 取到对应数据
|
||||
for i, dv := range data.ParamData {
|
||||
rowData[i] = append(rowData[i], dv[name])
|
||||
}
|
||||
}
|
||||
itemData = append(itemData, &rowTitle)
|
||||
for _, v := range rowData {
|
||||
item := v
|
||||
itemData = append(itemData, &item)
|
||||
}
|
||||
}
|
||||
|
||||
for i, row := range itemData {
|
||||
// 行头样式
|
||||
if i == 0 {
|
||||
f.SetCellStyle(sheetName, fmt.Sprintf("A%d", sheetRows), fmt.Sprintf("A%d", sheetRows), styleRow)
|
||||
}
|
||||
|
||||
f.SetSheetRow(sheetName, fmt.Sprintf("A%d", sheetRows), row)
|
||||
|
||||
// 存在array子层时转字符串
|
||||
for i, s := range *row {
|
||||
if reflect.ValueOf(s).Kind() == reflect.Slice {
|
||||
if cell, err := excelize.CoordinatesToCellName(i+1, sheetRows); err == nil {
|
||||
b, _ := json.Marshal(s)
|
||||
f.SetCellDefault(sheetName, cell, "#")
|
||||
f.SetCellStyle(sheetName, cell, cell, styleMore)
|
||||
f.AddComment(sheetName, excelize.Comment{
|
||||
Cell: cell,
|
||||
Author: "OMC",
|
||||
Text: string(b),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sheetRows += 1
|
||||
}
|
||||
|
||||
// 记下次写入的行数
|
||||
sheetRows += 2
|
||||
sheetNameRows[sheetName] = sheetRows
|
||||
}
|
||||
|
||||
// 默认工作表
|
||||
f.SetCellValue("Sheet1", "A1", cellData[0].CreateBy)
|
||||
f.MergeCell("Sheet1", "A1", "B1")
|
||||
f.SetCellStyle("Sheet1", "A1", "B1", styleType)
|
||||
f.SetCellValue("Sheet1", "A2", "5GC")
|
||||
f.SetCellStyle("Sheet1", "A2", "A2", styleRow)
|
||||
sheetNameData := []any{}
|
||||
for k := range sheetNameRows {
|
||||
sheetNameData = append(sheetNameData, k)
|
||||
}
|
||||
f.SetSheetRow("Sheet1", "A3", &sheetNameData)
|
||||
|
||||
// 上传资源路径
|
||||
filePath := file.ParseUploadFileDir(uploadsubpath.EXPORT)
|
||||
saveFilePath := filepath.ToSlash(filepath.Join(filePath, fileName))
|
||||
// 创建文件目录
|
||||
if err := os.MkdirAll(filepath.Dir(saveFilePath), 0775); err != nil {
|
||||
return "", fmt.Errorf("failed to create save file %v", err)
|
||||
}
|
||||
// 根据指定路径保存文件
|
||||
if err := f.SaveAs(saveFilePath); err != nil {
|
||||
return "", fmt.Errorf("failed to save worksheet %v", err)
|
||||
}
|
||||
return saveFilePath, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user