package excel_import import ( "fmt" "github.com/bytedance/sonic" "os" "regexp" "sort" "strings" "time" ) func importLogPath(jobName string) (string, error) { path, err := os.Getwd() path = fmt.Sprintf("%s/%s/%s", path, "log/import", jobName) err = CheckDir(path) return path, err } func ImportLogPathByOrder(jobName string) (string, error) { path, err := os.Getwd() path = fmt.Sprintf("%s/%s/%s/excel/", path, "log/import", jobName) err = CheckDir(path) return path, err } func tempFile(jobName string) string { path, _ := os.Getwd() path = fmt.Sprintf("%s/%s/%s.xlsx", path, "docs/import_temp", jobName) return path } func CheckDir(path string) error { // 判断目录是否存在 if _, err := os.Stat(path); os.IsNotExist(err) { // 如果目录不存在,则创建它 err = os.MkdirAll(path, os.ModePerm) if err != nil { return err } } else if err != nil { // 如果Stat返回了其他错误(比如权限问题) return err } return nil } func SortFileWithStatus(dir string) []FileInfoStatus { // 获取目录中的文件信息 d, _ := os.Open(dir) defer d.Close() files, _ := d.ReadDir(0) var fileInfoList []FileInfoStatus // 填充切片 for _, file := range files { fileName := file.Name() fileInfo, _ := file.Info() bytes, _ := os.ReadFile(dir + "/" + fileName) var info Task _ = sonic.Unmarshal(bytes, &info) times, _ := time.Parse(time.DateTime, info.Ctime) fileInfoList = append(fileInfoList, FileInfoStatus{FileInfo: fileInfo, Status: info.Status, Time: times}) } // 根据修改时间对切片进行排序 sort.Slice(fileInfoList, func(i, j int) bool { return fileInfoList[i].Time.After(fileInfoList[j].Time) }) return fileInfoList } // SortHeader 根据SortSlice排序, // 这里这样设计主要是考虑在实际开发中可能会频繁的出现excel表里面插入或者删除字段,导致之后的导入数据的具体v[n]也需要跟着改的情况 // HeaderMap决定了v[n]和excel表里面的字段名之间的映射关系 // SortSlice决定了导入导出数据的顺序,里面的元素可以是HeaderMap里面的key,也可以是HeaderMap里面的value,这个取决于HeaderMap是否为nil // HeaderMap可以为nil,如果为nil,则SortSlice里面的元素就是excel表里面的字段名,如果HeaderMap不为nil,则SortSlice里面的元素则是经过HeaderMap映射之后的值 // 严格来说这里的SortSlice应该是一个interface{}类型的切片,这里使用了string是为了方便 //***最愚蠢的事情就是为了强迫症而强迫症 //func SortHeader(header *Header) []string { // if header.HeaderMap == nil { // return header.SortSlice // } // var sortSlice []string // for _, v := range header.SortSlice { // if _, exist := header.HeaderMap[v]; exist { // sortSlice = append(sortSlice, header.HeaderMap[v]) // } // } // return sortSlice //} func ExchangeRows(oldRows [][]string, setHeader []string) (rows []map[string]string) { oldRowsHeader := oldRows[0] oldRowsMap := make(map[string]int, len(oldRowsHeader)) for index, header := range oldRowsHeader { oldRowsMap[header] = index } for _, oldRow := range oldRows { newRow := make(map[string]string, len(setHeader)) lenOldRow := len(oldRow) for _, header := range setHeader { point, exist := oldRowsMap[header] if !exist || point >= lenOldRow { newRow[header] = "" } else { newRow[header] = oldRow[point] } } rows = append(rows, newRow) } return rows } func ExchangeRowWithMap(oldRow map[string]string, setHeader []string) (rows []string) { for _, header := range setHeader { rows = append(rows, oldRow[header]) } return rows } func Ter[T any](cond bool, a, b T) T { if cond { return a } return b } func RegexMatch(str string, pattern string) bool { matched, err := regexp.MatchString(pattern, str) if err != nil { return false } return matched } // IsExcelFormat 检查是否为 Excel 相关格式 func IsExcelFormat(fileObjectUrl string) bool { // 支持的扩展名 allowedExtensions := []string{".xls", ".xlsx", ".csv"} // 转为小写,避免大小写问题 fileObjectUrl = strings.ToLower(fileObjectUrl) // 遍历匹配扩展名 for _, ext := range allowedExtensions { if strings.HasSuffix(fileObjectUrl, ext) { return true } } return false }