写点什么

Go-Excelize API 源码阅读(三)——OpenReader()

作者:Regan Yue
  • 2022 年 8 月 07 日
  • 本文字数:1634 字

    阅读完需:约 5 分钟

Go-Excelize API 源码阅读(三)——OpenReader()

一、Go-Excelize 简介

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

二、OpenReader()

func OpenReader(r io.Reader, opt ...Options) (*File, error)OpenReader 的作用是从 io.Reader 读取数据流。


func OpenReader(r io.Reader, opt ...Options) (*File, error) {  b, err := ioutil.ReadAll(r)  if err != nil {    return nil, err  }  f := newFile()  f.options = parseOptions(opt...)  if f.options.UnzipSizeLimit == 0 {    f.options.UnzipSizeLimit = UnzipSizeLimit    if f.options.UnzipXMLSizeLimit > f.options.UnzipSizeLimit {      f.options.UnzipSizeLimit = f.options.UnzipXMLSizeLimit    }  }  if f.options.UnzipXMLSizeLimit == 0 {    f.options.UnzipXMLSizeLimit = StreamChunkSize    if f.options.UnzipSizeLimit < f.options.UnzipXMLSizeLimit {      f.options.UnzipXMLSizeLimit = f.options.UnzipSizeLimit    }  }  if f.options.UnzipXMLSizeLimit > f.options.UnzipSizeLimit {    return nil, ErrOptionsUnzipSizeLimit  }  if bytes.Contains(b, oleIdentifier) {    if b, err = Decrypt(b, f.options); err != nil {      return nil, ErrWorkbookFileFormat    }  }  zr, err := zip.NewReader(bytes.NewReader(b), int64(len(b)))  if err != nil {    if len(f.options.Password) > 0 {      return nil, ErrWorkbookPassword    }    return nil, err  }  file, sheetCount, err := f.ReadZipReader(zr)  if err != nil {    return nil, err  }  f.SheetCount = sheetCount  for k, v := range file {    f.Pkg.Store(k, v)  }  f.CalcChain = f.calcChainReader()  f.sheetMap = f.getSheetMap()  f.Styles = f.stylesReader()  f.Theme = f.themeReader()  return f, nil}
复制代码


ioutil.ReadAll(r)先从 io.Reader 读取整条数据流,newFile()创建一个 Excel 工作薄。


f.options.UnzipSizeLimit: UnzipSizeLimit 指定了打开电子表格时的解压大小限制,以字节为单位,这个值应该大于或等于 UnzipXMLSizeLimit,默认的大小限制是 16GB。


f.options.UnzipXMLSizeLimit:UnzipXMLSizeLimit 指定解压工作表和共享字符串表的内存限制,单位为字节,当文件大小超过此值时,工作表的 XML 将被解压到系统的临时目录中,此值应小于或等于 UnzipSizeLimit,默认值为 16MB。


UnzipSizeLimit = 1000 << 24StreamChunkSize = 1 << 24


然后判断读取的数据流中是不是包含oleIdentifier = []byte{0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1}这是 OLE 程序标识符,具体查看微软文档:https://docs.microsoft.com/zh-cn/office/vba/outlook/concepts/getting-started/ole-programmatic-identifiers-outlook


zip.NewReader 返回一个从 bytes.NewReader(b)读取的新的阅读器,它被赋值为给定的字节大小 int64(len(b))。


f.ReadZipReader(zr)中 ReadZipReader 通过给定的选项提取电子表格。给定的选项主要是密码等:


type Options struct {  MaxCalcIterations uint  Password          string  RawCellValue      bool  UnzipSizeLimit    int64  UnzipXMLSizeLimit int64}
复制代码


后面和新建文件 API 差不多NewFile(),给 f 结构体的成员赋值。


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

发布于: 刚刚阅读数: 2
用户头像

Regan Yue

关注

还未添加个人签名 2020.08.12 加入

对Go、Python、网络安全、区块链感兴趣. · 华为云云享专家 · 掘金资讯创作者

评论

发布
暂无评论
Go-Excelize API源码阅读(三)——OpenReader()_Go_Regan Yue_InfoQ写作社区