当前位置: 首页 > news >正文

Go-Excelize API源码阅读(二十七)——SetRowOutlineLevel、SetColOutlineLevel

Go-Excelize API源码阅读(二十七)——SetRowOutlineLevel、SetColOutlineLevel

开源摘星计划(WeOpen Star) 是由腾源会 2022 年推出的全新项目,旨在为开源人提供成长激励,为开源项目提供成长支持,助力开发者更好地了解开源,更快地跨越鸿沟,参与到开源的具体贡献与实践中。

不管你是开源萌新,还是希望更深度参与开源贡献的老兵,跟随“开源摘星计划”开启你的开源之旅,从一篇学习笔记、到一段代码的提交,不断挖掘自己的潜能,最终成长为开源社区的“闪亮之星”。

我们将同你一起,探索更多的可能性!

项目地址: WeOpen-Star:https://github.com/weopenprojects/WeOpen-Star

一、Go-Excelize简介

Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带有样式、图片(表)、透视表、切片器等复杂组件的文档,并提供流式读写 API,用于处理包含大规模数据的工作簿。可应用于各类报表平台、云计算、边缘计算等系统。使用本类库要求使用的 Go 语言为 1.15 或更高版本。

二、SetRowOutlineLevel(sheet string, row int, level uint8)

func (f *File) SetRowOutlineLevel(sheet string, row int, level uint8) error

根据给定的工作表名称、行号和分级参数创建组。例如,在名为 Sheet1 的工作表的第 2 行创建 1 级分组。
在这里插入图片描述

err := f.SetRowOutlineLevel("Sheet1", 2, 1)

我们来看源码:

// SetRowOutlineLevel provides a function to set outline level number of a
// single row by given worksheet name and Excel row number. The value of
// parameter 'level' is 1-7. For example, outline row 2 in Sheet1 to level 1:
//
//    err := f.SetRowOutlineLevel("Sheet1", 2, 1)
//
func (f *File) SetRowOutlineLevel(sheet string, row int, level uint8) error {
	if row < 1 {
		return newInvalidRowNumberError(row)
	}
	if level > 7 || level < 1 {
		return ErrOutlineLevel
	}
	ws, err := f.workSheetReader(sheet)
	if err != nil {
		return err
	}
	prepareSheetXML(ws, 0, row)
	ws.SheetData.Row[row-1].OutlineLevel = level
	return nil
}

如果行号row小于1,就返回newInvalidRowNumberError(row)

// newInvalidRowNumberError defined the error message on receiving the invalid
// row number.
func newInvalidRowNumberError(row int) error {
	return fmt.Errorf("invalid row number %d", row)
}
if level > 7 || level < 1 {
	return ErrOutlineLevel
}

如果level小于1或者大于7,就返回ErrOutlineLevel

	// ErrOutlineLevel defined the error message on receive an invalid outline
	// level number.
	ErrOutlineLevel = errors.New("invalid outline level")
	prepareSheetXML(ws, 0, row)
	ws.SheetData.Row[row-1].OutlineLevel = level
	return nil
func prepareSheetXML(ws *xlsxWorksheet, col int, row int) {
	ws.Lock()
	defer ws.Unlock()
	rowCount := len(ws.SheetData.Row)
	sizeHint := 0
	var ht float64
	var customHeight bool
	if ws.SheetFormatPr != nil && ws.SheetFormatPr.CustomHeight {
		ht = ws.SheetFormatPr.DefaultRowHeight
		customHeight = true
	}
	if rowCount > 0 {
		sizeHint = len(ws.SheetData.Row[rowCount-1].C)
	}
	if rowCount < row {
		// append missing rows
		for rowIdx := rowCount; rowIdx < row; rowIdx++ {
			ws.SheetData.Row = append(ws.SheetData.Row, xlsxRow{R: rowIdx + 1, CustomHeight: customHeight, Ht: ht, C: make([]xlsxC, 0, sizeHint)})
		}
	}
	rowData := &ws.SheetData.Row[row-1]
	fillColumns(rowData, col, row)
}

prepareSheetXML确保有足够的行,以及所选择的行中的列来接受数据。缺少的行会被回填,并给出它们的行号。我们以最后填充的行作为提示,以确定下一个行的大小。

ws.SheetData.Row[row-1].OutlineLevel = level

将该行的OutlineLevel属性设置为level。

三、SetColOutlineLevel(sheet, col string, level uint8)

func (f *File) SetColOutlineLevel(sheet, col string, level uint8) error

根据给定的工作表名称、列名称和分级参数创建组。例如,在名为 Sheet1 的工作表的 D 列创建 2 级分组。
在这里插入图片描述

err := f.SetColOutlineLevel("Sheet1", "D", 2)

现在来看看源码:

func (f *File) SetColOutlineLevel(sheet, col string, level uint8) error {
	if level > 7 || level < 1 {
		return ErrOutlineLevel
	}
	colNum, err := ColumnNameToNumber(col)
	if err != nil {
		return err
	}
	colData := xlsxCol{
		Min:          colNum,
		Max:          colNum,
		OutlineLevel: level,
		CustomWidth:  true,
	}
	ws, err := f.workSheetReader(sheet)
	if err != nil {
		return err
	}
	if ws.Cols == nil {
		cols := xlsxCols{}
		cols.Col = append(cols.Col, colData)
		ws.Cols = &cols
		return err
	}
	ws.Cols.Col = flatCols(colData, ws.Cols.Col, func(fc, c xlsxCol) xlsxCol {
		fc.BestFit = c.BestFit
		fc.Collapsed = c.Collapsed
		fc.CustomWidth = c.CustomWidth
		fc.Hidden = c.Hidden
		fc.Phonetic = c.Phonetic
		fc.Style = c.Style
		fc.Width = c.Width
		return fc
	})
	return err
}

看第一部分:

	if level > 7 || level < 1 {
		return ErrOutlineLevel
	}
	colNum, err := ColumnNameToNumber(col)
	if err != nil {
		return err
	}
	colData := xlsxCol{
		Min:          colNum,
		Max:          colNum,
		OutlineLevel: level,
		CustomWidth:  true,
	}

如果level大于7或者小于1,就会return一个ErrOutlineLevel。

接下来是colNum, err := ColumnNameToNumber(col)

// ColumnNameToNumber provides a function to convert Excel sheet column name
// to int. Column name case-insensitive. The function returns an error if
// column name incorrect.
//
// Example:
//
//     excelize.ColumnNameToNumber("AK") // returns 37, nil
//
func ColumnNameToNumber(name string) (int, error) {
	if len(name) == 0 {
		return -1, newInvalidColumnNameError(name)
	}
	col := 0
	multi := 1
	for i := len(name) - 1; i >= 0; i-- {
		r := name[i]
		if r >= 'A' && r <= 'Z' {
			col += int(r-'A'+1) * multi
		} else if r >= 'a' && r <= 'z' {
			col += int(r-'a'+1) * multi
		} else {
			return -1, newInvalidColumnNameError(name)
		}
		multi *= 26
	}
	if col > MaxColumns {
		return -1, ErrColumnNumber
	}
	return col, nil
}

因为列号是字母,所以我们要讲字母转换为列号,此ColumnNameToNumber(name string)便是将字母列名转换为列号。
创建一个变量名为colData的xlsxCol对象。
看看第二部分:

	ws, err := f.workSheetReader(sheet)
	if err != nil {
		return err
	}
	if ws.Cols == nil {
		cols := xlsxCols{}
		cols.Col = append(cols.Col, colData)
		ws.Cols = &cols
		return err
	}
	ws.Cols.Col = flatCols(colData, ws.Cols.Col, func(fc, c xlsxCol) xlsxCol {
		fc.BestFit = c.BestFit
		fc.Collapsed = c.Collapsed
		fc.CustomWidth = c.CustomWidth
		fc.Hidden = c.Hidden
		fc.Phonetic = c.Phonetic
		fc.Style = c.Style
		fc.Width = c.Width
		return fc
	})
	return err

如果工作簿的列数为空,我们就新建一个xlsxCols对象,然后加入cols.Col
flatCols 用于平铺和检查工作表的列。

相关文章:

  • 详细介绍LinkedList
  • 【SSM】Spring MVC 程序开发(重点:SpringMVC 工作流程)
  • 【以太网硬件十四】以太网的MAC是干什么的?
  • RocketMQ 消费者Rebalance算法 解析——图解、源码级解析
  • 【网络安全】内网杀器之Cobalt Strike
  • 法国1油井反杀苏军2油井经典案例分析
  • 【一年总结】我的大三
  • 【TS系列】TypeScript进阶(三)
  • 动态内存管理
  • Linux05开机/重启/用户登录注销
  • MySQL索引-2聚集索引探讨
  • 【node.js从入门到精通】模块化+npm包详解
  • Android 面试需要哪些准备?
  • Vue进阶--render函数和jsx的使用
  • 嵌入式 Linux 入门(十、Linux 下的 C 编程)
  • Docker: 容器互访的三种方式
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • JS专题之继承
  • leetcode386. Lexicographical Numbers
  • leetcode讲解--894. All Possible Full Binary Trees
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Linux下的乱码问题
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 从重复到重用
  • 排序算法之--选择排序
  • 算法---两个栈实现一个队列
  • 用简单代码看卷积组块发展
  • FaaS 的简单实践
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (2020)Java后端开发----(面试题和笔试题)
  • (39)STM32——FLASH闪存
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (九十四)函数和二维数组
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (一)插入排序
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .Net Web项目创建比较不错的参考文章
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • @FeignClient注解,fallback和fallbackFactory
  • [ C++ ] STL---string类的使用指南
  • [1525]字符统计2 (哈希)SDUT
  • [ASP.NET MVC]Ajax与CustomErrors的尴尬
  • [C]整形提升(转载)
  • [codeforces]Checkpoints
  • [DAX] MAX函数 | MAXX函数
  • [EWS]查找 文件夹
  • [HackMyVM]靶场 Wild
  • [LeetCode][138]【学习日记】深拷贝带有随机指针的链表
  • [MYSQL数据库]- 索引