Go-Excelize API源码阅读(四)——Save()、SaveAs(name string)

2022-07-30 10:53:46 浏览数 (1)

Go-Excelize API源码阅读(四)——Save()

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

二、Save()

func (f *File) Save() error 使用 Save 保存对 Excel 文档的编辑。

代码语言:javascript复制
func (f *File) Save() error {
	if f.Path == "" {
		return ErrSave
	}
	if f.options != nil {
		return f.SaveAs(f.Path, *f.options)
	}
	return f.SaveAs(f.Path)
}

Save 可以用于在源路径覆盖电子表格。 第一个if判断,是判断要保存的路径是否为空,如果为空就返回ErrSave。

代码语言:javascript复制
	// ErrSave defined the error message for saving file.
	ErrSave = errors.New("no path defined for file, consider File.WriteTo or File.Write")

该项目将错误放置在errors.go中。ErrSave是保存文件时发生错误的错误消息。

接下来的if判断:

代码语言:javascript复制
	if f.options != nil {
		return f.SaveAs(f.Path, *f.options)
	}

当文件结构体的options 成员不为空时,保存文件需要考虑options的信息。 如果为空就不需要考虑。

三、SaveAs(name string)

至于SaveAs(name string),我们来看看: 使用 SaveAs 保存 Excel 文档为指定文件。

代码语言:javascript复制
func (f *File) SaveAs(name string, opt ...Options) error {
	if len(name) > MaxFilePathLength {
		return ErrMaxFilePathLength
	}
	f.Path = name
	contentType, ok := map[string]string{
		".xlam": ContentTypeAddinMacro,
		".xlsm": ContentTypeMacro,
		".xlsx": ContentTypeSheetML,
		".xltm": ContentTypeTemplateMacro,
		".xltx": ContentTypeTemplate,
	}[filepath.Ext(f.Path)]
	if !ok {
		return ErrWorkbookFileFormat
	}
	f.setContentTypePartProjectExtensions(contentType)
	file, err := os.OpenFile(filepath.Clean(name), os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)
	if err != nil {
		return err
	}
	defer file.Close()
	f.options = nil
	for i := range opt {
		f.options = &opt[i]
	}
	return f.Write(file)
}

第一个if:

代码语言:javascript复制
	if len(name) > MaxFilePathLength {
		return ErrMaxFilePathLength
	}

用来判断文件名长度是不是合法。

文件错误信息如下:

接下来是根据文件的扩展名确定内容类型:

代码语言:javascript复制
	contentType, ok := map[string]string{
		".xlam": ContentTypeAddinMacro,
		".xlsm": ContentTypeMacro,
		".xlsx": ContentTypeSheetML,
		".xltm": ContentTypeTemplateMacro,
		".xltx": ContentTypeTemplate,
	}[filepath.Ext(f.Path)]

这段的写法可以学习。。。至于其内容下图可见。。。

setContentTypePartProjectExtensions()将获取到的contentType赋给文档关系部分和主文档部分。 然后打开文件写入f文件流。

os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm 这个要介绍一下:

os.O_APPEND:当向文件中写入内容时,把新内容追加到现有内容的后边。 os.O_CREATE:当给定路径上的文件不存在时,创建一个新文件。 os.O_EXCL:需要与os.O_CREATE一同使用,表示在给定的路径上不能有已存在的文件。 os.O_SYNC:在打开的文件之上实施同步 I/O。它会保证读写的内容总会与硬盘上的数据保持同步。 os.O_TRUNC:如果文件已存在,并且是常规的文件,那么就先清空其中已经存在的任何内容。

os.O_WRONLY | os.O_CREATE | O_EXCL 【如果已经存在,则失败】 os.O_WRONLY | os.O_CREATE 【如果已经存在,会覆盖写,不会清空原来的文件,而是从头直接覆盖写】 os.O_WRONLY | os.O_CREATE | os.O_APPEND 【如果已经存在,则在尾部添加写】

0 人点赞