• 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)
    
    • 1
    • 2

    直接上手读源码

    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    此函数应该是给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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

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

    嗯,我们继续。

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

    这里调用了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()
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

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

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

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

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

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

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

  • 相关阅读:
    dubbo:从零理解及搭建dubbo微服务框架(一)【附带源码】
    《C++ Primer Plus》学习笔记——第5章 循环和文本输入
    含文档+PPT+源码等]精品基于Uniapp+SSM实现的定制旅游APP[包运行成功]SSM毕业设计安卓项目源码
    使用ollama,MacOS也能轻松玩转大语言模型
    程序包org.apache.commons.XXX不存在
    springboot 结合easyexcel实现动态表头的方法
    新文件覆盖旧文件还能复原吗,3个方法快速恢复覆盖文件!
    【Qt】【CMake】-CMakelists.txt-编译错误:No SOURCES given to target: project
    数模国赛:四川赛区即将线上答辩
    java游戏制作-拼图游戏
  • 原文地址:https://blog.csdn.net/qq_36045898/article/details/126048253