forked from p30928647/excelize
This closes #1095, support to set and get document application properties
This commit is contained in:
parent
089cd365a3
commit
6b1e592cbc
|
@ -23,7 +23,7 @@ Excelize is a library written in pure Go providing a set of functions that allow
|
|||
go get github.com/xuri/excelize
|
||||
```
|
||||
|
||||
- If your packages are managed using [Go Modules](https://blog.golang.org/using-go-modules), please install with following command.
|
||||
- If your packages are managed using [Go Modules](https://go.dev/blog/using-go-modules), please install with following command.
|
||||
|
||||
```bash
|
||||
go get github.com/xuri/excelize/v2
|
||||
|
|
|
@ -23,7 +23,7 @@ Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基
|
|||
go get github.com/xuri/excelize
|
||||
```
|
||||
|
||||
- 如果您使用 [Go Modules](https://blog.golang.org/using-go-modules) 管理软件包,请使用下面的命令来安装最新版本。
|
||||
- 如果您使用 [Go Modules](https://go.dev/blog/using-go-modules) 管理软件包,请使用下面的命令来安装最新版本。
|
||||
|
||||
```bash
|
||||
go get github.com/xuri/excelize/v2
|
||||
|
|
1
calc.go
1
calc.go
|
@ -626,6 +626,7 @@ type formulaFuncs struct {
|
|||
// WEIBULL
|
||||
// WEIBULL.DIST
|
||||
// XIRR
|
||||
// XLOOKUP
|
||||
// XNPV
|
||||
// XOR
|
||||
// YEAR
|
||||
|
|
100
docProps.go
100
docProps.go
|
@ -19,6 +19,106 @@ import (
|
|||
"reflect"
|
||||
)
|
||||
|
||||
// SetAppProps provides a function to set document application properties. The
|
||||
// properties that can be set are:
|
||||
//
|
||||
// Property | Description
|
||||
// -------------------+--------------------------------------------------------------------------
|
||||
// Application | The name of the application that created this document.
|
||||
// |
|
||||
// ScaleCrop | Indicates the display mode of the document thumbnail. Set this element
|
||||
// | to TRUE to enable scaling of the document thumbnail to the display. Set
|
||||
// | this element to FALSE to enable cropping of the document thumbnail to
|
||||
// | show only sections that will fit the display.
|
||||
// |
|
||||
// DocSecurity | Security level of a document as a numeric value. Document security is
|
||||
// | defined as:
|
||||
// | 1 - Document is password protected.
|
||||
// | 2 - Document is recommended to be opened as read-only.
|
||||
// | 3 - Document is enforced to be opened as read-only.
|
||||
// | 4 - Document is locked for annotation.
|
||||
// |
|
||||
// Company | The name of a company associated with the document.
|
||||
// |
|
||||
// LinksUpToDate | Indicates whether hyperlinks in a document are up-to-date. Set this
|
||||
// | element to TRUE to indicate that hyperlinks are updated. Set this
|
||||
// | element to FALSE to indicate that hyperlinks are outdated.
|
||||
// |
|
||||
// HyperlinksChanged | Specifies that one or more hyperlinks in this part were updated
|
||||
// | exclusively in this part by a producer. The next producer to open this
|
||||
// | document shall update the hyperlink relationships with the new
|
||||
// | hyperlinks specified in this part.
|
||||
// |
|
||||
// AppVersion | Specifies the version of the application which produced this document.
|
||||
// | The content of this element shall be of the form XX.YYYY where X and Y
|
||||
// | represent numerical values, or the document shall be considered
|
||||
// | non-conformant.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// err := f.SetAppProps(&excelize.AppProperties{
|
||||
// Application: "Microsoft Excel",
|
||||
// ScaleCrop: true,
|
||||
// DocSecurity: 3,
|
||||
// Company: "Company Name",
|
||||
// LinksUpToDate: true,
|
||||
// HyperlinksChanged: true,
|
||||
// AppVersion: "16.0000",
|
||||
// })
|
||||
//
|
||||
func (f *File) SetAppProps(appProperties *AppProperties) (err error) {
|
||||
var (
|
||||
app *xlsxProperties
|
||||
fields []string
|
||||
output []byte
|
||||
immutable, mutable reflect.Value
|
||||
field string
|
||||
)
|
||||
app = new(xlsxProperties)
|
||||
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML("docProps/app.xml")))).
|
||||
Decode(app); err != nil && err != io.EOF {
|
||||
err = fmt.Errorf("xml decode error: %s", err)
|
||||
return
|
||||
}
|
||||
fields = []string{"Application", "ScaleCrop", "DocSecurity", "Company", "LinksUpToDate", "HyperlinksChanged", "AppVersion"}
|
||||
immutable, mutable = reflect.ValueOf(*appProperties), reflect.ValueOf(app).Elem()
|
||||
for _, field = range fields {
|
||||
immutableField := immutable.FieldByName(field)
|
||||
switch immutableField.Kind() {
|
||||
case reflect.Bool:
|
||||
mutable.FieldByName(field).SetBool(immutableField.Bool())
|
||||
case reflect.Int:
|
||||
mutable.FieldByName(field).SetInt(immutableField.Int())
|
||||
default:
|
||||
mutable.FieldByName(field).SetString(immutableField.String())
|
||||
}
|
||||
}
|
||||
app.Vt = NameSpaceDocumentPropertiesVariantTypes.Value
|
||||
output, err = xml.Marshal(app)
|
||||
f.saveFileList("docProps/app.xml", output)
|
||||
return
|
||||
}
|
||||
|
||||
// GetAppProps provides a function to get document application properties.
|
||||
func (f *File) GetAppProps() (ret *AppProperties, err error) {
|
||||
var app = new(xlsxProperties)
|
||||
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML("docProps/app.xml")))).
|
||||
Decode(app); err != nil && err != io.EOF {
|
||||
err = fmt.Errorf("xml decode error: %s", err)
|
||||
return
|
||||
}
|
||||
ret, err = &AppProperties{
|
||||
Application: app.Application,
|
||||
ScaleCrop: app.ScaleCrop,
|
||||
DocSecurity: app.DocSecurity,
|
||||
Company: app.Company,
|
||||
LinksUpToDate: app.LinksUpToDate,
|
||||
HyperlinksChanged: app.HyperlinksChanged,
|
||||
AppVersion: app.AppVersion,
|
||||
}, nil
|
||||
return
|
||||
}
|
||||
|
||||
// SetDocProps provides a function to set document core properties. The
|
||||
// properties that can be set are:
|
||||
//
|
||||
|
|
|
@ -20,6 +20,51 @@ import (
|
|||
|
||||
var MacintoshCyrillicCharset = []byte{0x8F, 0xF0, 0xE8, 0xE2, 0xE5, 0xF2, 0x20, 0xEC, 0xE8, 0xF0}
|
||||
|
||||
func TestSetAppProps(t *testing.T) {
|
||||
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
||||
if !assert.NoError(t, err) {
|
||||
t.FailNow()
|
||||
}
|
||||
assert.NoError(t, f.SetAppProps(&AppProperties{
|
||||
Application: "Microsoft Excel",
|
||||
ScaleCrop: true,
|
||||
DocSecurity: 3,
|
||||
Company: "Company Name",
|
||||
LinksUpToDate: true,
|
||||
HyperlinksChanged: true,
|
||||
AppVersion: "16.0000",
|
||||
}))
|
||||
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetAppProps.xlsx")))
|
||||
f.Pkg.Store("docProps/app.xml", nil)
|
||||
assert.NoError(t, f.SetAppProps(&AppProperties{}))
|
||||
assert.NoError(t, f.Close())
|
||||
|
||||
// Test unsupported charset
|
||||
f = NewFile()
|
||||
f.Pkg.Store("docProps/app.xml", MacintoshCyrillicCharset)
|
||||
assert.EqualError(t, f.SetAppProps(&AppProperties{}), "xml decode error: XML syntax error on line 1: invalid UTF-8")
|
||||
}
|
||||
|
||||
func TestGetAppProps(t *testing.T) {
|
||||
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
||||
if !assert.NoError(t, err) {
|
||||
t.FailNow()
|
||||
}
|
||||
props, err := f.GetAppProps()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, props.Application, "Microsoft Macintosh Excel")
|
||||
f.Pkg.Store("docProps/app.xml", nil)
|
||||
_, err = f.GetAppProps()
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, f.Close())
|
||||
|
||||
// Test unsupported charset
|
||||
f = NewFile()
|
||||
f.Pkg.Store("docProps/app.xml", MacintoshCyrillicCharset)
|
||||
_, err = f.GetAppProps()
|
||||
assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
|
||||
}
|
||||
|
||||
func TestSetDocProps(t *testing.T) {
|
||||
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
||||
if !assert.NoError(t, err) {
|
||||
|
|
BIN
test/Book1.xlsx
BIN
test/Book1.xlsx
Binary file not shown.
58
xmlApp.go
58
xmlApp.go
|
@ -13,38 +13,50 @@ package excelize
|
|||
|
||||
import "encoding/xml"
|
||||
|
||||
// AppProperties directly maps the document application properties.
|
||||
type AppProperties struct {
|
||||
Application string
|
||||
ScaleCrop bool
|
||||
DocSecurity int
|
||||
Company string
|
||||
LinksUpToDate bool
|
||||
HyperlinksChanged bool
|
||||
AppVersion string
|
||||
}
|
||||
|
||||
// xlsxProperties specifies to an OOXML document properties such as the
|
||||
// template used, the number of pages and words, and the application name and
|
||||
// version.
|
||||
type xlsxProperties struct {
|
||||
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties Properties"`
|
||||
Template string
|
||||
Manager string
|
||||
Company string
|
||||
Pages int
|
||||
Words int
|
||||
Characters int
|
||||
PresentationFormat string
|
||||
Lines int
|
||||
Paragraphs int
|
||||
Slides int
|
||||
Notes int
|
||||
TotalTime int
|
||||
HiddenSlides int
|
||||
MMClips int
|
||||
ScaleCrop bool
|
||||
Vt string `xml:"xmlns:vt,attr"`
|
||||
Template string `xml:",omitempty"`
|
||||
Manager string `xml:",omitempty"`
|
||||
Company string `xml:",omitempty"`
|
||||
Pages int `xml:",omitempty"`
|
||||
Words int `xml:",omitempty"`
|
||||
Characters int `xml:",omitempty"`
|
||||
PresentationFormat string `xml:",omitempty"`
|
||||
Lines int `xml:",omitempty"`
|
||||
Paragraphs int `xml:",omitempty"`
|
||||
Slides int `xml:",omitempty"`
|
||||
Notes int `xml:",omitempty"`
|
||||
TotalTime int `xml:",omitempty"`
|
||||
HiddenSlides int `xml:",omitempty"`
|
||||
MMClips int `xml:",omitempty"`
|
||||
ScaleCrop bool `xml:",omitempty"`
|
||||
HeadingPairs *xlsxVectorVariant
|
||||
TitlesOfParts *xlsxVectorLpstr
|
||||
LinksUpToDate bool
|
||||
CharactersWithSpaces int
|
||||
SharedDoc bool
|
||||
HyperlinkBase string
|
||||
LinksUpToDate bool `xml:",omitempty"`
|
||||
CharactersWithSpaces int `xml:",omitempty"`
|
||||
SharedDoc bool `xml:",omitempty"`
|
||||
HyperlinkBase string `xml:",omitempty"`
|
||||
HLinks *xlsxVectorVariant
|
||||
HyperlinksChanged bool
|
||||
HyperlinksChanged bool `xml:",omitempty"`
|
||||
DigSig *xlsxDigSig
|
||||
Application string
|
||||
AppVersion string
|
||||
DocSecurity int
|
||||
Application string `xml:",omitempty"`
|
||||
AppVersion string `xml:",omitempty"`
|
||||
DocSecurity int `xml:",omitempty"`
|
||||
}
|
||||
|
||||
// xlsxVectorVariant specifies the set of hyperlinks that were in this
|
||||
|
|
|
@ -32,6 +32,7 @@ var (
|
|||
NameSpaceSpreadSheetX15 = xml.Attr{Name: xml.Name{Local: "x15", Space: "xmlns"}, Value: "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"}
|
||||
NameSpaceSpreadSheetExcel2006Main = xml.Attr{Name: xml.Name{Local: "xne", Space: "xmlns"}, Value: "http://schemas.microsoft.com/office/excel/2006/main"}
|
||||
NameSpaceMacExcel2008Main = xml.Attr{Name: xml.Name{Local: "mx", Space: "xmlns"}, Value: "http://schemas.microsoft.com/office/mac/excel/2008/main"}
|
||||
NameSpaceDocumentPropertiesVariantTypes = xml.Attr{Name: xml.Name{Local: "vt", Space: "xmlns"}, Value: "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"}
|
||||
)
|
||||
|
||||
// Source relationship and namespace.
|
||||
|
@ -50,6 +51,7 @@ const (
|
|||
SourceRelationshipPivotTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable"
|
||||
SourceRelationshipPivotCache = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition"
|
||||
SourceRelationshipSharedStrings = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"
|
||||
|
||||
SourceRelationshipVBAProject = "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
|
||||
NameSpaceXML = "http://www.w3.org/XML/1998/namespace"
|
||||
NameSpaceXMLSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
|
|
Loading…
Reference in New Issue