fix
parent
b52dfc1b1d
commit
5f6aec0aee
|
@ -1,3 +1,10 @@
|
||||||
# xlsx
|
# xlsx
|
||||||
|
|
||||||
excel的导出导入(目前仅完成导出)
|
excel的导出导入(目前仅完成导出)
|
||||||
|
|
||||||
|
## 导出功能
|
||||||
|
如果要使用导出,则传入的数据必须为指针,类型可以是struct或者元素为struct的slice。
|
||||||
|
|
||||||
|
通过tag来确认需要导出的字段,内容为`export:”x:1,y:1”`,注意下x,y分别表是该字段在excel表格中的起始位置x为col,y为row,且tag中的x在数据中需要顺序列出。
|
||||||
|
|
||||||
|
详情请看测试文件
|
|
@ -10,27 +10,61 @@ type Cell struct {
|
||||||
Value any
|
Value any
|
||||||
// 标题位置(列)
|
// 标题位置(列)
|
||||||
Location Location
|
Location Location
|
||||||
// 标题合并列数(除开本身)
|
// 标题合并列数
|
||||||
Colspan int
|
Colspan int
|
||||||
// 标题合并行数(除开本身)
|
// 标题合并行数
|
||||||
Rowspan int
|
Rowspan int
|
||||||
Style *excelize.Style
|
Style *excelize.Style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CellLocation struct {
|
||||||
|
LeftX int
|
||||||
|
RightX int
|
||||||
|
TopY int
|
||||||
|
BottomY int
|
||||||
|
IsMerge bool
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Exporter) SetCell(sheet string, cell Cell) {
|
func (e *Exporter) SetCell(sheet string, cell Cell) {
|
||||||
start_col, end_col := e.CaculateCell(cell.Location, cell.Rowspan, cell.Colspan)
|
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)
|
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 {
|
if cell.Style != nil {
|
||||||
style, _ := e.xlsx.NewStyle(cell.Style)
|
style, _ := e.xlsx.NewStyle(cell.Style)
|
||||||
e.xlsx.SetCellStyle(sheet, start_col, end_col, 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) {
|
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)
|
col_name, _ := excelize.ColumnNumberToName(location.X)
|
||||||
start_col := fmt.Sprintf("%s%d", col_name, location.Y)
|
start_col := fmt.Sprintf("%s%d", col_name, location.Y)
|
||||||
h_pos, _ := excelize.ColumnNumberToName(location.X + rowSpan)
|
h_pos, _ := excelize.ColumnNumberToName(location.X + colSpan)
|
||||||
end_col := fmt.Sprintf("%s%d", h_pos, location.Y+colSpan)
|
end_col := fmt.Sprintf("%s%d", h_pos, location.Y+rowSpan)
|
||||||
return start_col, end_col
|
return start_col, end_col
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@ type Title struct {
|
||||||
Name string
|
Name string
|
||||||
// 标题位置(列)
|
// 标题位置(列)
|
||||||
Location Location
|
Location Location
|
||||||
// 标题合并列数(除开本身)
|
// 标题合并列数
|
||||||
Colspan int
|
Colspan int
|
||||||
// 标题合并行数(除开本身)
|
// 标题合并行数
|
||||||
Rowspan int
|
Rowspan int
|
||||||
Style *excelize.Style
|
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)
|
start_col, end_col := e.CaculateCell(title.Location, title.Rowspan, title.Colspan)
|
||||||
e.xlsx.MergeCell(sheet, start_col, end_col)
|
e.xlsx.MergeCell(sheet, start_col, end_col)
|
||||||
e.xlsx.SetCellValue(sheet, start_col, title.Name)
|
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 {
|
if title.Style != nil {
|
||||||
style, _ := e.xlsx.NewStyle(title.Style)
|
style, _ := e.xlsx.NewStyle(title.Style)
|
||||||
e.xlsx.SetCellStyle(sheet, start_col, end_col, style)
|
e.xlsx.SetCellStyle(sheet, start_col, end_col, style)
|
||||||
|
|
|
@ -17,6 +17,8 @@ type Exporter struct {
|
||||||
Data interface{}
|
Data interface{}
|
||||||
xlsx *excelize.File
|
xlsx *excelize.File
|
||||||
GlobalTitleStyle *excelize.Style
|
GlobalTitleStyle *excelize.Style
|
||||||
|
GlobalCellStyle *excelize.Style
|
||||||
|
preLocation *CellLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExporter() *Exporter {
|
func NewExporter() *Exporter {
|
||||||
|
@ -29,6 +31,7 @@ func DefaultExporter() *Exporter {
|
||||||
return &Exporter{
|
return &Exporter{
|
||||||
xlsx: excelize.NewFile(),
|
xlsx: excelize.NewFile(),
|
||||||
GlobalTitleStyle: DefaultTitleStyle(),
|
GlobalTitleStyle: DefaultTitleStyle(),
|
||||||
|
GlobalCellStyle: DefaultCellStyle(),
|
||||||
Sheets: []string{"Sheet1"},
|
Sheets: []string{"Sheet1"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,20 +63,24 @@ func (e *Exporter) Export(sheetIndex int) error {
|
||||||
if v.Kind() != reflect.Pointer {
|
if v.Kind() != reflect.Pointer {
|
||||||
return fmt.Errorf("data must be pointer")
|
return fmt.Errorf("data must be pointer")
|
||||||
}
|
}
|
||||||
if v.Elem().Kind() != reflect.Slice {
|
switch v.Elem().Kind() {
|
||||||
return fmt.Errorf("data must be slice")
|
case reflect.Slice:
|
||||||
}
|
for i := 0; i < v.Elem().Len(); i++ {
|
||||||
for i := 0; i < v.Elem().Len(); i++ {
|
value := v.Elem().Index(i)
|
||||||
value := v.Elem().Index(i)
|
if value.Kind() != reflect.Struct {
|
||||||
if value.Kind() != reflect.Struct {
|
return fmt.Errorf("element must be 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++ {
|
for i := 0; i < data.NumField(); i++ {
|
||||||
field := data.Field(i)
|
field := data.Field(i)
|
||||||
t := data.Type().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:
|
case reflect.Struct:
|
||||||
// 如果是结构体类型,但是没有export标签,则进行递归,否则直接处理(例如time.Time类型是结构体,但是可能需要导出)
|
// 如果是结构体类型,但是没有export标签,则进行递归,否则直接处理(例如time.Time类型是结构体,但是可能需要导出)
|
||||||
if !ok {
|
if !ok {
|
||||||
e.dealElement(sheet, field, index)
|
e.dealElement(sheet, field)
|
||||||
} else {
|
} else {
|
||||||
e.writeCell(sheet, field, tag, index)
|
e.writeCell(sheet, field, tag)
|
||||||
}
|
}
|
||||||
// 该逻辑有待验证
|
// 该逻辑有待验证
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
for j := 0; j < field.Len(); j++ {
|
for j := 0; j < field.Len(); j++ {
|
||||||
value := field.Index(j)
|
value := field.Index(j)
|
||||||
if value.Kind() == reflect.Struct {
|
if value.Kind() == reflect.Struct {
|
||||||
e.dealElement(sheet, value, index)
|
e.dealElement(sheet, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if ok {
|
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)
|
tagMap := dealTag(tag)
|
||||||
x, _ := strconv.Atoi(tagMap["x"])
|
x, _ := strconv.Atoi(tagMap["x"])
|
||||||
y, _ := strconv.Atoi(tagMap["y"])
|
y, _ := strconv.Atoi(tagMap["y"])
|
||||||
colSpan, _ := strconv.Atoi(tagMap["colspan"])
|
colSpan, _ := strconv.Atoi(tagMap["colspan"])
|
||||||
rowSpan, _ := strconv.Atoi(tagMap["rowspan"])
|
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,
|
X: x,
|
||||||
Y: y + index,
|
Y: y,
|
||||||
}
|
}
|
||||||
value := value(field)
|
value := value(field)
|
||||||
cell := Cell{
|
cell := Cell{
|
||||||
|
|
|
@ -49,16 +49,16 @@ func (t Date) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Data struct {
|
type Data struct {
|
||||||
Date time.Time `export:"x:7,y:3"`
|
|
||||||
Name string
|
Name string
|
||||||
TotalInvest Fen `export:"true,x:2,y:3"`
|
|
||||||
ProjectName string `export:"true,x:1,y:3"`
|
ProjectName string `export:"true,x:1,y:3"`
|
||||||
|
TotalInvest Fen `export:"true,x:2,y:3"`
|
||||||
|
ExData2 ExData2
|
||||||
CenterInvest Fen
|
CenterInvest Fen
|
||||||
CityInvest Fen
|
CityInvest Fen
|
||||||
CompanyInvest 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
|
ExData []ExData
|
||||||
ExData2 ExData2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExData struct {
|
type ExData struct {
|
||||||
|
@ -72,55 +72,44 @@ type ExData2 struct {
|
||||||
CompanyInvest Fen `export:"true,x:5,y:3"`
|
CompanyInvest Fen `export:"true,x:5,y:3"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func TestMain(t *testing.T) {
|
||||||
title := []export.Title{
|
title := []export.Title{
|
||||||
{
|
{
|
||||||
Name: "项目名称",
|
Name: "项目名称",
|
||||||
Location: export.Location{X: 1, Y: 1},
|
Location: export.Location{X: 1, Y: 1},
|
||||||
Colspan: 1,
|
Rowspan: 2,
|
||||||
Rowspan: 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "总投资",
|
Name: "总投资",
|
||||||
Location: export.Location{X: 2, Y: 1},
|
Location: export.Location{X: 2, Y: 1},
|
||||||
Colspan: 1,
|
Rowspan: 2,
|
||||||
Rowspan: 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "资金来源",
|
Name: "资金来源",
|
||||||
Location: export.Location{X: 3, Y: 1},
|
Location: export.Location{X: 3, Y: 1},
|
||||||
Colspan: 0,
|
Colspan: 3,
|
||||||
Rowspan: 2,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "中央",
|
Name: "中央",
|
||||||
Location: export.Location{X: 3, Y: 2},
|
Location: export.Location{X: 3, Y: 2},
|
||||||
Colspan: 0,
|
|
||||||
Rowspan: 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "地方",
|
Name: "地方",
|
||||||
Location: export.Location{X: 4, Y: 2},
|
Location: export.Location{X: 4, Y: 2},
|
||||||
Colspan: 0,
|
|
||||||
Rowspan: 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "公司",
|
Name: "公司",
|
||||||
Location: export.Location{X: 5, Y: 2},
|
Location: export.Location{X: 5, Y: 2},
|
||||||
Colspan: 0,
|
|
||||||
Rowspan: 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "合作主体",
|
Name: "合作主体",
|
||||||
Location: export.Location{X: 6, Y: 1},
|
Location: export.Location{X: 6, Y: 1},
|
||||||
Colspan: 1,
|
Rowspan: 2,
|
||||||
Rowspan: 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "日期",
|
Name: "日期",
|
||||||
Location: export.Location{X: 7, Y: 1},
|
Location: export.Location{X: 7, Y: 1},
|
||||||
Colspan: 1,
|
Rowspan: 2,
|
||||||
Rowspan: 0,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
data := []Data{
|
data := []Data{
|
|
@ -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)
|
||||||
|
}
|
|
@ -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")
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue