在 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
}
- Type:边线方向
- left 左边
- right 正确的
- top 顶端
- bottom 底部
- diagonalDown:左上到右下
- diagonalUP:左下到右上
- Color:颜色
- Style:边线类型
Sytle可选值参考:https://xuri.me/excelize/zh-hans/style.html#border
diagonalDown和diagonalUp同时设置,如果二者样式不同,则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
}
- Type
gradient:渐变pattern:填充图
- Shading(Type为
gradient时生效)- 1:横向填充
- 2:纵向填充
- 3:对角线向下填充
- 4:对角线向上填充
- 5:从内向外填充
- Pattern(Type为
pattern时生效)- 值从1~18。
- 1 表示纯色填充
- Color
- Type为
gradient时,Color 有两个值,Pattern不生效 - 切片只有一个成员时,Shading 不生效。
- Type为
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
}
Bold:是否粗体Italic:是否斜体Underline:下划线single:单线double:双线
Family:字体样式Size:字体大小Color:字体颜色
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
}
Horizontal:水平对齐right正确的left左边center中心
Indent:缩进JustifyLastLine:两端对齐ReadingOrder:文字方向RelativeIndent:相对缩进ShrinkToFit:缩小字体TextRotation:文字旋转Vertical:垂直对齐top顶端bottom底部center中心
WrapText:自动换行
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