From ad6626e67b9e0ce35a72ef44828d8b6df4350f7d Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 9 May 2025 11:53:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Execl=E8=AF=BB=E5=86=99=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/framework/utils/file/excel.go | 158 +++++++++++++++------- src/modules/system/controller/sys_user.go | 2 +- 2 files changed, 110 insertions(+), 50 deletions(-) diff --git a/src/framework/utils/file/excel.go b/src/framework/utils/file/excel.go index 2d52683c..b19676ec 100644 --- a/src/framework/utils/file/excel.go +++ b/src/framework/utils/file/excel.go @@ -37,55 +37,6 @@ func TransferExeclUploadFile(file *multipart.FileHeader) (string, error) { return filepath.ToSlash(writePathFile), nil } -// 表格读取数据 -// -// filePath 文件路径地址 -// -// sheetName 工作簿名称, 空字符默认Sheet1 -func ReadSheet(filePath, sheetName string) ([]map[string]string, error) { - data := make([]map[string]string, 0) - // 打开 Excel 文件 - f, err := excelize.OpenFile(filePath) - if err != nil { - return data, err - } - defer func() { - if err := f.Close(); err != nil { - logger.Errorf("ReadSheet to close worksheet file : %v", err) - } - }() - - // 检查工作簿是否存在 - if sheetName == "" { - sheetName = "Sheet1" - } - if visible, _ := f.GetSheetVisible(sheetName); !visible { - return data, fmt.Errorf("failed to read workbook %s", sheetName) - } - - // 获取工作簿记录 - rows, err := f.GetRows(sheetName) - if err != nil { - return data, err - } - - for i, row := range rows { - // 跳过第一行 - if i == 0 { - continue - } - // 遍历每个单元格 - rowData := map[string]string{} - for columnIndex, cellValue := range row { - columnName, _ := excelize.ColumnNumberToName(columnIndex + 1) - rowData[columnName] = cellValue - } - - data = append(data, rowData) - } - return data, nil -} - // 表格写入数据 // // headerCells 第一行表头标题 "A1":"?" @@ -152,3 +103,112 @@ func WriteSheet(headerCells map[string]string, dataCells []map[string]any, fileN } return saveFilePath, nil } + +// WriterFileExecl 写入xlsx文件 +// +// 例如: +// headerCells := map[string]string{"A1": "姓名", "B1": "年龄", "C1": "城市"} +// +// dataCells := []map[string]any{ +// {"A2": "1", "B2": "2", "C2": "3"}, +// } +// +// filePath := "example.xlsx" +// err := file.WriterFileExecl(headerCells, dataCells, filePath, "Sheet1") +func WriterFileExecl(headerCells map[string]string, dataCells []map[string]any, filePath, sheetName string) error { + f := excelize.NewFile() + defer func() { + if err := f.Close(); err != nil { + logger.Errorf("WriterFileExecl to close worksheet file: %v", err) + } + }() + + // 创建一个工作表 + if sheetName == "" { + sheetName = "Sheet1" + } + index, err := f.NewSheet(sheetName) + if err != nil { + return fmt.Errorf("failed to create worksheet %v", err) + } + // 设置工作簿的默认工作表 + f.SetActiveSheet(index) + + // 首个和最后key名称 + firstKey := "A" + lastKey := "B" + + // 第一行表头标题 + for key, title := range headerCells { + f.SetCellValue(sheetName, key, title) + if key[:1] > lastKey { + lastKey = key[:1] + } + } + + // 设置工作表上宽度为 20 + f.SetColWidth(sheetName, firstKey, lastKey, 20) + + // 从第二行开始的数据 + for _, cell := range dataCells { + for key, value := range cell { + f.SetCellValue(sheetName, key, value) + } + } + + // 创建文件目录 + if err := os.MkdirAll(filepath.Dir(filePath), 0775); err != nil { + return fmt.Errorf("failed to create save file %v", err) + } + + // 根据指定路径保存文件 + if err := f.SaveAs(filePath); err != nil { + return fmt.Errorf("failed to save worksheet %v", err) + } + return nil +} + +// ReadFileExecl 读取xlsx文件 转换数组数据 +func ReadFileExecl(filePath, sheetName string) ([]map[string]string, error) { + data := make([]map[string]string, 0) + // 打开 Excel 文件 + f, err := excelize.OpenFile(filePath) + if err != nil { + return data, err + } + defer func() { + if err := f.Close(); err != nil { + logger.Errorf("ReadSheet to close worksheet file : %v", err) + } + }() + + // 检查工作簿是否存在 + if sheetName == "" { + sheetName = "Sheet1" + } + if visible, _ := f.GetSheetVisible(sheetName); !visible { + return data, fmt.Errorf("failed to read workbook %s", sheetName) + } + + // 获取工作簿记录 + rows, err := f.GetRows(sheetName) + if err != nil { + return data, err + } + + for i, row := range rows { + // 跳过第一行 + if i == 0 { + continue + } + // 遍历每个单元格 + rowData := map[string]string{} + for columnIndex, cellValue := range row { + columnName, _ := excelize.ColumnNumberToName(columnIndex + 1) + rowData[columnName] = cellValue + } + + data = append(data, rowData) + } + return data, nil +} diff --git a/src/modules/system/controller/sys_user.go b/src/modules/system/controller/sys_user.go index 22c12b18..84961a9d 100644 --- a/src/modules/system/controller/sys_user.go +++ b/src/modules/system/controller/sys_user.go @@ -655,7 +655,7 @@ func (s *SysUserController) Import(c *gin.Context) { // 表格文件绝对地址 filePath := file.ParseUploadFileAbsPath(body.FilePath) // 读取表格数据 - rows, err := file.ReadSheet(filePath, "") + rows, err := file.ReadFileExecl(filePath, "") if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return