最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang使用excelize庫(kù)操作excel文件的方法詳解

 更新時(shí)間:2022年11月29日 15:53:36   作者:CK持續(xù)成長(zhǎng)  
Excelize是Go語(yǔ)言編寫的用于操作Office Excel文檔基礎(chǔ)庫(kù),基于ECMA-376,ISO/IEC 29500國(guó)際標(biāo)準(zhǔn),下面這篇文章主要給大家介紹了關(guān)于golang使用excelize庫(kù)操作excel文件的相關(guān)資料,需要的朋友可以參考下

? 今天我們講一下使用excelize操作excel,首先熟悉一下excel的文件構(gòu)成,excel分為以下結(jié)構(gòu):

? 1. excel文件,2. sheet頁(yè), 3. 行row, 4. 列col, 5. 項(xiàng)cell

? 對(duì)應(yīng)結(jié)構(gòu)如下圖:

1. 準(zhǔn)備工作

我們讀取的文件格式如上圖所示, 我們先定義一個(gè)StockInfo結(jié)構(gòu)來(lái)存儲(chǔ)相應(yīng)字段

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"
}

這里我們會(huì)使用gorm將數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù),所以這里我們添加了gorm的標(biāo)簽。

安裝excelize庫(kù):

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

2. 使用excelize讀取excel文件

操作步驟:

1.先獲取文件excel.File對(duì)象,excelize提供了兩個(gè)函數(shù)獲取文件File對(duì)象

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

這里我們使用如下方式獲取File實(shí)例:

   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庫(kù)提供了如下操作的sheet的函數(shù)

 // 根據(jù)sheet的名稱獲取sheet的索引
 func (f *File) GetSheetIndex(name string) int
 // 根據(jù)sheet的索引獲取sheet的名稱
 func (f *File) GetSheetName(index int) (name string)
 // 獲取所有sheet的名稱列表
 func (f *File) GetSheetList() (list []string)
 // 獲取所有sheet的索引對(duì)應(yīng)的名稱集合
 func (f *File) GetSheetMap() map[int]string

? 這里我們我先通過(guò)GetSheetList獲取所有的sheet名稱列表,然后對(duì)每個(gè)sheet進(jìn)行操作

3.讀取excel中數(shù)據(jù)

讀取方式一:直接讀取Row和Col的數(shù)據(jù)二維數(shù)組,然后進(jìn)行讀取操作,使用如下函數(shù)

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

下面代碼實(shí)現(xiàn)按行列讀取,將讀取到的集合以StockInfo的結(jié)構(gòu)存放到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 {
 			// 跳過(guò)第一行標(biāo)題
 			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函數(shù),返回Rows的對(duì)象進(jìn)行操作, 函數(shù)原型如下:

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

然后配合Rows對(duì)象的Next方法和Columns方法,獲取列數(shù)據(jù),如下:

 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() {
 			// 這里讀到第一行標(biāo)題的時(shí)候,跳過(guò)
 			if rows.CurrentRow() == 1 {
         // 這一句一定要調(diào)用,否則兩列數(shù)據(jù)疊加在一起
 				rows.Columns()
 				continue
 			}
 
 			// 獲取當(dāng)前行的列
 			cols,_ := rows.Columns()
 
 			// 按列進(jìn)行處理
 			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函數(shù),根據(jù)具體的sheet和Cell的行和列名稱進(jìn)行獲取Cell值,GetCellValue函數(shù)如下:

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

直接使用file的GetCellValue的函數(shù)操作,使用excel的"A2","E4"這種行列定位cell的方法進(jìn)行操作:

 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++ {
 
 			// 根據(jù)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.數(shù)據(jù)讀取成功后,我們使用gorm將數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)

  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將數(shù)據(jù)寫入excel文件

操作步驟:

1.首先我們從mysql數(shù)據(jù)庫(kù),將上面例子從的數(shù)據(jù)庫(kù)讀出來(lái)

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.創(chuàng)建excelize的file對(duì)象,用來(lái)操作excel文件

file := excelize.NewFile()
// 創(chuàng)建一個(gè)名字為stock的sheet頁(yè)
file.NewSheet("stock")

3.將數(shù)據(jù)寫入到excel

寫入方式一: 按行添加數(shù)據(jù)方法:

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

第一個(gè)參數(shù)為sheet的名稱,第二個(gè)參數(shù)表示從哪一列開始,第三個(gè)參數(shù)為連續(xù)寫入的列的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設(shè)置數(shù)據(jù):

 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數(shù)據(jù)保存到文件

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

4. 參考資料:

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

總結(jié)

到此這篇關(guān)于golang使用excelize庫(kù)操作excel文件的文章就介紹到這了,更多相關(guān)golang excelize庫(kù)操作excel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文詳解Go語(yǔ)言中切片的底層原理

    一文詳解Go語(yǔ)言中切片的底層原理

    在Go語(yǔ)言中,切片作為一種引用類型數(shù)據(jù),相對(duì)數(shù)組而言是一種動(dòng)態(tài)長(zhǎng)度的數(shù)據(jù)類型,使用的場(chǎng)景也是非常多,所以本文主要來(lái)和大家聊聊切片的底層原理,需要的可以參考一下
    2023-06-06
  • 使用Go語(yǔ)言發(fā)送郵件的示例代碼

    使用Go語(yǔ)言發(fā)送郵件的示例代碼

    很多朋友想試試用Go語(yǔ)言發(fā)送郵件,所以接下來(lái)小編給大家介紹一下如何用Go語(yǔ)言發(fā)送郵件,文中通過(guò)代碼實(shí)例講解的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Golang實(shí)現(xiàn)Md5校驗(yàn)的示例代碼

    Golang實(shí)現(xiàn)Md5校驗(yàn)的示例代碼

    本文主要介紹了Golang實(shí)現(xiàn)Md5校驗(yàn)的示例代碼,要求接收方需要文件的md5值,和接收到的文件做比對(duì),以免文件不完整,但引起bug,下面就一起來(lái)解決一下
    2024-08-08
  • Go語(yǔ)言中http和mysql的實(shí)現(xiàn)代碼

    Go語(yǔ)言中http和mysql的實(shí)現(xiàn)代碼

    本文通過(guò)實(shí)例代碼給大家介紹了Go語(yǔ)言中http和mysql的實(shí)現(xiàn)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-11-11
  • GO語(yǔ)言實(shí)現(xiàn)的http抓包分析工具pproxy介紹

    GO語(yǔ)言實(shí)現(xiàn)的http抓包分析工具pproxy介紹

    這篇文章主要介紹了GO語(yǔ)言實(shí)現(xiàn)的http抓包分析工具pproxy介紹,本文同時(shí)對(duì)比了Fiddler、Charles等抓包軟件,需要的朋友可以參考下
    2015-03-03
  • 一文帶你輕松學(xué)會(huì)Go語(yǔ)言動(dòng)態(tài)調(diào)用函數(shù)

    一文帶你輕松學(xué)會(huì)Go語(yǔ)言動(dòng)態(tài)調(diào)用函數(shù)

    這篇文章主要是帶大家學(xué)習(xí)一下Go語(yǔ)言是如何動(dòng)態(tài)調(diào)用函數(shù)的,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的可以參考下
    2022-11-11
  • 深入解析Go語(yǔ)言編程中slice切片結(jié)構(gòu)

    深入解析Go語(yǔ)言編程中slice切片結(jié)構(gòu)

    這篇文章主要介紹了Go語(yǔ)言編程中slice切片結(jié)構(gòu),其中Append方法的用法介紹較為詳細(xì),需要的朋友可以參考下
    2015-10-10
  • Golang HTML 模板使用指南示例詳解

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

    本文詳細(xì)介紹了Golang HTML模板的使用方法,包括基礎(chǔ)模板、高級(jí)模板、完整應(yīng)用示例、CSS樣式、JavaScript交互等,文章強(qiáng)調(diào)了模板組織、代碼復(fù)用、語(yǔ)義化HTML、響應(yīng)式設(shè)計(jì)、性能優(yōu)化等最佳實(shí)踐,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • 一文搞懂Go語(yǔ)言中defer關(guān)鍵字的使用

    一文搞懂Go語(yǔ)言中defer關(guān)鍵字的使用

    defer是golang中用的比較多的一個(gè)關(guān)鍵字,也是go面試題里經(jīng)常出現(xiàn)的問題。今天就來(lái)整理一下關(guān)于defer的學(xué)習(xí)使用,希望對(duì)需要的朋友有所幫助
    2022-09-09
  • Go語(yǔ)言中的空值(nil)與零值(zerovalue)區(qū)別詳解

    Go語(yǔ)言中的空值(nil)與零值(zerovalue)區(qū)別詳解

    在Go語(yǔ)言中,空值(nil)和零值(zero value)是兩個(gè)不同的概念,它們?cè)谡Z(yǔ)義、使用場(chǎng)景以及實(shí)際的編程實(shí)踐中有著明顯的區(qū)別,理解這兩者的差異對(duì)于編寫清晰、健壯的Go代碼至關(guān)重要,需要的朋友可以參考下
    2024-06-06

最新評(píng)論

靖西县| 阿拉善右旗| 涞水县| 天长市| 霍山县| 区。| 涿州市| 建湖县| 鹤岗市| 呈贡县| 松原市| 车险| 淮滨县| 湛江市| 镇平县| 宜昌市| 兰溪市| 东海县| 阜康市| 通海县| 罗平县| 利辛县| 澎湖县| 峨眉山市| 肃宁县| 突泉县| 濉溪县| 安仁县| 涞源县| 雅江县| 沙坪坝区| 子长县| 松潘县| 汉川市| 霍林郭勒市| 清涧县| 杭锦旗| 黔西县| 都兰县| 胶州市| 张掖市|