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结构来存储相应字段

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库:

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

2. 使用excelize读取excel文件

操作步骤:

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

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

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

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

亦可以使用如下方式:

   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的函数

 // 根据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的数据二维数组,然后进行读取操作,使用如下函数

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

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

 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的对象进行操作, 函数原型如下:

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

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

 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函数如下:

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

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

 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将数据存储到数据库

  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数据库,将上面例子从的数据库读出来

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文件

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

3.将数据写入到excel

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

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

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

 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设置数据:

 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数据保存到文件

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

4. 参考资料:

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

总结

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

相关文章

  • 一文详解Go语言中切片的底层原理

    一文详解Go语言中切片的底层原理

    在Go语言中,切片作为一种引用类型数据,相对数组而言是一种动态长度的数据类型,使用的场景也是非常多,所以本文主要来和大家聊聊切片的底层原理,需要的可以参考一下
    2023-06-06
  • 使用Go语言发送邮件的示例代码

    使用Go语言发送邮件的示例代码

    很多朋友想试试用Go语言发送邮件,所以接下来小编给大家介绍一下如何用Go语言发送邮件,文中通过代码实例讲解的非常详细,需要的朋友可以参考下
    2023-07-07
  • Golang实现Md5校验的示例代码

    Golang实现Md5校验的示例代码

    本文主要介绍了Golang实现Md5校验的示例代码,要求接收方需要文件的md5值,和接收到的文件做比对,以免文件不完整,但引起bug,下面就一起来解决一下
    2024-08-08
  • Go语言中http和mysql的实现代码

    Go语言中http和mysql的实现代码

    本文通过实例代码给大家介绍了Go语言中http和mysql的实现代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-11-11
  • GO语言实现的http抓包分析工具pproxy介绍

    GO语言实现的http抓包分析工具pproxy介绍

    这篇文章主要介绍了GO语言实现的http抓包分析工具pproxy介绍,本文同时对比了Fiddler、Charles等抓包软件,需要的朋友可以参考下
    2015-03-03
  • 一文带你轻松学会Go语言动态调用函数

    一文带你轻松学会Go语言动态调用函数

    这篇文章主要是带大家学习一下Go语言是如何动态调用函数的,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的可以参考下
    2022-11-11
  • 深入解析Go语言编程中slice切片结构

    深入解析Go语言编程中slice切片结构

    这篇文章主要介绍了Go语言编程中slice切片结构,其中Append方法的用法介绍较为详细,需要的朋友可以参考下
    2015-10-10
  • Golang HTML 模板使用指南示例详解

    Golang HTML 模板使用指南示例详解

    本文详细介绍了Golang HTML模板的使用方法,包括基础模板、高级模板、完整应用示例、CSS样式、JavaScript交互等,文章强调了模板组织、代码复用、语义化HTML、响应式设计、性能优化等最佳实践,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • 一文搞懂Go语言中defer关键字的使用

    一文搞懂Go语言中defer关键字的使用

    defer是golang中用的比较多的一个关键字,也是go面试题里经常出现的问题。今天就来整理一下关于defer的学习使用,希望对需要的朋友有所帮助
    2022-09-09
  • Go语言中的空值(nil)与零值(zerovalue)区别详解

    Go语言中的空值(nil)与零值(zerovalue)区别详解

    在Go语言中,空值(nil)和零值(zero value)是两个不同的概念,它们在语义、使用场景以及实际的编程实践中有着明显的区别,理解这两者的差异对于编写清晰、健壮的Go代码至关重要,需要的朋友可以参考下
    2024-06-06

最新评论