正在显示
7 个修改的文件
包含
181 行增加
和
12 行删除
@@ -12,4 +12,5 @@ require ( | @@ -12,4 +12,5 @@ require ( | ||
12 | github.com/google/uuid v1.1.1 | 12 | github.com/google/uuid v1.1.1 |
13 | github.com/linmadan/egglib-go v0.0.0-20210827085852-177fa745932d | 13 | github.com/linmadan/egglib-go v0.0.0-20210827085852-177fa745932d |
14 | github.com/stretchr/testify v1.7.0 | 14 | github.com/stretchr/testify v1.7.0 |
15 | + golang.org/x/text v0.3.6 | ||
15 | ) | 16 | ) |
@@ -11,6 +11,7 @@ type ImportDataCommand struct { | @@ -11,6 +11,7 @@ type ImportDataCommand struct { | ||
11 | //操作人 | 11 | //操作人 |
12 | Operator domain.Operator `json:"-"` | 12 | Operator domain.Operator `json:"-"` |
13 | Reader io.Reader `json:"-"` | 13 | Reader io.Reader `json:"-"` |
14 | + FileExt string `json:"-"` | ||
14 | // 业务编码 | 15 | // 业务编码 |
15 | Code string `form:"code"` | 16 | Code string `form:"code"` |
16 | } | 17 | } |
@@ -2,6 +2,7 @@ package service | @@ -2,6 +2,7 @@ package service | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/util/converter" | ||
5 | "strings" | 6 | "strings" |
6 | 7 | ||
7 | "github.com/linmadan/egglib-go/core/application" | 8 | "github.com/linmadan/egglib-go/core/application" |
@@ -43,15 +44,12 @@ func (srv ExcelDataService) ImportCooperationUser(importDataCommand *command.Imp | @@ -43,15 +44,12 @@ func (srv ExcelDataService) ImportCooperationUser(importDataCommand *command.Imp | ||
43 | {EnName: "phone", CnName: "*手机号"}, | 44 | {EnName: "phone", CnName: "*手机号"}, |
44 | {EnName: "email", CnName: "邮箱"}, | 45 | {EnName: "email", CnName: "邮箱"}, |
45 | } | 46 | } |
46 | - excelData, err := excelImport.OpenExcelFromIoReader(importDataCommand.Reader) | 47 | + excelData, err := converter.OpenImportFileFromIoReader(excelImport, importDataCommand.Reader, importDataCommand.FileExt) //excelImport.OpenExcelFromIoReader(importDataCommand.Reader) |
47 | if err != nil { | 48 | if err != nil { |
48 | return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) | 49 | return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) |
49 | } | 50 | } |
50 | users := make([]allied_creation_user.BatchAddUserItem, 0) | 51 | users := make([]allied_creation_user.BatchAddUserItem, 0) |
51 | for _, v := range excelData { | 52 | for _, v := range excelData { |
52 | - if srv.fieldValueAllEmpty(v) { | ||
53 | - continue | ||
54 | - } | ||
55 | item := allied_creation_user.BatchAddUserItem{ | 53 | item := allied_creation_user.BatchAddUserItem{ |
56 | CompanyId: importDataCommand.Operator.CompanyId, | 54 | CompanyId: importDataCommand.Operator.CompanyId, |
57 | UserType: domain.UserTypeCooperation, | 55 | UserType: domain.UserTypeCooperation, |
@@ -118,12 +118,25 @@ func (controller *BaseController) GetExcelFile() (io.Reader, error) { | @@ -118,12 +118,25 @@ func (controller *BaseController) GetExcelFile() (io.Reader, error) { | ||
118 | return nil, fmt.Errorf("上传文件不存在") | 118 | return nil, fmt.Errorf("上传文件不存在") |
119 | } | 119 | } |
120 | ext := filepath.Ext(fileHeader.Filename) | 120 | ext := filepath.Ext(fileHeader.Filename) |
121 | - if !(ext == ".xlsx" || ext == ".xls") { | ||
122 | - return nil, fmt.Errorf("仅支持上传文件格式 xls/xlsx") | 121 | + if !(ext == ".xlsx" || ext == ".xls" || ext == ".csv") { |
122 | + return nil, fmt.Errorf("仅支持上传文件格式 xls/xlsx/csv") | ||
123 | } | 123 | } |
124 | return excelFile, nil | 124 | return excelFile, nil |
125 | } | 125 | } |
126 | 126 | ||
127 | +func (controller *BaseController) GetFileWithExt() (io.Reader, string, error) { | ||
128 | + excelFile, fileHeader, err := controller.GetFile("file") | ||
129 | + if err != nil { | ||
130 | + log.Logger.Error(err.Error()) | ||
131 | + return nil, "", fmt.Errorf("上传文件不存在") | ||
132 | + } | ||
133 | + ext := filepath.Ext(fileHeader.Filename) | ||
134 | + if !(ext == ".xlsx" || ext == ".xls" || ext == ".csv") { | ||
135 | + return nil, "", fmt.Errorf("仅支持上传文件格式 xls/xlsx/csv") | ||
136 | + } | ||
137 | + return excelFile, ext, nil | ||
138 | +} | ||
139 | + | ||
127 | func Must(err error) { | 140 | func Must(err error) { |
128 | if err != nil { | 141 | if err != nil { |
129 | log.Logger.Error(err.Error()) | 142 | log.Logger.Error(err.Error()) |
@@ -189,9 +189,10 @@ func defaultImport(controller *ExcelDataController) { | @@ -189,9 +189,10 @@ func defaultImport(controller *ExcelDataController) { | ||
189 | data interface{} | 189 | data interface{} |
190 | err error | 190 | err error |
191 | r io.Reader | 191 | r io.Reader |
192 | + ext string | ||
192 | ) | 193 | ) |
193 | excelService := service.NewExcelDataService(nil) | 194 | excelService := service.NewExcelDataService(nil) |
194 | - r, err = controller.GetExcelFile() | 195 | + r, ext, err = controller.GetFileWithExt() |
195 | if err != nil { | 196 | if err != nil { |
196 | controller.Response(nil, err) | 197 | controller.Response(nil, err) |
197 | return | 198 | return |
@@ -200,6 +201,7 @@ func defaultImport(controller *ExcelDataController) { | @@ -200,6 +201,7 @@ func defaultImport(controller *ExcelDataController) { | ||
200 | controller.ParseForm(cmd) | 201 | controller.ParseForm(cmd) |
201 | cmd.Operator = controller.GetOperator() | 202 | cmd.Operator = controller.GetOperator() |
202 | cmd.Reader = r | 203 | cmd.Reader = r |
204 | + cmd.FileExt = ext | ||
203 | switch cmd.Code { | 205 | switch cmd.Code { |
204 | case domain.ImportCompanyUser: | 206 | case domain.ImportCompanyUser: |
205 | data, err = excelService.ImportCompanyUser(cmd) | 207 | data, err = excelService.ImportCompanyUser(cmd) |
@@ -296,11 +296,11 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | @@ -296,11 +296,11 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | ||
296 | col: columnNumber, | 296 | col: columnNumber, |
297 | name: "range many item (80<n<220)", | 297 | name: "range many item (80<n<220)", |
298 | ins: []Expr{ | 298 | ins: []Expr{ |
299 | - {OpChar: Range, Value: []interface{}{150, 180}, LeftOp: GreaterThanEqual, RightOp: LessThanEqual}, | ||
300 | - {OpChar: Range, Value: []interface{}{120, 220}, LeftOp: GreaterThanEqual, RightOp: LessThan}, | ||
301 | - {OpChar: Range, Value: []interface{}{100, 200}, LeftOp: GreaterThanEqual, RightOp: LessThanEqual}, | ||
302 | - {OpChar: Range, Value: []interface{}{80, 100}, LeftOp: GreaterThan, RightOp: LessThanEqual}, | ||
303 | - {OpChar: Range, Value: []interface{}{300, 500}, LeftOp: GreaterThan, RightOp: LessThanEqual}, | 299 | + {OpChar: Range, Value: []interface{}{"150", "180"}, LeftOp: GreaterThanEqual, RightOp: LessThanEqual}, |
300 | + {OpChar: Range, Value: []interface{}{"120", "220"}, LeftOp: GreaterThanEqual, RightOp: LessThan}, | ||
301 | + {OpChar: Range, Value: []interface{}{"100", "200"}, LeftOp: GreaterThanEqual, RightOp: LessThanEqual}, | ||
302 | + {OpChar: Range, Value: []interface{}{"80", "100"}, LeftOp: GreaterThan, RightOp: LessThanEqual}, | ||
303 | + {OpChar: Range, Value: []interface{}{"300", "500"}, LeftOp: GreaterThan, RightOp: LessThanEqual}, | ||
304 | }, | 304 | }, |
305 | except: nil, | 305 | except: nil, |
306 | exceptSql: "(( age > 80 and age < 220 ) or ( age > 300 and age <= 500 ))", | 306 | exceptSql: "(( age > 80 and age < 220 ) or ( age > 300 and age <= 500 ))", |
pkg/util/converter/converter.go
0 → 100644
1 | +package converter | ||
2 | + | ||
3 | +import ( | ||
4 | + "bytes" | ||
5 | + "encoding/csv" | ||
6 | + "fmt" | ||
7 | + "github.com/linmadan/egglib-go/utils/excel" | ||
8 | + "golang.org/x/text/encoding/simplifiedchinese" | ||
9 | + "golang.org/x/text/transform" | ||
10 | + "io" | ||
11 | + "strings" | ||
12 | + "unicode/utf8" | ||
13 | +) | ||
14 | + | ||
15 | +type ( | ||
16 | + CSVReader struct { | ||
17 | + Data *excel.ExcelImport | ||
18 | + } | ||
19 | +) | ||
20 | + | ||
21 | +func (cr *CSVReader) ToMap(reader io.Reader) ([]map[string]string, error) { | ||
22 | + var err error | ||
23 | + if reader, err = cr.PrepareCheck(reader); err != nil { | ||
24 | + return nil, err | ||
25 | + } | ||
26 | + | ||
27 | + r := csv.NewReader(reader) | ||
28 | + rows := make([]map[string]string, 0) | ||
29 | + var header = make([]string, 0) | ||
30 | + var headerMap = make(map[string]string) | ||
31 | + var index int = 0 | ||
32 | + for i := range cr.Data.DataFields { | ||
33 | + item := cr.Data.DataFields[i] | ||
34 | + headerMap[item.CnName] = item.EnName | ||
35 | + } | ||
36 | + | ||
37 | + for { | ||
38 | + index++ | ||
39 | + | ||
40 | + record, err := r.Read() | ||
41 | + if err == io.EOF { | ||
42 | + break | ||
43 | + } | ||
44 | + if err != nil { | ||
45 | + return nil, err | ||
46 | + } | ||
47 | + if index <= cr.Data.RowBegin-1 { | ||
48 | + continue | ||
49 | + } | ||
50 | + | ||
51 | + if len(header) == 0 { | ||
52 | + header = record | ||
53 | + } else { | ||
54 | + dict := map[string]string{} | ||
55 | + for i := range header { | ||
56 | + if column, ok := headerMap[header[i]]; ok { | ||
57 | + dict[column] = record[i] | ||
58 | + } | ||
59 | + } | ||
60 | + rows = append(rows, dict) | ||
61 | + } | ||
62 | + | ||
63 | + } | ||
64 | + return rows, nil | ||
65 | +} | ||
66 | + | ||
67 | +func (cr *CSVReader) PrepareCheck(reader io.Reader) (io.Reader, error) { | ||
68 | + return GBKToUtf8(reader) | ||
69 | +} | ||
70 | + | ||
71 | +func GBKToUtf8(readIn io.Reader) (io.Reader, error) { | ||
72 | + var ( | ||
73 | + err error | ||
74 | + fileByte []byte | ||
75 | + ) | ||
76 | + fileByte, err = io.ReadAll(readIn) | ||
77 | + if err != nil { | ||
78 | + return nil, err | ||
79 | + } | ||
80 | + | ||
81 | + if utf8.Valid(fileByte) { | ||
82 | + return bytes.NewReader(fileByte), nil | ||
83 | + } else { | ||
84 | + utf8Reader := transform.NewReader(bytes.NewReader(fileByte), simplifiedchinese.GBK.NewDecoder()) | ||
85 | + return utf8Reader, nil | ||
86 | + } | ||
87 | +} | ||
88 | + | ||
89 | +func OpenImportFileFromIoReader(ex *excel.ExcelImport, reader io.Reader, ext string) ([]map[string]string, error) { | ||
90 | + var tmp []map[string]string | ||
91 | + var err error | ||
92 | + if ext == "csv" || ext == ".csv" { | ||
93 | + csvReader := &CSVReader{ex} | ||
94 | + tmp, err = csvReader.ToMap(reader) | ||
95 | + } else { | ||
96 | + tmp, err = ex.OpenExcelFromIoReader(reader) | ||
97 | + } | ||
98 | + if err != nil { | ||
99 | + return nil, err | ||
100 | + } | ||
101 | + var response []map[string]string | ||
102 | + for i := range tmp { | ||
103 | + if fieldValueAllEmpty(tmp[i]) { | ||
104 | + continue | ||
105 | + } | ||
106 | + response = append(response, tmp[i]) | ||
107 | + } | ||
108 | + return response, nil | ||
109 | +} | ||
110 | + | ||
111 | +func fieldValueAllEmpty(param map[string]string) bool { | ||
112 | + isAllEmpty := true | ||
113 | + for _, v := range param { | ||
114 | + value := strings.TrimSpace(v) | ||
115 | + if len(value) > 0 { | ||
116 | + isAllEmpty = false | ||
117 | + } | ||
118 | + } | ||
119 | + return isAllEmpty | ||
120 | +} | ||
121 | + | ||
122 | +// TODO: export csv | ||
123 | +func MakeToCsv(sourData excel.ExcelMaker, w io.Writer) error { | ||
124 | + _, err := w.Write([]byte("\xEF\xBB\xBF")) //写入UTF-8 BOM | ||
125 | + if err != nil { | ||
126 | + return err | ||
127 | + } | ||
128 | + csvWriter := csv.NewWriter(w) | ||
129 | + fields := sourData.DataFieldList() | ||
130 | + firstRow := []string{} | ||
131 | + for i := range fields { | ||
132 | + firstRow = append(firstRow, fields[i].CnName) | ||
133 | + } | ||
134 | + title := sourData.TableTitle() | ||
135 | + if len(title) > 0 { | ||
136 | + csvWriter.Write(title) | ||
137 | + } | ||
138 | + csvWriter.Write(firstRow) | ||
139 | + dataLenght := sourData.DataListLen() | ||
140 | + for i := 0; i < dataLenght; i++ { | ||
141 | + rowData := []string{} | ||
142 | + for ii := range fields { | ||
143 | + cellValue := sourData.CellValue(i, fields[ii].EnName) | ||
144 | + str := "" | ||
145 | + if cellValue != nil { | ||
146 | + str = fmt.Sprintf("%v", cellValue) | ||
147 | + } | ||
148 | + rowData = append(rowData, str) | ||
149 | + } | ||
150 | + csvWriter.Write(rowData) | ||
151 | + } | ||
152 | + csvWriter.Flush() | ||
153 | + return csvWriter.Error() | ||
154 | +} |
-
请 注册 或 登录 后发表评论