开发者社区> reganyue> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

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

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

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

二、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 << 24
StreamChunkSize = 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语言相关源码的解读第三篇,我会不断努力,给大家带来更多类似的文章,恳请大家不吝赐教。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
指数退避(Exponential backoff)在网络请求中的应用
## 一、背景 最近做云服务 API 测试项目的过程中,发现某些时候会大批量调用 API,从而导致限流的报错。在遇到这种报错时,传统的重试策略是每隔一段时间重试一次。但由于是固定的时间重试一次,重试时又会有大量的请求在同一时刻涌入,会不断地造成限流。 这让我回想起两年前在查阅[Celery Task 文档](http://docs.celeryproject.org/en/latest
3546 0
jdk11源码--ReentrantReadWriteLock源码
jdk11 ReentrantReadWriteLock 源码分析
634 0
java源码 - ReentrantReadWriteLock写锁介绍
开篇  这篇文章主要从源码角度讲解ReentrantReadWriteLock的WriteLock的加锁和减锁过程。  ReentrantReadWriteLock的WriteLock加锁解锁过程依赖于AbstractQueuedSynchronizer(AQS)类,所以有些相同的逻辑可以看看ReentrantLock的逻辑。
941 0
视频人脸检测——OpenCV版(三)
视频人脸检测是图片人脸检测的高级版本,图片检测详情点击查看我的上一篇《图片人脸检测——OpenCV版(二)》    往期目录   视频人脸检测——Dlib版(六)OpenCV添加中文(五)图片人脸检测——Dlib版(四)视频人脸检测——OpenCV版(三)图片人脸检测——OpenCV版(二)OpenCV环境搭建(一)更多更新,欢迎访问我的github:https://github.com/vipstone/faceai 实现思路: 调用电脑的摄像头,把摄像的信息逐帧分解成图片,基于图片检测标识出人脸的位置,把处理的图片逐帧绘制给用户,用户看到的效果就是视频的人脸检测。
2599 0
opencvbase 实现opencv打开摄像头和初步处理等效果操作(附源码)
// TwoCameraOnTimer2Dlg.cpp : 实现文件 /* CvMat, Mat, IplImage之间的互相转换 IpIImage -> CvMat CvMat matheader; CvMat * mat = cvGetMat(img, &matheader...
847 0
OAF_OAF OAWebBean和OAPageContext的分析(概念)
2015-04-03 Created By BaoXinjian  一、摘要 OAPageContext provides access to objects like AM class, page parameters, session values, navigation methods.
844 0
OpenCV学习(12) 图像的腐蚀与膨胀(3)
通过使用不同的结构元素来进行膨胀腐蚀操作,可以检测图像中的角点,下面就一步一步看这个算法如果实现角点检测。 原图像: 首先我们创建四个结构元素 先用十字结构元素对原图像进行膨胀操作,得到下面的图像 再对这个图像用钻石型结构元素进行腐蚀操作,得到图像1,如下图所示: 接着...
871 0
+关注
65
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载