diff --git a/export/cell.go b/export/cell.go index a85d494..99968f0 100644 --- a/export/cell.go +++ b/export/cell.go @@ -40,6 +40,7 @@ func (e *Exporter) SetCell(sheet string, cell Cell) { BottomY: bottomy, IsMerge: start_col != end_col, } + // 记录当前单元格位置 e.preLocation = &CellLocation if cell.Style != nil { style, _ := e.xlsx.NewStyle(cell.Style) diff --git a/export/title.go b/export/title.go index 0eac5d2..41bdc07 100644 --- a/export/title.go +++ b/export/title.go @@ -23,20 +23,24 @@ func (e *Exporter) SetGlobalTitleStyle(style *excelize.Style) { e.GlobalTitleStyle = style } -func (e *Exporter) SetTitle(sheet string) { - for _, title := range e.Titles { - 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) - } else if e.GlobalTitleStyle != nil { - style, _ := e.xlsx.NewStyle(e.GlobalTitleStyle) - e.xlsx.SetCellStyle(sheet, start_col, end_col, style) +func (e *Exporter) WriteTitle(sheet string, title Title) { + 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) + } else if e.GlobalTitleStyle != nil { + style, _ := e.xlsx.NewStyle(e.GlobalTitleStyle) + e.xlsx.SetCellStyle(sheet, start_col, end_col, style) - } + } +} + +func (e *Exporter) SetTitle(sheet string) { + for _, title := range e.Titles { + e.WriteTitle(sheet, title) } } diff --git a/export/xlsx.go b/export/xlsx.go index fa29b9c..4fd0730 100644 --- a/export/xlsx.go +++ b/export/xlsx.go @@ -54,11 +54,10 @@ func (e *Exporter) Export(sheetIndex int) error { if err != nil { return err } - if len(e.Titles) == 0 { - return fmt.Errorf("excel title is null") - } sheet := e.Sheets[sheetIndex] - e.SetTitle(sheet) + if len(e.Titles) > 0 { + e.SetTitle(sheet) + } v := reflect.ValueOf(e.Data) if v.Kind() != reflect.Pointer { return fmt.Errorf("data must be pointer") @@ -117,8 +116,19 @@ func (e *Exporter) writeCell(sheet string, field reflect.Value, tag string) { colSpan, _ := strconv.Atoi(tagMap["colspan"]) rowSpan, _ := strconv.Atoi(tagMap["rowspan"]) loop := tagMap["loop"] + title := tagMap["title"] + if title != "" { + t := Title{ + Name: title, + Location: Location{X: x, Y: 1}, + Colspan: colSpan, + Rowspan: rowSpan, + } + e.WriteTitle(sheet, t) + } var location Location if e.preLocation != nil { + // loop不为空,则表示该结构体需要循环输出,x坐标需要重新计算(即x坐标需要在上一个结构体的右边,主要用于导出字段数量不确定,用sliece类型的结构体存储) if loop != "" { y = e.preLocation.BottomY if x <= e.preLocation.RightX { @@ -127,7 +137,7 @@ func (e *Exporter) writeCell(sheet string, field reflect.Value, tag string) { } else { if x > e.preLocation.RightX { y = e.preLocation.TopY - } else if x <= e.preLocation.RightX { + } else if x <= e.preLocation.RightX { // 如果x坐标小于等于上一个单元格的x坐标,则表示需要换行,此时y坐标需要在上一个单元格的下面 y = e.preLocation.BottomY + 1 } } @@ -153,10 +163,8 @@ func value(field reflect.Value) (val string) { } if mthV.IsValid() && mthV.Kind() == reflect.Func && mthV.Type().NumIn() == 0 { callV := mthV.Call(nil) - if len(callV) > 0 { val = fmt.Sprintf("%s", callV[0].String()) - return } } diff --git a/export1_test.go b/export1_test.go index d0cf0fc..b82f9da 100644 --- a/export1_test.go +++ b/export1_test.go @@ -147,7 +147,7 @@ func TestMain(t *testing.T) { exporter := export.DefaultExporter() exporter.Data = &data exporter.Titles = title - exporter.File = "test.xlsx" + exporter.File = "test1.xlsx" exporter.Path = "./" exporter.Export(0) } diff --git a/export6_test.go b/export6_test.go new file mode 100644 index 0000000..861ea3d --- /dev/null +++ b/export6_test.go @@ -0,0 +1,44 @@ +package xlsx + +import ( + "fmt" + "testing" + + "git.botann.com/lijun/xlsx/export" +) + +type Data struct { + Name string `export:"true,x:1,y:1,title:项目名称"` + TotalInvest int64 `export:"true,x:2,y:1,title:总投资(万元)"` + Unit string `export:"true,x:3,y:1,title:单位"` + Remark string `export:"true,x:4,y:1,title:备注"` +} + +func TestMain(t *testing.T) { + data := []Data{ + { + Name: "项目1", + TotalInvest: 100, + Unit: "单位1", + Remark: "备注1", + }, + { + Name: "项目2", + TotalInvest: 200, + Unit: "单位2", + Remark: "备注2", + }, + { + Name: "项目3", + TotalInvest: 300, + Unit: "单位3", + Remark: "备注3", + }, + } + exporter := export.DefaultExporter() + exporter.Data = &data + exporter.File = "test6.xlsx" + exporter.Path = "./" + err := exporter.Export(0) + fmt.Println(err) +} diff --git a/test.xlsx b/test.xlsx deleted file mode 100755 index 7a2bab3..0000000 Binary files a/test.xlsx and /dev/null differ diff --git a/test1.xlsx b/test1.xlsx new file mode 100755 index 0000000..0dbb8b0 Binary files /dev/null and b/test1.xlsx differ diff --git a/test6.xlsx b/test6.xlsx new file mode 100755 index 0000000..43d945e Binary files /dev/null and b/test6.xlsx differ