golang使用excelize库操作excel文件的方法详解

 更新时间:2022年11月29日 15:53:36   作者:CK持续成长  
Excelize是Go语言编写的用于操作Office Excel文档基础库,基于ECMA-376,ISO/IEC 29500国际标准,下面这篇文章主要给大家介绍了关于golang使用excelize库操作excel文件的相关资料,需要的朋友可以参考下

脚本之家 / 编程助手:解决程序员“几乎”所有问题!
脚本之家官方知识库 → 点击立即使用

​ 今天我们讲一下使用excelize操作excel,首先熟悉一下excel的文件构成,excel分为以下结构:

​ 1. excel文件,2. sheet页, 3. 行row, 4. 列col, 5. 项cell

​ 对应结构如下图:

1. 准备工作

我们读取的文件格式如上图所示, 我们先定义一个StockInfo结构来存储相应字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type StockInfo struct {
    ID              uint64    `gorm:"primaryKey;autoIncrement"`
    CompanyNo       string    `gorm:"column:company_no"`
    CompanyAbbr     string    `gorm:"column:company_abbr"`
    StockNo         string    `gorm:"column:stock_no"`
    StockName       string    `gorm:"column:stock_name"`
    ListingTime     time.Time `gorm:"column:listing_time"`
    GmtCreate       time.Time `gorm:"column:gmt_create"`
    GmtModified     time.Time `gorm:"column:gmt_modified"`
}
 
func (stock *StockInfo) TableName() string {
    return "stock_info"
}

这里我们会使用gorm将数据存储到数据库,所以这里我们添加了gorm的标签。

安装excelize库:

1
go get github.com/xuri/excelize/v2@v2.5.0

2. 使用excelize读取excel文件

操作步骤:

1.先获取文件excel.File对象,excelize提供了两个函数获取文件File对象

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

这里我们使用如下方式获取File实例:

1
2
3
4
file, err := excelize.OpenFile("stock.xlsx")
if err != nil {
   log.Fatalf("open excel file err, error:%+v\n", err)
}

亦可以使用如下方式:

1
2
3
4
5
6
7
8
9
fileReader,err := os.OpenFile("stock.xlsx", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
  log.Fatalf("open excel file err, error:%+v\n", err)
}
 
file, err := excelize.OpenReader(fileReader)
if err != nil {
  log.Fatalf("open excel file err, error:%+v\n", err)
}

2.获取sheet, excelize库提供了如下操作的sheet的函数

1
2
3
4
5
6
7
8
// 根据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

​ 这里我们我先通过GetSheetList获取所有的sheet名称列表,然后对每个sheet进行操作

3.读取excel中数据

读取方式一:直接读取Row和Col的数据二维数组,然后进行读取操作,使用如下函数

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

下面代码实现按行列读取,将读取到的集合以StockInfo的结构存放到Slice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
func GetStockList1(file *excelize.File) ([]StockInfo, error){
 
   var list []StockInfo
 
   for _,sheetName := range file.GetSheetList() {
 
       rows, err := file.GetRows(sheetName)
 
       if err != nil {
           log.Printf("excel get rows error, err:%+v\n", err)
           return nil, err
       }
 
       for index, row := range rows {
           // 跳过第一行标题
           if index == 0 {
               continue
           }
 
           lt, err := time.Parse("2006-01-02", strings.TrimSpace(row[4]))
           if err != nil {
               return nil, err
           }
 
           list = append(list, StockInfo{
               CompanyNo:   row[0],
               CompanyAbbr: row[1],
               StockNo:     row[2],
               StockName:   row[3],
               ListingTime: lt,
               GmtCreate:   time.Now(),
           })
       }
   }
 
   return list,nil
}

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

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

然后配合Rows对象的Next方法和Columns方法,获取列数据,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
func GetStockList2(file *excelize.File) ([]StockInfo, error){
   var list []StockInfo
 
   for _,sheetName := range file.GetSheetList() {
 
       rows, err := file.Rows(sheetName)
       if err != nil{
           return nil, err
       }
 
       for rows.Next() {
           // 这里读到第一行标题的时候,跳过
           if rows.CurrentRow() == 1 {
        // 这一句一定要调用,否则两列数据叠加在一起
               rows.Columns()
               continue
           }
 
           // 获取当前行的列
           cols,_ := rows.Columns()
 
           // 按列进行处理
           lt, _ := time.Parse("2006-01-02", strings.TrimSpace(cols[4]))
           list = append(list, StockInfo{
               CompanyNo:  strings.TrimSpace(cols[0]) ,
               CompanyAbbr: strings.TrimSpace(cols[1]),
               StockNo:     strings.TrimSpace(cols[2]),
               StockName:   strings.TrimSpace(cols[3]),
               ListingTime: lt,
               GmtCreate:   time.Now(),
           })
       }
   }
 
   return list,nil
}

读取方式三:使用GetCellValue函数,根据具体的sheet和Cell的行和列名称进行获取Cell值,GetCellValue函数如下:

1
func (f *File) GetCellValue(sheet, axis string, opts ...Options) (string, error)

直接使用file的GetCellValue的函数操作,使用excel的"A2","E4"这种行列定位cell的方法进行操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
func GetStockList3(file *excelize.File) ([]StockInfo, error){
   var list []StockInfo
 
   for _,sheetName := range file.GetSheetList() {
 
       rows, err := file.Rows(sheetName)
       if err != nil{
           return nil, err
       }
 
    // 从第二行开始读取
       for i := 2; i <= rows.TotalRows(); i++ {
 
           // 根据sheet中Cell的位置获取,例如A1表示第一行的第一列
           companyNo, _ := file.GetCellValue(sheetName,fmt.Sprintf("A%d",i))
           companyAbbr, _ := file.GetCellValue(sheetName,fmt.Sprintf("B%d",i))
           stockNo, _ := file.GetCellValue(sheetName,fmt.Sprintf("C%d",i))
           stockName, _ := file.GetCellValue(sheetName,fmt.Sprintf("D%d",i))
 
           cell4, err := file.GetCellValue(sheetName, fmt.Sprintf("E%d",i))
           if err != nil {
               log.Printf("get cell error, err:%+v\n", err)
           }
           lt, _ := time.Parse("2006-01-02", strings.TrimSpace(cell4))
 
           list = append(list, StockInfo{
               CompanyNo:  companyNo ,
               CompanyAbbr: companyAbbr,
               StockNo:     stockNo,
               StockName:   stockName,
               ListingTime: lt,
               GmtCreate:   time.Now(),
           })
       }
   }
 
   return list,nil
}

4.数据读取成功后,我们使用gorm将数据存储到数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
dsn := "root:root@tcp(127.0.0.1:3306)/stock?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
  log.Fatalf("connect mysql error:%+v\n",err)
}
 
file, err := excelize.OpenFile("stock.xlsx")
if err != nil {
  log.Fatalf("open excel file err, error:%+v\n", err)
}
 
list1, err := GetStockList3(file)
if err != nil {
  log.Fatalf("get stock list1 error:%+v\n", err)
}
 
log.Printf("read stock list:%+v\n", list1)
 
defer file.Close()
 
db.Omit("GmtModified").Create(&list1)

3. 使用excelize将数据写入excel文件

操作步骤:

1.首先我们从mysql数据库,将上面例子从的数据库读出来

1
2
3
4
5
6
7
8
9
10
11
dsn := "root:root@tcp(127.0.0.1:3306)/stock?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
 
    if err != nil {
        log.Fatalf("connect mysql error:%+v\n",err)
    }
 
    var stocks []StockInfo
    db.Find(&stocks)
 
    log.Printf("stocks:%+v\n", stocks)

2.创建excelize的file对象,用来操作excel文件

1
2
3
file := excelize.NewFile()
// 创建一个名字为stock的sheet页
file.NewSheet("stock")

3.将数据写入到excel

写入方式一: 按行添加数据方法:

1
func (f *File) SetSheetRow(sheet, axis string, slice interface{}) error

第一个参数为sheet的名称,第二个参数表示从哪一列开始,第三个参数为连续写入的列的slice,代码如下:

1
2
3
4
5
6
7
8
9
10
11
func WriteToExcel1(file *excelize.File, stocks []StockInfo) error {
     
    rowsCount := len(stocks)
  
    for i := 1; i <= rowsCount ;i++ {
ex
        file.SetSheetRow("stock",fmt.Sprintf("A%d",i),&[]interface{}{stocks[i-1].CompanyNo,
            stocks[i-1].CompanyAbbr, stocks[i-1].StockNo, stocks[i-1].StockName})
    }
    return nil
 }

写入方式二: 按Cell设置数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func WriteToExcel2(file *excelize.File, stocks []StockInfo) error {
 
   rowsCount := len(stocks)
 
   for i := 1; i <= rowsCount ;i++ {
 
       file.SetCellStr("stock",fmt.Sprintf("A%d",i),stocks[i-1].CompanyNo)
       file.SetCellValue("stock",fmt.Sprintf("B%d",i),stocks[i-1].CompanyAbbr)
       file.SetCellValue("stock",fmt.Sprintf("C%d",i),stocks[i-1].StockNo)
       file.SetCellValue("stock",fmt.Sprintf("D%d",i),stocks[i-1].StockName)
       file.SetCellValue("stock",fmt.Sprintf("E%d",i),stocks[i-1].ListingTime)
 
   }
   return nil
}

将excel数据保存到文件

1
2
defer file.Close()
file.SaveAs("stock_2.xlsx")

4. 参考资料:

​ 包地址:https://pkg.go.dev/github.com/xuri/excelize/v2

总结

到此这篇关于golang使用excelize库操作excel文件的文章就介绍到这了,更多相关golang excelize库操作excel内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

蓄力AI

微信公众号搜索 “ 脚本之家 ” ,选择关注

程序猿的那些事、送书等活动等着你

原文链接:https://blog.csdn.net/keenw/article/details/125814918

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!

相关文章

  • Golang工作池的使用实例讲解

    Golang工作池的使用实例讲解

    我们使用Go语言开发项目,常常会使用到goroutine;goroutine太多会造成系统占用过高或其他系统异常,我们可以将goroutine控制指定数量,且减少goroutine的创建,这就运用到Go工作池,下面就介绍和使用一下
    2023-02-02
  • Golang通脉之数据类型详情

    Golang通脉之数据类型详情

    这篇文章主要介绍了Golang通脉之数据类型,在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等,Go语言中标识符允许由字母数字和_(下划线)组成,并且只能以字母和_开头,更详细内容请看下面文章吧
    2021-10-10
  • Golang实现for循环运行超时后自动退出的方法

    Golang实现for循环运行超时后自动退出的方法

    for循环对大家来说应该都不陌生,对于golang来说更是必不可少,所以下面这篇文章就来给大家介绍了关于Golang如何实现for循环运行一段时间超时后自动退出的相关资料,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • go-cqhttp智能聊天功能的实现

    go-cqhttp智能聊天功能的实现

    这篇文章主要介绍了go-cqhttp智能聊天功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • Go语言之fo循环与条件判断

    Go语言之fo循环与条件判断

    这篇文章主要介绍Go语言之fo循环与条件判断,for 循环是一个循环控制结构,可以执行指定次数的循环。下面文章我们结合条件判断,感兴趣的朋友可以参考一下
    2021-10-10
  • Go语言实现遗传算法的实例代码

    Go语言实现遗传算法的实例代码

    Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文将重点介绍如何用Go语言实现遗传算法。如果你还没有参加过GoLang Tour,我还建议你快速看一下这门语言的介绍
    2017-11-11
  • Golang Redis连接池实现原理及示例探究

    Golang Redis连接池实现原理及示例探究

    这篇文章主要为大家介绍了Golang Redis连接池实现示例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Go语言Gin框架前后端分离项目开发实例

    Go语言Gin框架前后端分离项目开发实例

    本文主要介绍了Go语言Gin框架前后端分离项目开发工程化实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-11-11
  • Go操作etcd的实现示例

    Go操作etcd的实现示例

    etcd是近几年比较火热的一个开源的、分布式的键值对数据存储系统,提供共享配置、服务的注册和发现,本文主要介绍etcd的安装和使用,感兴趣的可以了解一下
    2021-09-09
  • go性能分析工具pprof的用途及使用详解

    go性能分析工具pprof的用途及使用详解

    刚开始接触go就遇到了一个内存问题,在进行内存分析的时候发现了一下比较好的工具,在此留下记录,下面这篇文章主要给大家介绍了关于go性能分析工具pprof的用途及使用的相关资料,需要的朋友可以参考下
    2023-01-01

最新评论