Skip to content

《Learning Go 第二版》入门实战系列 19:Go语言Excel全能王——从快速入门到高级图表与数据验证

约 4171 字大约 14 分钟

《Learning Go 第二版》系列Go语言

2026-04-02

在数据驱动和报表生成无处不在的今天,以编程方式高效、精准地操作 Excel 文件已成为后端开发的刚需。Excelize 作为 Go 语言生态中最强大、最流行的 Excel 文档基础库,完美解决了这一痛点。它严格遵循国际标准,支持包括图表、图片、数据验证、复杂样式在内的完整 Excel 功能,并提供了流式 API 以处理海量数据。无论您是需要生成复杂的业务报表、进行数据导入导出,还是构建云端文档处理服务,掌握 Excelize 都将使您游刃有余。本篇将带您从零开始,全面掌握 Excelize 的核心用法与高级特性。

【本篇核心收获】

  • 掌握 Excelize 的核心概念与快速入门,包括版本兼容性、安装、以及创建/读取 Excel 文件的基础操作。
  • 精通工作簿、工作表、单元格的全面管理,包括增删改查、样式设置、合并、公式以及行列的精细控制。
  • 深入理解并应用 Excelize 强大的样式系统,能够创建并设置包括边框、填充、字体、对齐在内的复杂单元格格式,并运用条件格式实现动态视觉效果。
  • 掌握在 Excel 中创建丰富可视化内容的能力,包括插入各类图表(柱形图、饼图、折线图等)、迷你图(Sparkline)以及本地与网络图片。
  • 学会使用数据验证与筛选功能保障数据质量,能够为单元格设置输入限制、创建下拉列表,并实现数据自动筛选与表格化。

1. 快速开始

Excelize 是一个用 Go 语言编写的,用于操作 Office Excel 文档的基础库。它基于 ECMA-376、ISO/IEC 29500 国际标准,支持读取和写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。其支持 XLAM/XLSM/XLSX/XLTM/XLTX 等多种文档格式,高度兼容带有样式、图片(表)、透视表、切片器等复杂组件的文档,并提供流式读写 API,用于处理包含大规模数据的工作簿。可应用于各类报表平台、云计算、边缘计算等系统。

摘自Excelize官方文档

核心资源

1.1 安装与更新

各版本 Excelize 基础库所需要的最低 Go 语言版本兼容性如下:

表 1: Excelize 与 Go 语言版本兼容性对照表

Excelize 版本对 Go 语言版本的最低要求
v2.9.1 ~ master1.23.0
v2.8.1 ~ v2.9.01.18
v2.7.0 ~ v2.8.01.16
v2.4.0 ~ v2.6.11.15
v2.0.2 ~ v2.3.21.10
v1.0.0 ~ v2.0.11.6

如果使用 Go Modules 管理依赖,可以执行以下命令进行安装和更新:

# 安装最新版
go get github.com/xuri/excelize/v2

# 更新到最新稳定版
go get -u github.com/xuri/excelize/v2

# 更新到最新开发分支代码
go get -u github.com/xuri/excelize/v2@master

1.2 读写Excel文档

1.2.1 创建Excel文档

以下示例展示了如何创建一个新的 Excel 工作簿、添加工作表并写入数据。

package main

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

func main() {
    // 1. 创建一个新的工作簿
    f := excelize.NewFile()
    // 确保工作簿在关闭时释放资源
    defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()
    
    // 2. 创建一个名为“Sheet2”的新工作表
    index, err := f.NewSheet("Sheet2")
    if err != nil {
        fmt.Println(err)
        return
    }
    
    // 3. 定义要写入的数据
    data := [][]interface{}{
        {nil, "Apple", "Orange", "Pear"},
        {"Small", 2, 3, 3},
        {"Normal", 5, 2, 4},
        {"Large", 6, 7, 8},
    }
    
    // 4. 遍历数据,写入单元格
    for rowIdx, row := range data {
        for colIdx, cellValue := range row {
            // 将行列索引转换为单元格地址(如 (1,1) -> “A1“)
            cellName, err := excelize.CoordinatesToCellName(colIdx+1, rowIdx+1)
            if err != nil {
                fmt.Printf("生成单元格名称失败:%v\n", err)
                return
            }
            // 设置单元格的值
            if err := f.SetCellValue("Sheet2", cellName, cellValue); err != nil {
                fmt.Printf("设置单元格值失败:%v", err)
                return
            }
        }
    }
    
    // 5. 将“Sheet2”设置为默认激活的工作表
    f.SetActiveSheet(index)
    // 6. 保存文件
    if err := f.SaveAs("Book1.xlsx"); err != nil {
        fmt.Println(err)
    }
}

执行上述代码后,将生成一个 Book1.xlsx 文件,其“Sheet2”工作表内容如图1所示。

!https://cdn.nlark.com/yuque/0/2026/png/2447732/1768550652896-f0161fd5-0ecb-4955-b424-095f93898b24.png

1.2.2 读取Excel文档

以下示例展示了如何打开一个已存在的 Excel 文件并读取其中的数据。

package main

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

func main() {
    // 1. 打开文件
    f, err := excelize.OpenFile("Book1.xlsx")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()

    // 2. 检查目标工作表是否存在
    sheetName := "Sheet2"
    index, _ := f.GetSheetIndex(sheetName)
    if index == -1 {
        fmt.Printf("工作表%s不存在\n", sheetName)
        return
    }

    // 3. 获取工作表中的所有行数据
    rows, err := f.GetRows(sheetName)
    if err != nil {
        fmt.Printf("读取工作表数据失败:%v\n", err)
        return
    }

    // 4. 遍历并打印数据
    fmt.Println("读取到的数据:")
    for _, row := range rows {
        for _, col := range row {
            fmt.Printf("%s\t", col)
        }
        fmt.Println()
    }
}

运行此程序,将输出之前创建的文件内容。

1.2.3 插入图表

Excelize 支持创建丰富的图表。以下示例先写入数据,然后基于数据创建一个三维簇状柱形图。

package main

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

func main() {
    f := excelize.NewFile()
    defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()
    
    // 1. 向“Sheet1”写入数据
    for idx, row := range [][]interface{}{
        {nil, "Apple", "Orange", "Pear"},
        {"Small", 2, 3, 3},
        {"Normal", 5, 2, 4},
        {"Large", 6, 7, 8},
    } {
        cell, err := excelize.CoordinatesToCellName(1, idx+1)
        if err != nil {
            fmt.Println(err)
            return
        }
        f.SetSheetRow("Sheet1", cell, &row)
    }
    
    // 2. 在E1单元格位置添加一个三维簇状柱形图
    if err := f.AddChart("Sheet1", "E1", &excelize.Chart{
        Type: excelize.Col3DClustered,
        Series: []excelize.ChartSeries{
            {Name: "Sheet1!$A$2", Categories: "Sheet1!$B$1:$D$1", Values: "Sheet1!$B$2:$D$2"},
            {Name: "Sheet1!$A$3", Categories: "Sheet1!$B$1:$D$1", Values: "Sheet1!$B$3:$D$3"},
            {Name: "Sheet1!$A$4", Categories: "Sheet1!$B$1:$D$1", Values: "Sheet1!$B$4:$D$4"},
        },
        Title: []excelize.RichTextRun{{Text: "Fruit 3D Clustered Column Chart"}},
    }); err != nil {
        fmt.Println(err)
        return
    }
    
    // 3. 保存文件
    if err := f.SaveAs("Book1.xlsx"); err != nil {
        fmt.Println(err)
    }
}

生成的 Excel 文件将包含一个图表,效果如图2所示。

!https://cdn.nlark.com/yuque/0/2026/png/2447732/1768550664513-f9486e0d-5682-4869-a707-48d211982469.png

1.2.4 插入图片

可以向工作表中插入本地或网络图片,并控制其显示属性。

package main

import (
    "fmt"
    _ "image/gif"
    _ "image/jpeg"
    _ "image/png"
    "github.com/xuri/excelize/v2"
)

func main() {
    f := excelize.NewFile()
    defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()

    // 1. 插入图片并缩放40%
    if err := f.AddPicture("Sheet1", "E2", "./pics/Img.jpg",
        &excelize.GraphicOptions{ScaleX: 0.4, ScaleY: 0.4}); err != nil {
        fmt.Println(err)
        return
    }
    
    // 2. 插入GIF图片,并设置更多属性(偏移、缩放、锁定等)
    enable, disable := true, false
    if err := f.AddPicture("Sheet1", "I2", "./pics/Java.gif",
        &excelize.GraphicOptions{
            PrintObject:     &enable,
            LockAspectRatio: false,
            OffsetX:         15,
            OffsetY:         10,
            Locked:          &disable,
            ScaleX:          0.8,
            ScaleY:          0.8,
        }); err != nil {
        fmt.Println(err)
        return
    }
    
    if err := f.SaveAs("Book1.xlsx"); err != nil {
        fmt.Println(err)
    }
}

插入图片后的效果如图3所示。

!https://cdn.nlark.com/yuque/0/2026/png/2447732/1768550676525-66fe6929-0e49-4be4-8763-4cdb6226af76.png

2. 工作簿、工作表与单元格操作

2.1 工作簿操作

工作簿(Workbook)是Excel文件本身。Excelize提供了创建、打开、保存、保护等核心API。

表 2: 操作 Excel 工作簿(Workbook)的核心 API

API 函数函数说明
func NewFile(options ...Options) *File用默认模板创建 Excel 文档,默认含 Sheet1 工作表。
func OpenFile(filename string, opts ...Options) (*File, error)打开指定路径的 Excel 文档。
func OpenReader(r io.Reader, opts ...Options) (*File, error)从数据流(如HTTP响应体)读取并打开 Excel 文档。
func (f *File) Save(options ...Options) error保存到创建或打开时的原始路径。
func (f *File) SaveAs(name string, opts ...Options) error另存 Excel 文档到新路径。
func (f *File) Close() error关闭文档,清理临时文件。
func (f *File) ProtectWorkbook(options *WorkbookProtectionOptions) error保护(如加密)工作簿。
func (f *File) UnprotectWorkbook(password ...string) error取消工作簿保护。

2.2 工作表操作

工作表(Sheet)是工作簿内的具体表格。Excelize 提供了完整的工作表管理功能。

表 3: 操作 Excel 工作表(Sheet)的核心 API

API 函数函数说明
func (f *File) NewSheet(sheet string) (int, error)新建工作表,返回索引。
func (f *File) DeleteSheet(sheet string) error删除工作表。
func (f *File) CopySheet(from, to int) error复制工作表。
func (f *File) SetSheetName(source, target string) error重命名工作表。
func (f *File) GetSheetList() (list []string)获取所有工作表名称列表。
func (f *File) GetSheetIndex(sheet string) (int, error)通过名称获取工作表索引。
func (f *File) SetSheetVisible(sheet string, visible bool) error设置工作表是否可见。
func (f *File) SetActiveSheet(index int)设置默认激活的工作表。

2.3 单元格基础

2.3.1 单元格引用与坐标处理

单元格地址主要有 A1 引用(如 B3)和 R1C1 引用(如 R3C2)两种形式。Excelize 默认使用 A1 引用,并提供了转换函数。

表 4: 单元格坐标处理 API

API 函数函数说明
func CoordinatesToCellName(col, row int, abs ...bool) (string, error)将行列编号 (1,1) 转换为 A1 地址 (“A1“)。
func CellNameToCoordinates(cell string) (int, int, error)将 A1 地址 (“B3“) 转换为行列编号 (2, 3)。
func ColumnNumberToName(num int) (string, error)将列编号 (1) 转换为列名 (“A“)。
func ColumnNameToNumber(name string) (int, error)将列名 (“C“) 转换为列编号 (3)。

2.3.2 单元格读写

表 5: 单元格赋值与读取 API

API 函数函数说明
func (f *File) SetCellValue(sheet, cell string, value interface{}) error通用设置单元格值(支持多种类型)。
func (f *File) SetCellStr/Int/Float/Bool(...)设置特定类型的单元格值。
func (f *File) GetCellValue(sheet, cell string, opts ...Options) (string, error)获取单元格格式化后的字符串值。
func (f *File) GetCellType(sheet, cell string) (CellType, error)获取单元格的数据类型。

内联存储值:指直接在单元格的 XML 节点中存储数据值(如 <v>42</v>),而非通过共享字符串表引用。这种方式对数值、日期等非文本数据效率更高。

2.3.3 单元格合并与公式

表 6: 单元格合并与公式 API

API 函数函数说明
func (f *File) MergeCell(sheet, topLeftCell, bottomRightCell string) error合并单元格区域。
func (f *File) UnmergeCell(sheet, topLeftCell, bottomRightCell string) error取消合并单元格区域。
func (f *File) SetCellFormula(sheet, cell, formula string, opts ...FormulaOptions) error设置单元格公式(如 =SUM(A1:B2))。
func (f *File) CalcCellValue(sheet, cell string, opts ...Options) (result string, err error)计算公式单元格的结果。

2.4 行列处理

2.4.1 行列插入、删除与调整

表 7: 行列处理 API

API 函数函数说明
func (f *File) InsertRows(sheet string, row, n int) error在指定行前插入 n 行。
func (f *File) RemoveRow(sheet string, row int) error删除指定行。
func (f *File) InsertCols(sheet, col string, n int) error在指定列前插入 n 列。
func (f *File) RemoveCol(sheet, col string) error删除指定列。
func (f *File) SetRowHeight(sheet string, row int, height float64) error设置行高。
func (f *File) SetColWidth(sheet, startCol, endCol string, width float64) error设置单列或多列宽度。
func (f *File) SetRowVisible(sheet string, row int, visible bool) error设置行可见性。
func (f *File) SetColVisible(sheet, columns string, visible bool) error设置列可见性。

3. 样式与条件格式

3.1 创建与设置样式

样式是一组格式特征的集合,如边框、填充、字体、对齐等。通过 NewStyle 函数创建样式并获取索引,然后使用 SetCellStyle 等函数应用。

表 8: 创建与应用样式 API

API 函数函数说明
func (f *File) NewStyle(style *Style) (int, error)创建新样式,返回样式ID。
func (f *File) SetCellStyle(sheet, topLeftCell, bottomRightCell string, styleID int) error为单元格区域应用样式。
func (f *File) SetRowStyle(sheet string, start, end, styleID int) error为行应用样式。
func (f *File) SetColStyle(sheet, columns string, styleID int) error为列应用样式。

Style 结构体定义了所有格式选项:

表 9: *Style 支持的格式选项

选项描述
Border []Border边框样式(类型、颜色、线型)。
Fill Fill填充格式(颜色、图案、渐变)。
Font *Font字体格式(名称、大小、颜色、加粗等)。
Alignment *Alignment对齐方式(水平、垂直、自动换行等)。
NumFmt int数字格式索引。
CustomNumFmt string自定义数字格式。

边框 (Border) 选项示例

style, err := f.NewStyle(&excelize.Style{
    Border: []excelize.Border{
        {Type: "left", Color: "000000", Style: 1},   // 左边框,黑色细实线
        {Type: "top", Color: "FF0000", Style: 2},    // 上边框,红色粗实线
    },
})

填充 (Fill) 选项示例

style, err := f.NewStyle(&excelize.Style{
    Fill: excelize.Fill{
        Type: "pattern", Pattern: 1, Color: []string{"FFFF00"}, // 实心黄色填充
    },
})

字体 (Font) 与对齐 (Alignment) 选项示例

style, err := f.NewStyle(&excelize.Style{
    Font: &excelize.Font{Bold: true, Size: 14, Color: "1a5fb4"},
    Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
})

3.2 条件格式

条件格式允许根据单元格的值动态应用样式。

表 10: 条件格式 API

API 函数函数说明
func (f *File) NewConditionalStyle(style *Style) (int, error)创建用于条件格式的样式。
func (f *File) SetConditionalFormat(sheet, rangeRef string, opts []ConditionalFormatOptions) error为单元格区域设置条件格式规则。

ConditionalFormatOptions 定义了规则,其核心字段是 Type(规则类型)和对应的条件参数。例如,高亮大于100的单元格:

// 1. 创建条件格式样式(红色填充)
redStyle, _ := f.NewConditionalStyle(&excelize.Style{Fill: excelize.Fill{Type: "pattern", Color: []string{"FFCCCC"}, Pattern: 1}})
// 2. 定义规则
err := f.SetConditionalFormat("Sheet1", "A1:A10",
    []excelize.ConditionalFormatOptions{
        {
            Type:     "cell",
            Criteria: ">",
            Value:    "100",
            Format:   &redStyle, // 应用红色样式
        },
    })

4. 图表、迷你图与图片

4.1 图表

图表是数据可视化的重要工具。Excelize 支持创建多达55种类型的图表。

表 11: 图表核心 API

API 函数函数说明
func (f *File) AddChart(sheet, cell string, chart *Chart, combo ...*Chart) error在工作表中添加图表。
func (f *File) AddChartSheet(sheet string, chart *Chart, combo ...*Chart) error创建单独的图表工作表。

Chart 结构体是图表的配置核心,主要包含 Type(图表类型,如 excelize.Col3DClustered)、Series(数据系列)和 Title(标题)等字段。ChartSeries 用于定义每个数据系列的数据来源(Values)、分类(Categories)和名称(Name)。

4.2 迷你图

迷你图(Sparkline)是嵌入在单元格中的微型图表,用于显示数据趋势。

表 12: 迷你图 API 与配置

API 函数/配置项描述
func (f *File) AddSparkline(sheet string, opts *SparklineOptions) error添加迷你图。
SparklineOptions.Location必填,迷你图放置的单元格范围。
SparklineOptions.Range必填,迷你图的数据来源范围。
SparklineOptions.Type类型:line(折线)、column(柱形)、win_loss(盈亏)。
err := f.AddSparkline("Sheet1", &excelize.SparklineOptions{
    Location: []string{"F2:F4"},
    Range:    []string{"B2:D4"},
    Type:     "column",
})

4.3 图片

除了基础的 AddPicture,还可以从字节流添加图片。

表 13: 图片操作 API

API 函数函数说明
func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error从字节数组添加图片。
func (f *File) GetPictureCells(sheet string) ([]string, error)获取包含图片的单元格列表。

Picture 结构体需指定文件扩展名(Extension)和文件字节数据(File)。

5. 数据验证与筛选

5.1 数据验证

数据验证用于限制用户在单元格中的输入,例如创建下拉列表、限制数字范围等。

表 14: 数据验证 API 使用流程

API 函数函数说明
dv := NewDataValidation(true)创建一个数据验证对象。
dv.SetSqref(“A1:A10”)设置验证规则应用的单元格范围。
dv.SetRange(...)设置验证条件(类型、运算符、值)。
f.AddDataValidation(“Sheet1”, dv)将验证规则添加到工作表。

示例:在 A1 单元格创建“是/否”下拉列表。

dv := excelize.NewDataValidation(true)
dv.SetSqref(“A1”) // 应用范围
// 设置验证类型为列表,列表选项为“是,否”
if err := dv.SetDropList([]string{“是”, “否”}); err != nil {
    fmt.Println(err)
}
dv.SetInput(“提示”, “请从下拉列表中选择“) // 设置输入提示
if err := f.AddDataValidation(“Sheet1”, dv); err != nil {
    fmt.Println(err)
}

5.2 自动筛选与表格

自动筛选可以为数据表添加筛选按钮,而表格(Table)是一种带有样式和筛选功能的结构化区域。

表 15: 筛选与表格 API

API 函数函数说明
func (f *File) AutoFilter(sheet, rangeRef string, opts []AutoFilterOptions) error为区域添加自动筛选。
func (f *File) AddTable(sheet string, table *Table) error将区域转换为表格。
// 为区域 A1:D10 添加自动筛选
err := f.AutoFilter(“Sheet1”, “A1:D10”, []excelize.AutoFilterOptions{})
// 将区域 A1:D9 转换为名为“MyTable”的表格
err := f.AddTable(“Sheet1”, &excelize.Table{Range: “A1:D9”, Name: “MyTable”})

【本篇核心知识点速记】

  1. 快速上手:使用 excelize.NewFile() 创建,f.SaveAs() 保存;使用 excelize.OpenFile() 打开。SetCellValueGetRows 是读写数据的核心。
  2. 核心对象管理
    • 工作簿:对应 File 结构体,是操作的入口。
    • 工作表:使用 NewSheetDeleteSheetGetSheetList 管理。
    • 单元格:使用 CoordinatesToCellName 处理坐标,SetCellValue/FormulaGetCellValue 进行读写,MergeCell 进行合并。
    • 行列:使用 InsertRows/ColsRemoveRow/ColSetRowHeight/ColWidth 进行结构调整。
  3. 样式系统
    • 通过 NewStyle(&excelize.Style{...}) 创建样式,获得样式ID。
    • Style 中定义 BorderFillFontAlignment 等所有格式。
    • 使用 SetCellStyle 将样式ID应用到单元格区域。
    • 条件格式:用 NewConditionalStyle 创建样式,用 SetConditionalFormat 设置规则,实现动态格式。
  4. 可视化与嵌入
    • 图表:用 AddChart 添加,核心是配置 Chart 结构体,特别是 TypeSeries(数据系列)。
    • 迷你图:用 AddSparkline 添加微型趋势图。
    • 图片:用 AddPicture 添加本地图片,或用 AddPictureFromBytes 添加字节流图片。
  5. 数据质量与控制
    • 数据验证:通过 NewDataValidation -> SetSqref -> SetRange/SetDropList -> AddDataValidation 流程,为单元格设置输入限制。
    • 筛选与表格AutoFilter 为区域添加筛选按钮;AddTable 创建具有固定样式的表格区域。