golang使用excelize庫操作excel文件的方法詳解
? 今天我們講一下使用excelize操作excel,首先熟悉一下excel的文件構(gòu)成,excel分為以下結(jié)構(gòu):
? 1. excel文件,2. sheet頁, 3. 行row, 4. 列col, 5. 項cell
? 對應(yīng)結(jié)構(gòu)如下圖:

1. 準備工作
我們讀取的文件格式如上圖所示, 我們先定義一個StockInfo結(jié)構(gòu)來存儲相應(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"
}
這里我們會使用gorm將數(shù)據(jù)存儲到數(shù)據(jù)庫,所以這里我們添加了gorm的標簽。
安裝excelize庫:
go get github.com/xuri/excelize/v2@v2.5.0
2. 使用excelize讀取excel文件
操作步驟:
1.先獲取文件excel.File對象,excelize提供了兩個函數(shù)獲取文件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的函數(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的索引對應(yīng)的名稱集合 func (f *File) GetSheetMap() map[int]string
? 這里我們我先通過GetSheetList獲取所有的sheet名稱列表,然后對每個sheet進行操作
3.讀取excel中數(shù)據(jù)
讀取方式一:直接讀取Row和Col的數(shù)據(jù)二維數(shù)組,然后進行讀取操作,使用如下函數(shù)
func (f *File) GetRows(sheet string, opts ...Options) ([][]string, error)
下面代碼實現(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 {
// 跳過第一行標題
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的對象進行操作, 函數(shù)原型如下:
func (f *File) Rows(sheet string) (*Rows, error)
然后配合Rows對象的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() {
// 這里讀到第一行標題的時候,跳過
if rows.CurrentRow() == 1 {
// 這一句一定要調(diào)用,否則兩列數(shù)據(jù)疊加在一起
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函數(shù),根據(jù)具體的sheet和Cell的行和列名稱進行獲取Cell值,GetCellValue函數(shù)如下:
func (f *File) GetCellValue(sheet, axis string, opts ...Options) (string, error)
直接使用file的GetCellValue的函數(shù)操作,使用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++ {
// 根據(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ù)存儲到數(shù)據(jù)庫
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ù)庫,將上面例子從的數(shù)據(jù)庫讀出來
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對象,用來操作excel文件
file := excelize.NewFile()
// 創(chuàng)建一個名字為stock的sheet頁
file.NewSheet("stock")
3.將數(shù)據(jù)寫入到excel
寫入方式一: 按行添加數(shù)據(jù)方法:
func (f *File) SetSheetRow(sheet, axis string, slice interface{}) error
第一個參數(shù)為sheet的名稱,第二個參數(shù)表示從哪一列開始,第三個參數(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庫操作excel文件的文章就介紹到這了,更多相關(guān)golang excelize庫操作excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Go語言操作Excel利器之excelize類庫詳解
- 如何使用?Go?和?Excelize?構(gòu)建電子表格
- Go Excelize API源碼閱讀GetPageLayout及SetPageMargins
- Go Excelize API源碼解讀GetSheetViewOptions與SetPageLayout
- Go?Excelize?API源碼閱讀SetSheetViewOptions示例解析
- Go?Excelize?API源碼解析GetSheetFormatPr使用示例
- Go?Excelize?API源碼閱讀Close及NewSheet方法示例解析
- go中Excelize處理excel表實現(xiàn)帶數(shù)據(jù)校驗的文件導出
相關(guān)文章
Golang實現(xiàn)for循環(huán)運行超時后自動退出的方法
for循環(huán)對大家來說應(yīng)該都不陌生,對于golang來說更是必不可少,所以下面這篇文章就來給大家介紹了關(guān)于Golang如何實現(xiàn)for循環(huán)運行一段時間超時后自動退出的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧。2017-11-11
Golang?Redis連接池實現(xiàn)原理及示例探究
這篇文章主要為大家介紹了Golang?Redis連接池實現(xiàn)示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01

