Go-Excelize API 源码阅读(二十三)——SetDocProps、GetDocProps
- 2022-10-15 湖北
本文字数:3469 字
阅读完需:约 1 分钟
Go-Excelize API 源码阅读(二十三)——SetDocProps、GetDocProps
一、Go-Excelize 简介
Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带有样式、图片(表)、透视表、切片器等复杂组件的文档,并提供流式读写 API,用于处理包含大规模数据的工作簿。可应用于各类报表平台、云计算、边缘计算等系统。使用本类库要求使用的 Go 语言为 1.15 或更高版本。
二、 SetDocProps(docProperties *DocProperties)
func (f *File) SetDocProps(docProperties *DocProperties) error
设置工作簿的核心属性。可以设置的属性包括:
下面举一个使用例子:
err := f.SetDocProps(&excelize.DocProperties{
Category: "category",
ContentStatus: "Draft",
Created: "2019-06-04T22:00:10Z",
Creator: "Go Excelize",
Description: "This file created by Go Excelize",
Identifier: "xlsx",
Keywords: "Spreadsheet",
LastModifiedBy: "Go Author",
Modified: "2019-06-04T22:00:10Z",
Revision: "0",
Subject: "Test Subject",
Title: "Test Title",
Language: "en-US",
Version: "1.0.0",
})
然后直接上源码:
func (f *File) SetDocProps(docProperties *DocProperties) (err error) {
var (
core *decodeCoreProperties
newProps *xlsxCoreProperties
fields []string
output []byte
immutable, mutable reflect.Value
field, val string
)
core = new(decodeCoreProperties)
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
Decode(core); err != nil && err != io.EOF {
err = fmt.Errorf("xml decode error: %s", err)
return
}
newProps, err = &xlsxCoreProperties{
Dc: NameSpaceDublinCore,
Dcterms: NameSpaceDublinCoreTerms,
Dcmitype: NameSpaceDublinCoreMetadataInitiative,
XSI: NameSpaceXMLSchemaInstance,
Title: core.Title,
Subject: core.Subject,
Creator: core.Creator,
Keywords: core.Keywords,
Description: core.Description,
LastModifiedBy: core.LastModifiedBy,
Language: core.Language,
Identifier: core.Identifier,
Revision: core.Revision,
ContentStatus: core.ContentStatus,
Category: core.Category,
Version: core.Version,
}, nil
if core.Created != nil {
newProps.Created = &xlsxDcTerms{Type: core.Created.Type, Text: core.Created.Text}
}
if core.Modified != nil {
newProps.Modified = &xlsxDcTerms{Type: core.Modified.Type, Text: core.Modified.Text}
}
fields = []string{
"Category", "ContentStatus", "Creator", "Description", "Identifier", "Keywords",
"LastModifiedBy", "Revision", "Subject", "Title", "Language", "Version",
}
immutable, mutable = reflect.ValueOf(*docProperties), reflect.ValueOf(newProps).Elem()
for _, field = range fields {
if val = immutable.FieldByName(field).String(); val != "" {
mutable.FieldByName(field).SetString(val)
}
}
if docProperties.Created != "" {
newProps.Created = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Created}
}
if docProperties.Modified != "" {
newProps.Modified = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Modified}
}
output, err = xml.Marshal(newProps)
f.saveFileList(defaultXMLPathDocPropsCore, output)
return
}
这个 API 的实现看起来很复杂,我们来对他进行拆解:
core = new(decodeCoreProperties)
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
Decode(core); err != nil && err != io.EOF {
err = fmt.Errorf("xml decode error: %s", err)
return
}
这部分的作用是对 defaultXMLPathDocPropsCore 文件进行读取,即 docProps/core.xml 文件:
defaultXMLPathDocPropsCore = "docProps/core.xml"
然后对 xml 文件进行解码。
newProps, err = &xlsxCoreProperties{
Dc: NameSpaceDublinCore,
Dcterms: NameSpaceDublinCoreTerms,
Dcmitype: NameSpaceDublinCoreMetadataInitiative,
XSI: NameSpaceXMLSchemaInstance,
Title: core.Title,
Subject: core.Subject,
Creator: core.Creator,
Keywords: core.Keywords,
Description: core.Description,
LastModifiedBy: core.LastModifiedBy,
Language: core.Language,
Identifier: core.Identifier,
Revision: core.Revision,
ContentStatus: core.ContentStatus,
Category: core.Category,
Version: core.Version,
}, nil
if core.Created != nil {
newProps.Created = &xlsxDcTerms{Type: core.Created.Type, Text: core.Created.Text}
}
if core.Modified != nil {
newProps.Modified = &xlsxDcTerms{Type: core.Modified.Type, Text: core.Modified.Text}
}
fields = []string{
"Category", "ContentStatus", "Creator", "Description", "Identifier", "Keywords",
"LastModifiedBy", "Revision", "Subject", "Title", "Language", "Version",
}
immutable, mutable = reflect.ValueOf(*docProperties), reflect.ValueOf(newProps).Elem()
for _, field = range fields {
if val = immutable.FieldByName(field).String(); val != "" {
mutable.FieldByName(field).SetString(val)
}
}
if docProperties.Created != "" {
newProps.Created = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Created}
}
if docProperties.Modified != "" {
newProps.Modified = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Modified}
}
output, err = xml.Marshal(newProps)
f.saveFileList(defaultXMLPathDocPropsCore, output)
将获取的信息创建一个新的 xlsxCoreProperties 结构体。然后将结构体序列化之后保存为配置文件即可。
三、GetDocProps()
下面介绍工作簿的最后一个 API:GetDocProps()
// GetDocProps provides a function to get document core properties.
func (f *File) GetDocProps() (ret *DocProperties, err error) {
core := new(decodeCoreProperties)
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
Decode(core); err != nil && err != io.EOF {
err = fmt.Errorf("xml decode error: %s", err)
return
}
ret, err = &DocProperties{
Category: core.Category,
ContentStatus: core.ContentStatus,
Creator: core.Creator,
Description: core.Description,
Identifier: core.Identifier,
Keywords: core.Keywords,
LastModifiedBy: core.LastModifiedBy,
Revision: core.Revision,
Subject: core.Subject,
Title: core.Title,
Language: core.Language,
Version: core.Version,
}, nil
if core.Created != nil {
ret.Created = core.Created.Text
}
if core.Modified != nil {
ret.Modified = core.Modified.Text
}
return
}
逻辑很简单,读取并解码 xml 文件,将获得的结果 core 中的变量放入 ret,其也是一个 DocProperties 结构体,最后返回即可。
版权声明: 本文为 InfoQ 作者【Regan Yue】的原创文章。
原文链接:【http://xie.infoq.cn/article/ccd98e42535968e950b5a1a5c】。文章转载请联系作者。
Regan Yue
还未添加个人签名 2020-08-12 加入
对Go、Python、网络安全、区块链感兴趣. · 华为云云享专家 · 掘金资讯创作者
评论