7、excelize

在 Go 中操作 Excel 文件,最常用的库是 excelize,它支持读取、写入和修改 Excel 文件。

官网:https://xuri.me/excelize/zh-hans/

安装

go get github.com/xuri/excelize/v2

读写操作

创建并写入 Excel

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	file := excelize.NewFile()
	sheet := "Sheet1"
	file.SetCellValue(sheet, "A1", "A1Value")
	file.SetCellValue(sheet, "B1", "B1Value")
	file.SetCellValue(sheet, "C1", "C1Value")
	file.SetCellValue(sheet, "D1", "D1Value")
	if err := file.SaveAs("test.xlsx"); err != nil {
		fmt.Println(err)
	}
}

读取 Excel

excelize提供了两个函数获取文件File对象

func OpenFile(filename string, opt ...Options) (*File, error)
func OpenReader(r io.Reader, opt ...Options) (*File, error)

方式一

func (f *File) GetRows(sheet string, opts ...Options) ([][]string, error)

直接读取Row和Col的数据二维切片,然后进行读取操作

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	file, err := excelize.OpenFile("test.xlsx")
	defer file.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	rows, err := file.GetRows("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}
	for i, row := range rows {
		fmt.Printf("Row %d is %v", i, row)
	}
}

方式二

使用Rows函数,返回Rows的对象进行操作, 函数原型如下:

func (f *File) Rows(sheet string) (*Rows, error)

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	file, err := excelize.OpenFile("test.xlsx")
	defer file.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	rows, err := file.Rows("Sheet1")
	for rows.Next() {
		columns, _ := rows.Columns()
		fmt.Println(columns)
	}
}

更新单元格的值

在一个现有 Excel 文件中更新某个单元格值:

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	file, err := excelize.OpenFile("test.xlsx")
	defer file.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	if err = file.SetCellValue("Sheet1", "B1", "B1UpdateValue"); err != nil {
		fmt.Println(err)
	}
	file.Save()
}

读取单元格的值

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	file, err := excelize.OpenFile("test.xlsx")
	defer file.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	value, err := file.GetCellValue("Sheet1", "A1")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("Sheet1 A1 value is %s", value)
}

合并单元格

func (f *File) MergeCell(sheet, topLeftCell, bottomRightCell string) error

工作表

// 根据sheet的名称获取sheet的索引
func (f *File) GetSheetIndex(name string) int
// 根据sheet的索引获取sheet的名称
func (f *File) GetSheetName(index int) (name string)
// 获取所有sheet的名称列表
func (f *File) GetSheetList() (list []string)
// 获取所有sheet的索引对应的名称集合
func (f *File) GetSheetMap() map[int]string

添加新的工作表

如果你想在现有 Excel 文件中添加一个新的工作表,可以使用 NewSheet 方法:

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	file, err := excelize.OpenFile("test.xlsx")
	defer file.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	// 创建新的工作表
	sheet, err := file.NewSheet("Sheet2")
	// 写入数据到新工作表
	file.SetCellValue("Sheet2", "A1", "Sheet2A1Value")
	// 设置 "Sheet2" 为默认工作表,可选
	file.SetActiveSheet(sheet)
	file.Save()
}

删除工作表

func (f *File) DeleteSheet(sheet string) error

样式设置

创建样式

func (f *File) NewStyle(style *Style) (int, error)

Style 结构体

type Style struct {
	Border        []Border
	Fill          Fill
	Font          *Font
	Alignment     *Alignment
	Protection    *Protection
	NumFmt        int
	DecimalPlaces *int
	CustomNumFmt  *string
	NegRed        bool
}

Boder 结构体

type Border struct {
   Type  string
   Color string
   Style int
}

Sytle可选值参考:https://xuri.me/excelize/zh-hans/style.html#border

diagonalDowndiagonalUp同时设置,如果二者样式不同,则diagonalDown会被diagonalUp的样式覆盖。

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	f := excelize.NewFile()

	styleId, err := f.NewStyle(&excelize.Style{
		Border: []excelize.Border{
			{Type: "left", Color: "000000", Style: 1},
			{Type: "top", Color: "000000", Style: 2},
			{Type: "bottom", Color: "000000", Style: 3},
			{Type: "right", Color: "000000", Style: 4},
			{Type: "diagonalDown", Color: "000000", Style: 5},
			{Type: "diagonalUp", Color: "A020F0", Style: 6},
		},
	})
	if err != nil {
		fmt.Println(err)
	}
	err = f.SetCellStyle("Sheet1", "B4", "D2", styleId)
	if err = f.SaveAs("test.xlsx"); err != nil {
		fmt.Println(err)
	}
}

Fill 结构体

type Fill struct {
	Type    string
	Pattern int
	Color   []string
	Shading int
}

Pattern 可选值参考:https://xuri.me/excelize/zh-hans/style.html#shading

渐变填充

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	f := excelize.NewFile()

	styleId, err := f.NewStyle(&excelize.Style{
		Border: []excelize.Border{
			{Type: "left", Color: "000000", Style: 2},
			{Type: "top", Color: "000000", Style: 2},
			{Type: "bottom", Color: "000000", Style: 2},
			{Type: "right", Color: "000000", Style: 2},
		},
		Fill:  excelize.Fill{
			Type: "gradient",
			Color: []string{"FFFF00", "00FF00"},
			Shading: 1,
		},

	})
	if err != nil {
		fmt.Println(err)
	}
	err = f.SetCellStyle("Sheet1", "B4", "D2", styleId)
	if err = f.SaveAs("test.xlsx"); err != nil {
		fmt.Println(err)
	}
}

纯色填充

style, err := f.NewStyle(&excelize.Style{
    Fill: excelize.Fill{Type: "pattern", Color: []string{"FF0000"}, Pattern: 1},
})

Font 结构体

type Font struct {
	Bold         bool
	Italic       bool
	Underline    string
	Family       string
	Size         float64
	Strike       bool
	Color        string
	ColorIndexed int
	ColorTheme   *int
	ColorTint    float64
	VertAlign    string
}
package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	f := excelize.NewFile()

	styleId, err := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Bold:   true,
			Italic: true,
			Family: "Times New Roman",
			Size:   36,
			Color:  "微软雅黑",
		},

	})
	if err != nil {
		fmt.Println(err)
	}
	f.SetCellStyle("Sheet1", "B4", "B4", styleId)
	f.SetCellValue("Sheet1","B4","LiuBei")
	if err = f.SaveAs("test.xlsx"); err != nil {
		fmt.Println(err)
	}
}

Alignment 结构体

type Alignment struct {
	Horizontal      string
	Indent          int
	JustifyLastLine bool
	ReadingOrder    uint64
	RelativeIndent  int
	ShrinkToFit     bool
	TextRotation    int
	Vertical        string
	WrapText        bool
}
package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {
	f := excelize.NewFile()

	styleId, err := f.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{
			Horizontal:      "center",
			Indent:          1,
			JustifyLastLine: true,
			ReadingOrder:    2,
			RelativeIndent:  1,
			ShrinkToFit:     true,
			TextRotation:    30,
			Vertical:        "top",
			WrapText:        true,
		},

	})
	if err != nil {
		fmt.Println(err)
	}
	f.SetCellStyle("Sheet1", "B4", "B4", styleId)
	f.SetCellValue("Sheet1","B4","LiuBei")
	if err = f.SaveAs("test.xlsx"); err != nil {
		fmt.Println(err)
	}
}

CustomNumFmt自定义格式

import (
    "fmt"
    "github.com/xuri/excelize/v2"
		"time"
)

func main() {
	f := excelize.NewFile()
	numFmt := "yyyy\"年\"m\"月\"d\"日\""
	styleId, err := f.NewStyle(&excelize.Style{
		CustomNumFmt: &numFmt,

	})
	if err != nil {
		fmt.Println(err)
	}
	f.SetCellStyle("Sheet1", "B4", "B4", styleId)
	f.SetCellValue("Sheet1","B4",time.Now())
	if err = f.SaveAs("test.xlsx"); err != nil {
		fmt.Println(err)
	}
}

单元格使用样式

func (f *File) SetCellStyle(sheet string, hCell string, vCell string, styleID int) error

列使用样式

func (f *File) SetColStyle(sheet, columns string, styleID int) error

行使用样式

func (f *File) SetRowStyle(sheet string, start int, end int, styleID int) error