签入版本

This commit is contained in:
小蚂蚁云
2026-10-20 19:08:49 +08:00
commit 1f248e89e4
890 changed files with 119227 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
// Package excel 导入导出封装
//
// 基于 xuri/excelize/v2 实现,支持 xls 与 xlsx
package excel
import (
"fmt"
"mime/multipart"
"os"
"path/filepath"
"strings"
"time"
"github.com/xuri/excelize/v2"
)
// ============================== Excel 导入导出 ==============================
// FileOpener 可打开的上传文件接口
//
// ghttp.UploadFile 与 multipart.FileHeader 均满足该接口
type FileOpener interface {
Open() (multipart.File, error)
}
// ReadSheet 读取上传文件的首个工作表
//
// 返回表头与数据行列表,首行视为表头,所有单元格值统一转为字符串;
// 空行会被跳过
func ReadSheet(file FileOpener) (headers []string, rows [][]string, err error) {
f, err := file.Open()
if err != nil {
return nil, nil, err
}
defer f.Close()
xl, err := excelize.OpenReader(f)
if err != nil {
return nil, nil, fmt.Errorf("解析Excel失败: %v", err)
}
defer xl.Close()
sheet := xl.GetSheetName(0)
all, err := xl.GetRows(sheet)
if err != nil {
return nil, nil, err
}
if len(all) == 0 {
return nil, nil, fmt.Errorf("Excel内容为空")
}
for _, h := range all[0] {
headers = append(headers, strings.TrimSpace(h))
}
for _, row := range all[1:] {
if isBlankRow(row) {
continue
}
cells := make([]string, len(headers))
for i := range headers {
if i < len(row) {
cells[i] = strings.TrimSpace(row[i])
}
}
rows = append(rows, cells)
}
return headers, rows, nil
}
// WriteSheet 写出 xlsx 文件
//
// 文件写入指定目录,文件名由基础名与时间戳拼接而成;
// 返回文件名与完整路径
func WriteSheet(dir, baseName string, headers []string, rows [][]any) (fileName, filePath string, err error) {
if err = os.MkdirAll(dir, 0o755); err != nil {
return "", "", err
}
xl := excelize.NewFile()
defer xl.Close()
sheet := xl.GetSheetName(0)
_ = xl.SetSheetName(sheet, "data")
sheet = "data"
for i, h := range headers {
cell, _ := excelize.CoordinatesToCellName(i+1, 1)
if err = xl.SetCellValue(sheet, cell, h); err != nil {
return "", "", err
}
}
for r, row := range rows {
for c, v := range row {
cell, _ := excelize.CoordinatesToCellName(c+1, r+2)
if err = xl.SetCellValue(sheet, cell, v); err != nil {
return "", "", err
}
}
}
fileName = fmt.Sprintf("%s_%s.xlsx", baseName, time.Now().Format("20060102150405"))
filePath = filepath.Join(dir, fileName)
if err = xl.SaveAs(filePath); err != nil {
return "", "", err
}
return fileName, filePath, nil
}
// isBlankRow 判断是否为空行
//
// 所有单元格均为空时返回 true
func isBlankRow(row []string) bool {
for _, c := range row {
if strings.TrimSpace(c) != "" {
return false
}
}
return true
}