|
|
package converter
|
|
|
|
|
|
import (
|
|
|
"bytes"
|
|
|
"encoding/csv"
|
|
|
"fmt"
|
|
|
"github.com/linmadan/egglib-go/utils/excel"
|
|
|
"golang.org/x/text/encoding/simplifiedchinese"
|
|
|
"golang.org/x/text/transform"
|
|
|
"io"
|
|
|
"strings"
|
|
|
"unicode/utf8"
|
|
|
)
|
|
|
|
|
|
type (
|
|
|
CSVReader struct {
|
|
|
Data *excel.ExcelImport
|
|
|
}
|
|
|
)
|
|
|
|
|
|
func (cr *CSVReader) ToMap(reader io.Reader) ([]map[string]string, error) {
|
|
|
var err error
|
|
|
if reader, err = cr.PrepareCheck(reader); err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
r := csv.NewReader(reader)
|
|
|
rows := make([]map[string]string, 0)
|
|
|
var header = make([]string, 0)
|
|
|
var headerMap = make(map[string]string)
|
|
|
var index int = 0
|
|
|
for i := range cr.Data.DataFields {
|
|
|
item := cr.Data.DataFields[i]
|
|
|
headerMap[item.CnName] = item.EnName
|
|
|
}
|
|
|
|
|
|
for {
|
|
|
index++
|
|
|
|
|
|
record, err := r.Read()
|
|
|
if err == io.EOF {
|
|
|
break
|
|
|
}
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if index <= cr.Data.RowBegin-1 {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
if len(header) == 0 {
|
|
|
header = record
|
|
|
} else {
|
|
|
dict := map[string]string{}
|
|
|
for i := range header {
|
|
|
if column, ok := headerMap[header[i]]; ok {
|
|
|
dict[column] = record[i]
|
|
|
}
|
|
|
}
|
|
|
rows = append(rows, dict)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
return rows, nil
|
|
|
}
|
|
|
|
|
|
func (cr *CSVReader) PrepareCheck(reader io.Reader) (io.Reader, error) {
|
|
|
return GBKToUtf8(reader)
|
|
|
}
|
|
|
|
|
|
func GBKToUtf8(readIn io.Reader) (io.Reader, error) {
|
|
|
var (
|
|
|
err error
|
|
|
fileByte []byte
|
|
|
)
|
|
|
fileByte, err = io.ReadAll(readIn)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
if utf8.Valid(fileByte) {
|
|
|
return bytes.NewReader(fileByte), nil
|
|
|
} else {
|
|
|
utf8Reader := transform.NewReader(bytes.NewReader(fileByte), simplifiedchinese.GBK.NewDecoder())
|
|
|
return utf8Reader, nil
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func OpenImportFileFromIoReader(ex *excel.ExcelImport, reader io.Reader, ext string) ([]map[string]string, error) {
|
|
|
var tmp []map[string]string
|
|
|
var err error
|
|
|
if ext == "csv" || ext == ".csv" {
|
|
|
csvReader := &CSVReader{ex}
|
|
|
tmp, err = csvReader.ToMap(reader)
|
|
|
} else {
|
|
|
tmp, err = ex.OpenExcelFromIoReader(reader)
|
|
|
}
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
var response []map[string]string
|
|
|
for i := range tmp {
|
|
|
if fieldValueAllEmpty(tmp[i]) {
|
|
|
continue
|
|
|
}
|
|
|
response = append(response, tmp[i])
|
|
|
}
|
|
|
return response, nil
|
|
|
}
|
|
|
|
|
|
func fieldValueAllEmpty(param map[string]string) bool {
|
|
|
isAllEmpty := true
|
|
|
for _, v := range param {
|
|
|
value := strings.TrimSpace(v)
|
|
|
if len(value) > 0 {
|
|
|
isAllEmpty = false
|
|
|
}
|
|
|
}
|
|
|
return isAllEmpty
|
|
|
}
|
|
|
|
|
|
// TODO: export csv
|
|
|
func MakeToCsv(sourData excel.ExcelMaker, w io.Writer) error {
|
|
|
_, err := w.Write([]byte("\xEF\xBB\xBF")) //写入UTF-8 BOM
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
csvWriter := csv.NewWriter(w)
|
|
|
fields := sourData.DataFieldList()
|
|
|
firstRow := []string{}
|
|
|
for i := range fields {
|
|
|
firstRow = append(firstRow, fields[i].CnName)
|
|
|
}
|
|
|
title := sourData.TableTitle()
|
|
|
if len(title) > 0 {
|
|
|
csvWriter.Write(title)
|
|
|
}
|
|
|
csvWriter.Write(firstRow)
|
|
|
dataLenght := sourData.DataListLen()
|
|
|
for i := 0; i < dataLenght; i++ {
|
|
|
rowData := []string{}
|
|
|
for ii := range fields {
|
|
|
cellValue := sourData.CellValue(i, fields[ii].EnName)
|
|
|
str := ""
|
|
|
if cellValue != nil {
|
|
|
str = fmt.Sprintf("%v", cellValue)
|
|
|
}
|
|
|
rowData = append(rowData, str)
|
|
|
}
|
|
|
csvWriter.Write(rowData)
|
|
|
}
|
|
|
csvWriter.Flush()
|
|
|
return csvWriter.Error()
|
|
|
} |
...
|
...
|
|