正在显示
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 | +} |
-
请 注册 或 登录 后发表评论