Go-Excelize API源码阅读(七)—— CopySheet(from, to int)

Go-Excelize API源码阅读(七)—— CopySheet(from, to int)

开源摘星计划(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 或更高版本。

二、CopySheet(from, to int)、

func (f *File) CopySheet(from, to int) error

该API的作用是提供了一个通过给出的源工作表和目标工作表索引来复制工作表的功能,此索引需要开发者自行确认是否存在。注意,目前不支持复制包含表格、图表或图片的工作簿,仅支持包含单元格值以及公式的工作表复制。

使用案例:

sheet_index := f.NewSheet("Sheet2")
err := f.CopySheet(1, sheet_index)

直接上手读源码:

func (f *File) CopySheet(from, to int) error {
	if from < 0 || to < 0 || from == to || f.GetSheetName(from) == "" || f.GetSheetName(to) == "" {
		return ErrSheetIdx
	}
	return f.copySheet(from, to)
}

此函数应该是给copySheet过滤一些索引错误的情况。比如:

  1. 源工作表索引小于0或目标工作表索引小于0。
  2. 源工作表索引等于目标工作表索引。
  3. 源工作表不存在或者目标工作表不存在

然后调用copySheet

接下来直接读copySheet的源码:

unc (f *File) copySheet(from, to int) error {
	fromSheet := f.GetSheetName(from)
	sheet, err := f.workSheetReader(fromSheet)
	if err != nil {
		return err
	}
	worksheet := deepcopy.Copy(sheet).(*xlsxWorksheet)
	toSheetID := strconv.Itoa(f.getSheetID(f.GetSheetName(to)))
	sheetXMLPath := "xl/worksheets/sheet" + toSheetID + ".xml"
	if len(worksheet.SheetViews.SheetView) > 0 {
		worksheet.SheetViews.SheetView[0].TabSelected = false
	}
	worksheet.Drawing = nil
	worksheet.TableParts = nil
	worksheet.PageSetUp = nil
	f.Sheet.Store(sheetXMLPath, worksheet)
	toRels := "xl/worksheets/_rels/sheet" + toSheetID + ".xml.rels"
	fromRels := "xl/worksheets/_rels/sheet" + strconv.Itoa(f.getSheetID(fromSheet)) + ".xml.rels"
	if rels, ok := f.Pkg.Load(fromRels); ok && rels != nil {
		f.Pkg.Store(toRels, rels.([]byte))
	}
	fromSheetXMLPath := f.sheetMap[trimSheetName(fromSheet)]
	fromSheetAttr := f.xmlAttr[fromSheetXMLPath]
	f.xmlAttr[sheetXMLPath] = fromSheetAttr
	return err
}

看第一部分:
在这里插入图片描述
这部分是获取源工作表名字,然后读取源工作表。

嗯,我们继续。

worksheet := deepcopy.Copy(sheet).(*xlsxWorksheet)

这里调用了github.com/mohae/deepcopy包。

func Copy(src interface{}) interface{} {
	if src == nil {
		return nil
	}

	// Make the interface a reflect.Value
	original := reflect.ValueOf(src)

	// Make a copy of the same type as the original.
	cpy := reflect.New(original.Type()).Elem()

	// Recursively copy the original.
	copyRecursive(original, cpy)

	// Return the copy as an interface.
	return cpy.Interface()
}

Copy将传递给它的对象创建一个深度拷贝,并在一个interface {}中返回该拷贝。 返回的值将需要被断言为正确的类型。

在这里插入图片描述
接下来是获取目标工作表ID,并拼凑目标工作表XML路径。
在这里插入图片描述
如果xml文件中SheetView参数所对应的sheetView长度大于0,这个参数是[]xlsxSheetView类型,应该是工作表视图集合。此处当视图个数大于0,就将第1个视图的TabSelected 参数置为false.
TabSelected找了找微软的文档,没有说明是干什么用的。此处笔者猜测是点击一下单元格时强调的那个框框对应的参数。

接下来是给深拷贝过来的工作表的三个参数初始化。
然后以sheetXMLPath为键,worksheet为值,存入目标工作表Map:Sheet

在这里插入图片描述
这部分是处理rels文件的拷贝。

在这里插入图片描述
此处应是拷贝工作表的属性。

三、结语
这里是老岳,这是Go语言相关源码的解读第七篇,我会不断努力,给大家带来更多类似的文章,恳请大家不吝赐教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ReganYue

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

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

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

打赏作者

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

抵扣说明:

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

余额充值