当前位置:网站首页>Go-Excelize API源码阅读(七)—— CopySheet(from, to int)

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

2022-08-11 11:00:00 InfoQ

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

一、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) == &quot;&quot; || f.GetSheetName(to) == &quot;&quot; {
 return ErrSheetIdx
 }
 return f.copySheet(from, to)
}

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

  • 源工作表索引小于0或目标工作表索引小于0。
  • 源工作表索引等于目标工作表索引。
  • 源工作表不存在或者目标工作表不存在

然后调用
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 := &quot;xl/worksheets/sheet&quot; + toSheetID + &quot;.xml&quot;
 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 := &quot;xl/worksheets/_rels/sheet&quot; + toSheetID + &quot;.xml.rels&quot;
 fromRels := &quot;xl/worksheets/_rels/sheet&quot; + strconv.Itoa(f.getSheetID(fromSheet)) + &quot;.xml.rels&quot;
 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
}

看第一部分:

null
这部分是获取源工作表名字,然后读取源工作表。

嗯,我们继续。

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 {}中返回该拷贝。 返回的值将需要被断言为正确的类型。

null
接下来是获取目标工作表ID,并拼凑目标工作表XML路径。

null
如果xml文件中SheetView参数所对应的
sheetView
长度大于0,这个参数是[]xlsxSheetView类型,应该是工作表视图集合。此处当视图个数大于0,就将第1个视图的
TabSelected
 参数置为
false
.
TabSelected
找了找微软的文档,没有说明是干什么用的。此处笔者猜测是点击一下单元格时强调的那个框框对应的参数。

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

null
这部分是处理rels文件的拷贝。

null
此处应是拷贝工作表的属性。

三、结语

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

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/283aae650bfaa16f08242442e