• go 生成器读取csv文件 写csv文件 指定或不指定headers写入


    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))
    
    
    
    	
    }
    

      

  • 相关阅读:
    python 数据类型 变量 注释
    tornado 模版
    tornado 响应头 中断 状态码 工作流程
    tornado write render redirect IP
    tornado样板
    Celery实现异步任务
    Python pika简单实现RabbitMQ通信
    进程、线程与协程的比较
    使用 flask 实现 RESTful API
    阿里云服务器部署Tornado应用
  • 原文地址:https://www.cnblogs.com/zzay/p/15985273.html
Copyright © 2020-2023  润新知