From 5f6aec0aee49b5584a1f23a3e6ead90a9e2b6fdc Mon Sep 17 00:00:00 2001 From: lj-wsdj <1134294381@qq.com> Date: Thu, 16 May 2024 16:53:29 +0800 Subject: [PATCH] fix --- README.md | 9 ++- export/cell.go | 44 ++++++++++-- export/style.go | 39 ++++++++++ export/title.go | 6 +- export/xlsx.go | 50 ++++++++----- export_test.go => export1_test.go | 31 +++----- export2_test.go | 115 ++++++++++++++++++++++++++++++ export3_test.go | 61 ++++++++++++++++ export4_test.go | 80 +++++++++++++++++++++ test.xlsx | Bin 6621 -> 6562 bytes test2.xlsx | Bin 0 -> 9414 bytes test3.xlsx | Bin 0 -> 6370 bytes test4.xlsx | Bin 0 -> 6502 bytes 13 files changed, 388 insertions(+), 47 deletions(-) rename export_test.go => export1_test.go (89%) create mode 100644 export2_test.go create mode 100644 export3_test.go create mode 100644 export4_test.go create mode 100755 test2.xlsx create mode 100755 test3.xlsx create mode 100755 test4.xlsx diff --git a/README.md b/README.md index 8bc211c..9d3b883 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ # xlsx -excel的导出导入(目前仅完成导出) \ No newline at end of file +excel的导出导入(目前仅完成导出) + +## 导出功能 +如果要使用导出,则传入的数据必须为指针,类型可以是struct或者元素为struct的slice。 + +通过tag来确认需要导出的字段,内容为`export:”x:1,y:1”`,注意下x,y分别表是该字段在excel表格中的起始位置x为col,y为row,且tag中的x在数据中需要顺序列出。 + +详情请看测试文件 \ No newline at end of file diff --git a/export/cell.go b/export/cell.go index 41c2789..f90ce54 100644 --- a/export/cell.go +++ b/export/cell.go @@ -10,27 +10,61 @@ type Cell struct { Value any // 标题位置(列) Location Location - // 标题合并列数(除开本身) + // 标题合并列数 Colspan int - // 标题合并行数(除开本身) + // 标题合并行数 Rowspan int Style *excelize.Style } +type CellLocation struct { + LeftX int + RightX int + TopY int + BottomY int + IsMerge bool +} + func (e *Exporter) SetCell(sheet string, cell Cell) { start_col, end_col := e.CaculateCell(cell.Location, cell.Rowspan, cell.Colspan) - e.xlsx.MergeCell(sheet, start_col, end_col) + fmt.Println(sheet, start_col, end_col, cell.Value) + if start_col != end_col { + e.xlsx.MergeCell(sheet, start_col, end_col) + } + leftx, topy, _ := excelize.CellNameToCoordinates(start_col) + rightx, bottomy, _ := excelize.CellNameToCoordinates(end_col) e.xlsx.SetCellValue(sheet, start_col, cell.Value) + CellLocation := CellLocation{ + LeftX: leftx, + RightX: rightx, + TopY: topy, + BottomY: bottomy, + IsMerge: start_col != end_col, + } + e.preLocation = &CellLocation if cell.Style != nil { style, _ := e.xlsx.NewStyle(cell.Style) e.xlsx.SetCellStyle(sheet, start_col, end_col, style) + } else if e.GlobalCellStyle != nil { + style, _ := e.xlsx.NewStyle(e.GlobalCellStyle) + e.xlsx.SetCellStyle(sheet, start_col, end_col, style) } } func (e *Exporter) CaculateCell(location Location, rowSpan, colSpan int) (string, string) { + if rowSpan >= 1 { + rowSpan -= 1 + } else { + rowSpan = 0 + } + if colSpan >= 1 { + colSpan -= 1 + } else { + colSpan = 0 + } col_name, _ := excelize.ColumnNumberToName(location.X) start_col := fmt.Sprintf("%s%d", col_name, location.Y) - h_pos, _ := excelize.ColumnNumberToName(location.X + rowSpan) - end_col := fmt.Sprintf("%s%d", h_pos, location.Y+colSpan) + h_pos, _ := excelize.ColumnNumberToName(location.X + colSpan) + end_col := fmt.Sprintf("%s%d", h_pos, location.Y+rowSpan) return start_col, end_col } diff --git a/export/style.go b/export/style.go index 8eeb7c8..a284d9f 100644 --- a/export/style.go +++ b/export/style.go @@ -40,3 +40,42 @@ func DefaultTitleStyle() *excelize.Style { }, } } + +func DefaultCellStyle() *excelize.Style { + return &excelize.Style{ + Alignment: &excelize.Alignment{ + Horizontal: "center", + Vertical: "center", + }, + // Font: &excelize.Font{ + // Bold: true, + // }, + // Fill: excelize.Fill{ + // Type: "pattern", + // Color: []string{"4aa4ea"}, + // Pattern: 1, + // }, + Border: []excelize.Border{ + { + Type: "left", + Color: "000000", + Style: 4, + }, + { + Type: "top", + Color: "000000", + Style: 4, + }, + { + Type: "right", + Color: "000000", + Style: 4, + }, + { + Type: "bottom", + Color: "000000", + Style: 4, + }, + }, + } +} diff --git a/export/title.go b/export/title.go index dd7be12..0eac5d2 100644 --- a/export/title.go +++ b/export/title.go @@ -7,9 +7,9 @@ type Title struct { Name string // 标题位置(列) Location Location - // 标题合并列数(除开本身) + // 标题合并列数 Colspan int - // 标题合并行数(除开本身) + // 标题合并行数 Rowspan int Style *excelize.Style } @@ -28,6 +28,8 @@ func (e *Exporter) SetTitle(sheet string) { start_col, end_col := e.CaculateCell(title.Location, title.Rowspan, title.Colspan) e.xlsx.MergeCell(sheet, start_col, end_col) e.xlsx.SetCellValue(sheet, start_col, title.Name) + start_col_number, _, _ := excelize.SplitCellName(start_col) + e.xlsx.SetColWidth(sheet, start_col_number, start_col_number, 20) if title.Style != nil { style, _ := e.xlsx.NewStyle(title.Style) e.xlsx.SetCellStyle(sheet, start_col, end_col, style) diff --git a/export/xlsx.go b/export/xlsx.go index a73adae..134693e 100644 --- a/export/xlsx.go +++ b/export/xlsx.go @@ -17,6 +17,8 @@ type Exporter struct { Data interface{} xlsx *excelize.File GlobalTitleStyle *excelize.Style + GlobalCellStyle *excelize.Style + preLocation *CellLocation } func NewExporter() *Exporter { @@ -29,6 +31,7 @@ func DefaultExporter() *Exporter { return &Exporter{ xlsx: excelize.NewFile(), GlobalTitleStyle: DefaultTitleStyle(), + GlobalCellStyle: DefaultCellStyle(), Sheets: []string{"Sheet1"}, } } @@ -60,20 +63,24 @@ func (e *Exporter) Export(sheetIndex int) error { if v.Kind() != reflect.Pointer { return fmt.Errorf("data must be pointer") } - if v.Elem().Kind() != reflect.Slice { - return fmt.Errorf("data must be slice") - } - for i := 0; i < v.Elem().Len(); i++ { - value := v.Elem().Index(i) - if value.Kind() != reflect.Struct { - return fmt.Errorf("element must be struct") + switch v.Elem().Kind() { + case reflect.Slice: + for i := 0; i < v.Elem().Len(); i++ { + value := v.Elem().Index(i) + if value.Kind() != reflect.Struct { + return fmt.Errorf("element must be struct") + } + e.dealElement(sheet, value) } - e.dealElement(sheet, value, i) + case reflect.Struct: + e.dealElement(sheet, v.Elem()) + default: + return fmt.Errorf("data must be slice or struct") } - return nil + return e.Save() } -func (e *Exporter) dealElement(sheet string, data reflect.Value, index int) error { +func (e *Exporter) dealElement(sheet string, data reflect.Value) { for i := 0; i < data.NumField(); i++ { field := data.Field(i) t := data.Type().Field(i) @@ -82,37 +89,44 @@ func (e *Exporter) dealElement(sheet string, data reflect.Value, index int) erro case reflect.Struct: // 如果是结构体类型,但是没有export标签,则进行递归,否则直接处理(例如time.Time类型是结构体,但是可能需要导出) if !ok { - e.dealElement(sheet, field, index) + e.dealElement(sheet, field) } else { - e.writeCell(sheet, field, tag, index) + e.writeCell(sheet, field, tag) } // 该逻辑有待验证 case reflect.Slice: for j := 0; j < field.Len(); j++ { value := field.Index(j) if value.Kind() == reflect.Struct { - e.dealElement(sheet, value, index) + e.dealElement(sheet, value) } } default: if ok { - e.writeCell(sheet, field, tag, index) + e.writeCell(sheet, field, tag) } } } - return e.Save() } -func (e *Exporter) writeCell(sheet string, field reflect.Value, tag string, index int) { +func (e *Exporter) writeCell(sheet string, field reflect.Value, tag string) { tagMap := dealTag(tag) x, _ := strconv.Atoi(tagMap["x"]) y, _ := strconv.Atoi(tagMap["y"]) colSpan, _ := strconv.Atoi(tagMap["colspan"]) rowSpan, _ := strconv.Atoi(tagMap["rowspan"]) - location := Location{ + var location Location + if e.preLocation != nil { + if x > e.preLocation.RightX { + y = e.preLocation.TopY + } else if x <= e.preLocation.RightX { + y = e.preLocation.BottomY + 1 + } + } + location = Location{ X: x, - Y: y + index, + Y: y, } value := value(field) cell := Cell{ diff --git a/export_test.go b/export1_test.go similarity index 89% rename from export_test.go rename to export1_test.go index 57edb79..d0cf0fc 100644 --- a/export_test.go +++ b/export1_test.go @@ -49,16 +49,16 @@ func (t Date) MarshalJSON() ([]byte, error) { } type Data struct { - Date time.Time `export:"x:7,y:3"` Name string - TotalInvest Fen `export:"true,x:2,y:3"` ProjectName string `export:"true,x:1,y:3"` + TotalInvest Fen `export:"true,x:2,y:3"` + ExData2 ExData2 CenterInvest Fen CityInvest Fen CompanyInvest Fen - Partner string `export:"true,x:6,y:3"` + Partner string `export:"true,x:6,y:3"` + Date time.Time `export:"x:7,y:3"` ExData []ExData - ExData2 ExData2 } type ExData struct { @@ -72,55 +72,44 @@ type ExData2 struct { CompanyInvest Fen `export:"true,x:5,y:3"` } -func Test(t *testing.T) { +func TestMain(t *testing.T) { title := []export.Title{ { Name: "项目名称", Location: export.Location{X: 1, Y: 1}, - Colspan: 1, - Rowspan: 0, + Rowspan: 2, }, { Name: "总投资", Location: export.Location{X: 2, Y: 1}, - Colspan: 1, - Rowspan: 0, + Rowspan: 2, }, { Name: "资金来源", Location: export.Location{X: 3, Y: 1}, - Colspan: 0, - Rowspan: 2, + Colspan: 3, }, { Name: "中央", Location: export.Location{X: 3, Y: 2}, - Colspan: 0, - Rowspan: 0, }, { Name: "地方", Location: export.Location{X: 4, Y: 2}, - Colspan: 0, - Rowspan: 0, }, { Name: "公司", Location: export.Location{X: 5, Y: 2}, - Colspan: 0, - Rowspan: 0, }, { Name: "合作主体", Location: export.Location{X: 6, Y: 1}, - Colspan: 1, - Rowspan: 0, + Rowspan: 2, }, { Name: "日期", Location: export.Location{X: 7, Y: 1}, - Colspan: 1, - Rowspan: 0, + Rowspan: 2, }, } data := []Data{ diff --git a/export2_test.go b/export2_test.go new file mode 100644 index 0000000..329dfae --- /dev/null +++ b/export2_test.go @@ -0,0 +1,115 @@ +package xlsx + +import ( + "testing" + + "git.botann.com/lijun/xlsx/export" +) + +type Data2 struct { + Name string + ProjectName string `export:"true,x:1,y:2,rowspan:3"` + TotalInvest int `export:"true,x:2,y:2,rowspan:3"` + Partner string `export:"true,x:3,y:2,rowspan:3"` + Radio []InvestRadio +} + +type InvestRadio struct { + Name string `export:"true,x:4,y:2"` + Invest int `export:"true,x:5,y:2"` +} + +type ExDataEx struct { + Name string + Invest int +} + +func TestMain(T *testing.T) { + title := []export.Title{ + { + Name: "项目名称", + Location: export.Location{X: 1, Y: 1}, + }, + { + Name: "总投资", + Location: export.Location{X: 2, Y: 1}, + }, + { + Name: "合作主体", + Location: export.Location{X: 3, Y: 1}, + }, + { + Name: "出资比例", + Location: export.Location{X: 4, Y: 1}, + Colspan: 2, + }, + } + data := []Data2{ + { + Name: "项目1", + ProjectName: "项目1", + TotalInvest: 100, + Partner: "合作主体1", + Radio: []InvestRadio{ + { + Name: "1合作主体1", + Invest: 10, + }, + { + Name: "1合作主体2", + Invest: 20, + }, + { + Name: "1合作主体3", + Invest: 30, + }, + }, + }, + { + Name: "项目2", + ProjectName: "项目2", + TotalInvest: 200, + Partner: "合作主体2", + Radio: []InvestRadio{ + { + Name: "2合作主体1", + Invest: 10, + }, + { + Name: "2合作主体2", + Invest: 20, + }, + { + Name: "2合作主体3", + Invest: 30, + }, + }, + }, + { + Name: "项目3", + ProjectName: "项目3", + TotalInvest: 200, + Partner: "合作主体3", + Radio: []InvestRadio{ + { + Name: "3合作主体1", + Invest: 10, + }, + { + Name: "3合作主体2", + Invest: 20, + }, + { + Name: "3合作主体3", + Invest: 30, + }, + }, + }, + } + exporter := export.DefaultExporter() + exporter.Titles = title + exporter.Data = &data + exporter.File = "test2.xlsx" + exporter.Path = "./" + exporter.Export(0) +} diff --git a/export3_test.go b/export3_test.go new file mode 100644 index 0000000..6b6febd --- /dev/null +++ b/export3_test.go @@ -0,0 +1,61 @@ +package xlsx + +import ( + "fmt" + "testing" + "time" + + "github.com/xuri/excelize/v2" +) + +func TestMain(T *testing.T) { + f := excelize.NewFile() + defer func() { + if err := f.Close(); err != nil { + fmt.Println(err) + } + }() + index, err := f.NewSheet("Sheet1") + if err != nil { + fmt.Println(err) + return + } + f.SetActiveSheet(index) + f.SetCellValue("Sheet1", "A1", "项目名称") + f.SetCellValue("Sheet1", "B1", "总投资") + f.SetCellValue("Sheet1", "C1", "合作主体") + f.MergeCell("Sheet1", "D1", "E1") + f.SetCellValue("Sheet1", "D1", "出资比例") + f.SetCellValue("Sheet1", "F1", "日期") + + f.MergeCell("Sheet1", "F2", "F4") + f.SetCellValue("Sheet1", "F2", time.Now()) + f.MergeCell("Sheet1", "A2", "A4") + f.SetCellValue("Sheet1", "A2", "项目1") + f.MergeCell("Sheet1", "B2", "B4") + f.SetCellValue("Sheet1", "B2", 100) + f.MergeCell("Sheet1", "C2", "C4") + f.SetCellValue("Sheet1", "C2", "合作主体1") + f.SetCellValue("Sheet1", "D2", "1合作主体1") + f.SetCellValue("Sheet1", "E2", 10) + f.SetCellValue("Sheet1", "D3", "1合作主体2") + f.SetCellValue("Sheet1", "E3", 20) + f.SetCellValue("Sheet1", "D4", "1合作主体3") + f.SetCellValue("Sheet1", "E4", 30) + + f.MergeCell("Sheet1", "F5", "F7") + f.SetCellValue("Sheet1", "F5", time.Now()) + f.MergeCell("Sheet1", "A5", "A7") + f.SetCellValue("Sheet1", "A5", "项目2") + f.MergeCell("Sheet1", "B5", "B7") + f.SetCellValue("Sheet1", "B5", 200) + f.MergeCell("Sheet1", "C5", "C7") + f.SetCellValue("Sheet1", "C5", "合作主体2") + f.SetCellValue("Sheet1", "D3", "2合作主体1") + f.SetCellValue("Sheet1", "E3", 10) + f.SetCellValue("Sheet1", "D4", "2合作主体2") + f.SetCellValue("Sheet1", "E4", 20) + f.SetCellValue("Sheet1", "D5", "2合作主体3") + f.SetCellValue("Sheet1", "E5", 30) + f.SaveAs("./test3.xlsx") +} diff --git a/export4_test.go b/export4_test.go new file mode 100644 index 0000000..cab8a10 --- /dev/null +++ b/export4_test.go @@ -0,0 +1,80 @@ +package xlsx + +import ( + "testing" + + "git.botann.com/lijun/xlsx/export" +) + +type Data4 struct { + ProjectName string `export:"true,x:1,y:3"` + ProjectUnit string `export:"true,x:2,y:3"` + CentralInvest int `export:"true,x:3,y:3"` + LocalInvest int `export:"true,x:4,y:3"` + CompanyInvest int `export:"true,x:5,y:3"` +} + +type Total struct { + TotalCentralInvest int `export:"true,x:3,y:2"` + TotalLocalInvest int `export:"true,x:4,y:2"` + TotalCompanyInvest int `export:"true,x:5,y:2"` + Data []Data4 +} + +func TestMain(T *testing.T) { + title := []export.Title{ + { + Name: "项目名称", + Location: export.Location{X: 1, Y: 1}, + }, + { + Name: "项目单位", + Location: export.Location{X: 2, Y: 1}, + }, + { + Name: "中央投资", + Location: export.Location{X: 3, Y: 1}, + }, + { + Name: "地方投资", + Location: export.Location{X: 4, Y: 1}, + }, + { + Name: "公司投资", + Location: export.Location{X: 5, Y: 1}, + }, + { + Name: "合计", + Location: export.Location{X: 1, Y: 2}, + Colspan: 2, + }, + } + data := Total{ + TotalCentralInvest: 100, + TotalLocalInvest: 200, + TotalCompanyInvest: 300, + Data: []Data4{ + { + ProjectName: "项目1", + ProjectUnit: "单位1", + CentralInvest: 10, + LocalInvest: 20, + CompanyInvest: 30, + }, + { + ProjectName: "项目2", + ProjectUnit: "单位2", + CentralInvest: 40, + LocalInvest: 50, + CompanyInvest: 60, + }, + }, + } + exporter := export.DefaultExporter() + exporter.Titles = title + exporter.Data = &data + exporter.File = "test4.xlsx" + exporter.Path = "./" + exporter.Export(0) + +} diff --git a/test.xlsx b/test.xlsx index 72fae1c4636a477294cc2589344b2aea9ea8e2f7..7a2bab3b82b7d43d1f5bc3bc6fc6b054a34c88c7 100755 GIT binary patch delta 973 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 literal 0 HcmV?d00001 diff --git a/test3.xlsx b/test3.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..7d211bcb1c00e02425a38db78a8becc7e35f2863 GIT binary patch literal 6370 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 H;NbobpD@}T literal 0 HcmV?d00001 diff --git a/test4.xlsx b/test4.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..60793bcb9e7138c6a3c5b9be72259416a2ab9cfb GIT binary patch literal 6502 zcmaJ_1yodP*B(kz96BAk6;K*+=pH(hlpcC$>AG~MAfbSSlr#ejNGS{
naB0YqF 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