From cc43c1429f6c21f9e0da7120c3595b8097da8c6e Mon Sep 17 00:00:00 2001 From: gazebo Date: Fri, 24 May 2019 16:44:34 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96excel.Obj2Excel=E6=80=A7?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E4=B8=8D=E4=BD=BF=E7=94=A8Struct2FlatMap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxutils/excel/excel.go | 49 ++++++++++++---- business/jxutils/excel/excel_test.go | 84 ++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 12 deletions(-) diff --git a/business/jxutils/excel/excel.go b/business/jxutils/excel/excel.go index 1226d502d..217a4493f 100644 --- a/business/jxutils/excel/excel.go +++ b/business/jxutils/excel/excel.go @@ -45,19 +45,44 @@ func Obj2Excel(sheetList []*Obj2ExcelSheetConfig) []byte { } else { excelFile.NewSheet(sheetConfig.Title) } - for index, name := range sheetConfig.CaptionList { - excelFile.SetCellStr(sheetConfig.Title, genAxis(0, index), name) - } - for i := 0; i < valueInfo.Len(); i++ { - var mapData map[string]interface{} - if typeInfo.Kind() == reflect.Struct { - mapData = utils.FlatMap(utils.Struct2MapByJson(valueInfo.Index(i).Interface())) - } else { - mapData = valueInfo.Index(i).Interface().(map[string]interface{}) + isMemberStruct := typeInfo.Kind() == reflect.Struct + if isMemberStruct { + var indexSlice [][]int + name2IndexMap := utils.GetStructNameIndex(typeInfo, "json") + for col, name := range sheetConfig.CaptionList { + if _, ok := name2IndexMap[name]; !ok { + panic(fmt.Sprintf("col:%s不能找到相应的数据", name)) + } + indexSlice = append(indexSlice, name2IndexMap[name]) + excelFile.SetCellStr(sheetConfig.Title, genAxis(0, col), name) } - for index, name := range sheetConfig.CaptionList { - // globals.SugarLogger.Debug(sheetConfig.Title, " ", genAxis(i+1, index), " ", fmt.Sprintf("%v", mapData[name])) - excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, index), fmt.Sprintf("%v", mapData[name])) + for i := 0; i < valueInfo.Len(); i++ { + for col, index := range indexSlice { + excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, col), fmt.Sprint(reflect.Indirect(valueInfo.Index(i)).FieldByIndex(index).Interface())) + } + } + } else { + var name2IndexMap map[string]int + if valueInfo.Len() > 0 { + oneData := valueInfo.Index(0).Interface().(map[string]interface{}) + name2IndexMap = make(map[string]int) + for k := range oneData { + name2IndexMap[k] = 1 + } + } + for col, name := range sheetConfig.CaptionList { + if name2IndexMap != nil { + if _, ok := name2IndexMap[name]; !ok { + panic(fmt.Sprintf("col:%s不能找到相应的数据", name)) + } + } + excelFile.SetCellStr(sheetConfig.Title, genAxis(0, col), name) + } + for i := 0; i < valueInfo.Len(); i++ { + mapData := valueInfo.Index(i).Interface().(map[string]interface{}) + for col, name := range sheetConfig.CaptionList { + excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, col), fmt.Sprint(mapData[name])) + } } } } diff --git a/business/jxutils/excel/excel_test.go b/business/jxutils/excel/excel_test.go index 4faec4626..659797a51 100644 --- a/business/jxutils/excel/excel_test.go +++ b/business/jxutils/excel/excel_test.go @@ -1,9 +1,47 @@ package excel import ( + "reflect" "testing" ) +type XXXX struct { + ID int64 `orm:"column(id)" json:"id"` + VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` + VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` + StoreID int `orm:"column(store_id)" json:"storeID"` // 外部系统里记录的 jxstoreid + JxStoreID int `orm:"column(jx_store_id)" json:"jxStoreID"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid + StoreName string `orm:"size(64)" json:"storeName"` + ShopPrice int64 `json:"shopPrice"` // 单位为分 门店标价 + SalePrice int64 `json:"salePrice"` // 单位为分 售卖价 + ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付 + Weight int `json:"weight"` // 单位为克 + ConsigneeName string `orm:"size(32)" json:"consigneeName"` + ConsigneeMobile string `orm:"size(32)" json:"consigneeMobile"` + ConsigneeMobile2 string `orm:"size(32)" json:"consigneeMobile2"` + ConsigneeAddress string `orm:"size(255)" json:"consigneeAddress"` + CoordinateType int `json:"-"` + ConsigneeLng int `json:"-"` // 坐标 * (10的六次方) + ConsigneeLat int `json:"-"` // 坐标 * (10的六次方) + SkuCount int `json:"skuCount"` // 商品类别数量,即有多少种商品(注意在某些情况下,相同SKU的商品由于售价不同,也会当成不同商品在这个值里) + GoodsCount int `json:"goodsCount"` // 商品个数 + Status int `json:"status"` // 参见OrderStatus*相关的常量定义 + VendorStatus string `orm:"size(255)" json:"vendorStatus"` + LockStatus int `json:"lockStatus"` + OrderSeq int `json:"orderSeq"` // 门店订单序号 + BuyerComment string `orm:"size(255)" json:"buyerComment"` + BusinessType int `json:"businessType"` + CancelApplyReason string `orm:"size(255)" json:"-"` // ""表示没有申请,不为null表示用户正在取消申请 + VendorWaybillID string `orm:"column(vendor_waybill_id);size(48)" json:"vendorWaybillID"` + WaybillVendorID int `orm:"column(waybill_vendor_id)" json:"waybillVendorID"` // 表示当前承运商,-1表示还没有安排 + DeliveryFlag int8 `json:"deliveryFlag"` // 第1位为1表示禁止调度器调度三方配送 + DuplicatedCount int `json:"-"` // 重复新订单消息数,这个一般不是由于消息重发造成的(消息重发由OrderStatus过滤),一般是业务逻辑造成的 + OriginalData string `orm:"-" json:"-"` // 只是用于传递数据 + Flag int8 `json:"flag"` //非运单调整相关的其它状态 +} + func TestObj2Excel(t *testing.T) { // kk := make([]*model.SkuName, 1) // kk[0] = &model.SkuName{ @@ -24,3 +62,49 @@ func TestObj2Excel(t *testing.T) { } Obj2Excel([]*Obj2ExcelSheetConfig{cc}) } + +func BenchmarkObj2Excel(b *testing.B) { + const sliceLen = 1000 + oneData := &XXXX{} + cc := &Obj2ExcelSheetConfig{ + Title: "Title", + CaptionList: nil, + } + elmType := reflect.TypeOf(oneData) + if elmType.Kind() == reflect.Ptr { + elmType = elmType.Elem() + } + for i := 0; i < elmType.NumField(); i++ { + if jsonTag := elmType.Field(i).Tag.Get("json"); jsonTag != "" && jsonTag != "-" { + cc.CaptionList = append(cc.CaptionList, jsonTag) + } + } + value := reflect.Indirect(reflect.ValueOf(oneData)) + for i := 0; i < elmType.NumField(); i++ { + value2 := value.Field(i) + if value2.Kind() == reflect.String { + value2.SetString(elmType.Field(i).Name) + } + } + + /* + data := make([]map[string]interface{}, sliceLen) + for k := range data { + data[k] = utils.Struct2MapByJson(oneData) + } + //*/ + + //* + data := make([]*XXXX, 1000) + for k := range data { + copied := *oneData + data[k] = &copied + } + //*/ + + cc.Data = data + for i := 0; i < b.N; i++ { + Obj2Excel([]*Obj2ExcelSheetConfig{cc}) + } + // b.Log(utils.Format4Output(data, false)) +}