goland 读写excel

35 篇文章 2 订阅
17 篇文章 2 订阅

Excelize 是 Go 语言编写的一个用来操作 Office Excel 文档类库,基于 ECMA-376 Office OpenXML 标准。

可以使用它来读取、写入 XLSX 文件,相比较其他的开源类库,Excelize 支持写入原本带有图片(表)的文档,还支持向 Excel 中插入图片,并且在保存后不会丢失图表样式。

[注意事项]

使用最新版本 Excelize 要求您使用的 Go 语言为 1.15 或更高版本

一、依赖库 

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

核心库

"github.com/xuri/excelize/v2"

[excelize官方项目]

[excelize官方API]

二、读取和写入

(一)读取excel文件数据

函数

// 读取excel
func TestReadExcel() {
	// 打开文件
	f, err := excelize.OpenFile("Book1.xlsx")
	if err != nil {
		fmt.Println(err)
		return
	}
	// 捕获异常
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	// 获取工作表中指定单元格的值
	cell, err := f.GetCellValue("Sheet1", "A2")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("cell", cell)
	// 获取 Sheet1 上所有单元格
	rows, err := f.GetRows("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}
	for _, row := range rows {
		for _, colCell := range row {
			fmt.Print(colCell, "\t")
		}
		fmt.Println()
	}
}

调用 

func TestGoExcelB(t *testing.T) {
	GoExcel.TestReadExcel()
}

效果

(二)覆盖写入

//  覆盖写入
func TestWriterEecel(sheetName string, cell string, writerContent string) {
	//  实例化结构体对象f,并调用结构体方法NewFile新建文件
	f := excelize.NewFile()
	// 创建一个工作表
	index := f.NewSheet("Sheet1")
	// 设置单元格的值
	f.SetCellValue("Sheet1", "A2", "Hello world.")
	f.SetCellValue("Sheet1", "B2", 100)
	// 设置工作簿的默认工作表
	f.SetActiveSheet(index)
	// 根据指定路径保存文件
	if err := f.SaveAs("Book1.xlsx"); err != nil {
		fmt.Println(err)
	}
}

(三)追加写入

封装

/*
* @methods TestAppendExcel
* @description 追加数据
* @params fileName string	文件名
* @params activeSheet string	Sheet名
* @params writerData map[string][]string{}	写入数据
 */
func TestAppendExcel(fileName string, activeSheet string, writerData map[string][]string) {
	//  文件名
	// fileName := "Book1.xlsx"
	//  工作表
	// activeSheet := "Sheet1"
	//  打开文件
	f, _ := excelize.OpenFile(fileName)
	// Get all the rows in the Sheet1
	//  获取所有行的数据,按行获取
	rows, err := f.GetRows(activeSheet)
	// 行数据
	fmt.Printf("rows_content:%v\n", rows)
	//  行数
	fmt.Println("rows_len:", len(rows))
	//  捕获异常
	if err != nil {
		fmt.Println(err)
		return
	}
	//  获取所有列的内容 按列获取
	cols, err := f.GetCols(activeSheet)
	//  捕获异常
	if err != nil {
		fmt.Println(err)
		return
	}
	// 列数据
	fmt.Printf("cols_content:%v\n", cols)
	//  列数
	fmt.Println("cols_len:", len(cols))
	//  行高
	lineHeight, err := f.GetRowHeight(activeSheet, 1)
	fmt.Println("lineHeight:", lineHeight)
	//  捕获异常
	if err != nil {
		fmt.Println(err)
		return
	}
	//  行级别
	lineLevel, err := f.GetRowOutlineLevel(activeSheet, 2)
	fmt.Println("lineLevel:", lineLevel)
	//  捕获异常
	if err != nil {
		fmt.Println(err)
		return
	}
	// 遍历写入数据(遍历map元素是字符串数组)
	for i, arr_v := range writerData["names"] {
		fmt.Println("writerData['names']", arr_v)
		// 判断数据类型
		fmt.Println("writerData['names'] arr_v type:", reflect.TypeOf(arr_v))
		// 单元格值设置
		f.SetCellValue(activeSheet, fmt.Sprintf("A%d", len(rows)+1+i), fmt.Sprintf("%v", arr_v))
	}
	for i, arr_v := range writerData["address"] {
		fmt.Println("writerData['address']", arr_v)
		//  判断数据类型
		fmt.Println("writerData['address'] arr_v type:", reflect.TypeOf(arr_v))
		f.SetCellValue(activeSheet, fmt.Sprintf("B%d", len(rows)+1+i), fmt.Sprintf("%v", arr_v))
	}
	for i, arr_v := range writerData["numbers"] {
		fmt.Println("writerData['numbers']", arr_v)
		//  判断数据类型
		fmt.Println("writerData['numbers'] arr_v type:", reflect.TypeOf(arr_v))
		// 单元格值设置
		f.SetCellValue(activeSheet, fmt.Sprintf("C%d", len(rows)+1+i), fmt.Sprintf("%v", arr_v))
		fmt.Println("arr_v[i]:", arr_v)
	}
	//  单元格值设置
	// f.SetCellValue(activeSheet, fmt.Sprintf("A%d", len(rows)+1), fmt.Sprintf("aa%d", len(rows)+1))
	//  保存文件,并捕获异常
	if err := f.SaveAs(fileName); err != nil {
		fmt.Println(err)
	}
}

调用

func TestGoExcelC(t *testing.T) {
	// 声明集合
	map_data := map[string][]string{}
	// 声明数组并初始化
	names := []string{"张三", "李四", "王五"}
	fmt.Printf("names:%v\n", names)
	// 声明数组并初始化
	address := []string{"泉州市丰泽区", "厦门市集美区", "福州市金山区"}
	fmt.Printf("address:%v\n", address)
	// 声明数组并初始化
	numbers := []string{"2020001", "2020002", "2020003"}
	fmt.Printf("numbers:%v\n", numbers)

	map_data["names"] = names
	map_data["address"] = address
	map_data["numbers"] = numbers
	t.Logf("map_data:%v\n", map_data) // map_data:map[address:[泉州市丰泽区 厦门市集美区 福州市金山区] names:[张三 李四 王五] numbers:[123123 234234 4534534]]

	// 追加写入excel
	GoExcel.TestAppendExcel("Book1.xlsx", "Sheet1", map_data)
}

效果 :

三 、常用方法

	// 获取当前活动sheet页的索引
	sheet_idx := f.GetActiveSheetIndex()
	sheetName := f.GetSheetName(sheet_idx)

	// 设置单元格的值
	// 在excel中SetCellValue设置的值都是常规模式
	f.SetCellValue(sheetName, "A1", "字符串")
	f.SetCellValue(sheetName, "A2", 200)
	f.SetCellValue(sheetName, "A3", true)

	f.SetCellStr(sheetName, "B1", "这是SetCellStr")
	f.SetCellBool(sheetName, "B3", true)
	f.SetCellFloat(sheetName, "B2", 100.00200, 3, 64) // 第三个参数是值,必须是float64类型的,第四个是小数点的位数,第五个是32或者64,原始的数据是float32就是32,是float64就是64
	f.SetCellInt(sheetName, "B4", 100000)             // 整数
	f.SetCellDefault(sheetName, "C1", "这是SetCellDefault")

	// 设置单个单元格的公式
	f.SetCellFormula(sheetName, "C2", "B2+A2")

	// 链接只会做链接,不会给单元格赋值,需要单独设置值和样式
	f.SetCellHyperLink(sheetName, "D1", "https://www.baidu.com", "External")
	f.SetCellValue(sheetName, "D1", "链接1External")
	f.SetCellHyperLink(sheetName, "D2", "Sheet1!A1", "Location")
	f.SetCellValue(sheetName, "D2", "链接2Location")

	// 插入行
	f.InsertRow(sheetName, 2)
	f.InsertCol(sheetName, "D")

	// 复制行
	f.DuplicateRow(sheetName, 3)
	f.DuplicateRowTo(sheetName, 1, 7)

	// 删除行/列
	f.RemoveCol(sheetName, "F")
	f.RemoveRow(sheetName, 7)

	//查找
	fmt.Println(f.SearchSheet(sheetName, "200", true))
	fmt.Println(f.SearchSheet(sheetName, "^[0-9]{1,3}$", true))

	// 修改sheet页的名称
	f.SetSheetName(sheetName, "新的名称")

	// go数据类型添加到excel中  其中的基础数据类型,string,int,float,bool 都可以直接通过设置指定单元格的值实现
	// 下面演示数组,切片以及map格式的数据写入excel
	var arr = []interface{}{
		"姓名", "性别", "年龄", "工作",
	}

	idx := f.NewSheet("data")
	// 数据必须是 []interface{} 类型的
	err := f.SetSheetRow("data", "A1", &arr)
	if err != nil {
		fmt.Println(err)
	}
	f.SetActiveSheet(idx)

	// 行列索引转换为单元格索引
	fmt.Println(excelize.JoinCellName("A", 10))
	// 单元格索引拆分行、列索引
	fmt.Println(excelize.SplitCellName("AA10"))

	// 设置多个单元格的公式,相当于在excel中通过拖拉复制公式
	data := [][]float64{{10.5, 20.5}, {18, 28}, {100, 900}}
	for i, d := range data {
		startCell, _ := excelize.JoinCellName("A", i+2)
		f.SetSheetRow("data", startCell, &d)
	}
	// 定义需要设置公式的所有单元格范围
	f_type, ref := excelize.STCellFormulaTypeShared, "C2:C4"

	// 相当于设置计算公式的模板
	if err := f.SetCellFormula("data", "C2", "=SUM(A2:B2)", excelize.FormulaOpts{Type: &f_type, Ref: &ref}); err != nil {
		fmt.Println(err)
	}

	// 合并单元格
	if err := f.MergeCell("data", "D1", "G6"); err != nil {
		fmt.Println(err)
	}
	mergedCells, err := f.GetMergeCells("data")
	if err != nil {
		fmt.Println(err)
	}

	// 获取合并单元格的值以及合并单元格的起止位置
	for _, cell := range mergedCells {
		fmt.Println(cell.GetStartAxis())
		fmt.Println(cell.GetEndAxis())
		fmt.Println(cell.GetCellValue())
	}

	v, err := f.GetCellValue("data", "F3")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("合并单元格中的数据值是:", v)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liyinchi1988

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值