package main import ( "encoding/csv" "encoding/json" "fmt" "io" "os" "strconv" "strings" "time" ) func readCsvYield(fPath string, seq rune, printNum int) chan map[string]interface{} { /* fPath: 输入文件 seq: 分隔符 printNum: 打印的行数 */ // var yield chan map[string]interface{} yield := make(chan map[string]interface{}) var resDict map[string]interface{} resDict = make(map[string]interface{}) go func() { file, err := os.Open(fPath) if err != nil { fmt.Println(err) close(yield) } defer file.Close() reader := csv.NewReader(file) // 设置分隔符seq reader.Comma = seq //reader.Comment = '\xEF\xBB\xBF' totalRows := -1 var keys []string for { row, err := reader.Read() if err != nil && err != io.EOF { fmt.Printf("can not read , err is %s", err) close(yield) } if err == io.EOF { fmt.Println("total:", totalRows) close(yield) break } // 获取key if totalRows == -1 { for _, r := range row { // utf-8 bom去掉 r = strings.Replace(r, "\uFEFF", "", -1) keys = append(keys, r) } totalRows += 1 continue } // 组合成字典 for idx, item := range row { resDict[keys[idx]] = item } totalRows += 1 yield <- resDict resDict = make(map[string]interface{}) if totalRows%printNum == 0 { fmt.Println(totalRows) } } }() return yield } func writeCsv(outFile string, data []map[string]interface{}) { file, err := os.OpenFile(outFile, os.O_CREATE|os.O_RDWR, 0644) if err != nil { fmt.Println(err) } defer file.Close() // 写入UTF-8 BOM 防止中文乱码 file.WriteString("\xEF\xBB\xBF") w := csv.NewWriter(file) var key []string for idx, item := range data { var values []string // 第一行写入 获取key 写入第一行 if idx == 0 { var tmpV []string for k, v := range item { key = append(key, k) v := Strval(v) tmpV = append(tmpV, v) } w.Write(key) w.Write(tmpV) continue } for _, k := range key { v := Strval(item[k]) values = append(values, v) } w.Write(values) w.Flush() } } func writeCsvWithHeader(outFile string, data []map[string]interface{}, headers []string) { file, err := os.OpenFile(outFile, os.O_CREATE|os.O_RDWR, 0644) if err != nil { fmt.Println(err) } defer file.Close() var key []string // 写入UTF-8 BOM 防止中文乱码 file.WriteString("\xEF\xBB\xBF") w := csv.NewWriter(file) key = append(key, headers...) w.Write(key) for _, item := range data { var values []string for _, k := range key { v := Strval(item[k]) values = append(values, v) } w.Write(values) w.Flush() } } func getHeader(inFile string, seq rune) []string{ var headers []string file, err := os.Open(inFile) if err != nil { fmt.Println("读取文件出错", err) return headers } reader := csv.NewReader(file) reader.Comma = seq recon, _ := reader.Read() headers = append(headers, recon...) defer file.Close() return headers } func Strval(value interface{}) string { var key string if value == nil { return key } switch value.(type) { case float64: ft := value.(float64) key = strconv.FormatFloat(ft, 'f', -1, 64) case float32: ft := value.(float32) key = strconv.FormatFloat(float64(ft), 'f', -1, 64) case int: it := value.(int) key = strconv.Itoa(it) case uint: it := value.(uint) key = strconv.Itoa(int(it)) case int8: it := value.(int8) key = strconv.Itoa(int(it)) case uint8: it := value.(uint8) key = strconv.Itoa(int(it)) case int16: it := value.(int16) key = strconv.Itoa(int(it)) case uint16: it := value.(uint16) key = strconv.Itoa(int(it)) case int32: it := value.(int32) key = strconv.Itoa(int(it)) case uint32: it := value.(uint32) key = strconv.Itoa(int(it)) case int64: it := value.(int64) key = strconv.FormatInt(it, 10) case uint64: it := value.(uint64) key = strconv.FormatUint(it, 10) case string: key = value.(string) case []byte: key = string(value.([]byte)) default: newValue, _ := json.Marshal(value) key = string(newValue) } return key } func main() { fileName := "D:\\tmp\\20220228\\9982.csv" startTime := time.Now() var res []map[string]interface{} for line := range readCsvYield(fileName, ',', 100000) { //fmt.Println(line["credit_code"]) //fmt.Println(line["name"]) res = append(res, line) } fmt.Println(res) fmt.Println(len(res)) endTime := time.Now() fmt.Println(endTime.Sub(startTime)) }