Introduce 2 new functions SetCalcProps and GetCalcProps (#2098)
- Add new CalcPropsOptions data type - Support assign exported data structure fields value to internal data structure fields dynamically by specified fields name list - Simplify code for function SetAppProps, SetDocProps, SetWorkbookProps, GetWorkbookProps and getPivotTable - Update unit tests
This commit is contained in:
parent
c6d161fc76
commit
aef20e226c
57
docProps.go
57
docProps.go
|
@ -65,34 +65,15 @@ import (
|
||||||
// AppVersion: "16.0000",
|
// AppVersion: "16.0000",
|
||||||
// })
|
// })
|
||||||
func (f *File) SetAppProps(appProperties *AppProperties) error {
|
func (f *File) SetAppProps(appProperties *AppProperties) error {
|
||||||
var (
|
app := new(xlsxProperties)
|
||||||
app *xlsxProperties
|
if err := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsApp)))).
|
||||||
err error
|
|
||||||
field string
|
|
||||||
fields []string
|
|
||||||
immutable, mutable reflect.Value
|
|
||||||
output []byte
|
|
||||||
)
|
|
||||||
app = new(xlsxProperties)
|
|
||||||
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsApp)))).
|
|
||||||
Decode(app); err != nil && err != io.EOF {
|
Decode(app); err != nil && err != io.EOF {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fields = []string{"Application", "ScaleCrop", "DocSecurity", "Company", "LinksUpToDate", "HyperlinksChanged", "AppVersion"}
|
setNoPtrFieldsVal([]string{"Application", "ScaleCrop", "DocSecurity", "Company", "LinksUpToDate", "HyperlinksChanged", "AppVersion"},
|
||||||
immutable, mutable = reflect.ValueOf(*appProperties), reflect.ValueOf(app).Elem()
|
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
|
app.Vt = NameSpaceDocumentPropertiesVariantTypes.Value
|
||||||
output, err = xml.Marshal(app)
|
output, err := xml.Marshal(app)
|
||||||
f.saveFileList(defaultXMLPathDocPropsApp, output)
|
f.saveFileList(defaultXMLPathDocPropsApp, output)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -180,22 +161,12 @@ func (f *File) GetAppProps() (ret *AppProperties, err error) {
|
||||||
// Version: "1.0.0",
|
// Version: "1.0.0",
|
||||||
// })
|
// })
|
||||||
func (f *File) SetDocProps(docProperties *DocProperties) error {
|
func (f *File) SetDocProps(docProperties *DocProperties) error {
|
||||||
var (
|
core := new(decodeCoreProperties)
|
||||||
core *decodeCoreProperties
|
if err := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
|
||||||
err error
|
|
||||||
field, val string
|
|
||||||
fields []string
|
|
||||||
immutable, mutable reflect.Value
|
|
||||||
newProps *xlsxCoreProperties
|
|
||||||
output []byte
|
|
||||||
)
|
|
||||||
|
|
||||||
core = new(decodeCoreProperties)
|
|
||||||
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
|
|
||||||
Decode(core); err != nil && err != io.EOF {
|
Decode(core); err != nil && err != io.EOF {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
newProps = &xlsxCoreProperties{
|
newProps := &xlsxCoreProperties{
|
||||||
Dc: NameSpaceDublinCore,
|
Dc: NameSpaceDublinCore,
|
||||||
Dcterms: NameSpaceDublinCoreTerms,
|
Dcterms: NameSpaceDublinCoreTerms,
|
||||||
Dcmitype: NameSpaceDublinCoreMetadataInitiative,
|
Dcmitype: NameSpaceDublinCoreMetadataInitiative,
|
||||||
|
@ -219,23 +190,17 @@ func (f *File) SetDocProps(docProperties *DocProperties) error {
|
||||||
if core.Modified != nil {
|
if core.Modified != nil {
|
||||||
newProps.Modified = &xlsxDcTerms{Type: core.Modified.Type, Text: core.Modified.Text}
|
newProps.Modified = &xlsxDcTerms{Type: core.Modified.Type, Text: core.Modified.Text}
|
||||||
}
|
}
|
||||||
fields = []string{
|
setNoPtrFieldsVal([]string{
|
||||||
"Category", "ContentStatus", "Creator", "Description", "Identifier", "Keywords",
|
"Category", "ContentStatus", "Creator", "Description", "Identifier", "Keywords",
|
||||||
"LastModifiedBy", "Revision", "Subject", "Title", "Language", "Version",
|
"LastModifiedBy", "Revision", "Subject", "Title", "Language", "Version",
|
||||||
}
|
}, reflect.ValueOf(*docProperties), reflect.ValueOf(newProps).Elem())
|
||||||
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 != "" {
|
if docProperties.Created != "" {
|
||||||
newProps.Created = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Created}
|
newProps.Created = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Created}
|
||||||
}
|
}
|
||||||
if docProperties.Modified != "" {
|
if docProperties.Modified != "" {
|
||||||
newProps.Modified = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Modified}
|
newProps.Modified = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Modified}
|
||||||
}
|
}
|
||||||
output, err = xml.Marshal(newProps)
|
output, err := xml.Marshal(newProps)
|
||||||
f.saveFileList(defaultXMLPathDocPropsCore, output)
|
f.saveFileList(defaultXMLPathDocPropsCore, output)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
49
lib.go
49
lib.go
|
@ -21,6 +21,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -878,6 +879,54 @@ func continuedFraction(n float64, i int64, limit int64, prec float64) *big.Rat {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// assignFieldValue assigns the value from an immutable reflect.Value to a
|
||||||
|
// mutable reflect.Value based on the type of the immutable value.
|
||||||
|
func assignFieldValue(field string, immutable, mutable reflect.Value) {
|
||||||
|
switch immutable.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
mutable.FieldByName(field).SetBool(immutable.Bool())
|
||||||
|
case reflect.Int:
|
||||||
|
mutable.FieldByName(field).SetInt(immutable.Int())
|
||||||
|
default:
|
||||||
|
mutable.FieldByName(field).SetString(immutable.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setNoPtrFieldsVal assigns values from the pointer or no-pointer structs
|
||||||
|
// fields (immutable) value to no-pointer struct field.
|
||||||
|
func setNoPtrFieldsVal(fields []string, immutable, mutable reflect.Value) {
|
||||||
|
for _, field := range fields {
|
||||||
|
immutableField := immutable.FieldByName(field)
|
||||||
|
if immutableField.Kind() == reflect.Ptr {
|
||||||
|
if immutableField.IsValid() && !immutableField.IsNil() {
|
||||||
|
assignFieldValue(field, immutableField.Elem(), mutable)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
assignFieldValue(field, immutableField, mutable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setPtrFieldsVal assigns values from the pointer or no-pointer structs
|
||||||
|
// fields (immutable) value to pointer struct field.
|
||||||
|
func setPtrFieldsVal(fields []string, immutable, mutable reflect.Value) {
|
||||||
|
for _, field := range fields {
|
||||||
|
immutableField := immutable.FieldByName(field)
|
||||||
|
if immutableField.Kind() == reflect.Ptr {
|
||||||
|
if immutableField.IsValid() && !immutableField.IsNil() {
|
||||||
|
mutable.FieldByName(field).Set(immutableField.Elem())
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if immutableField.IsZero() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ptr := reflect.New(immutableField.Type())
|
||||||
|
ptr.Elem().Set(immutableField)
|
||||||
|
mutable.FieldByName(field).Set(ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stack defined an abstract data type that serves as a collection of elements.
|
// Stack defined an abstract data type that serves as a collection of elements.
|
||||||
type Stack struct {
|
type Stack struct {
|
||||||
list *list.List
|
list *list.List
|
||||||
|
|
|
@ -883,14 +883,10 @@ func (f *File) getPivotTable(sheet, pivotTableXML, pivotCacheRels string) (Pivot
|
||||||
opts.DataRange = pc.CacheSource.WorksheetSource.Name
|
opts.DataRange = pc.CacheSource.WorksheetSource.Name
|
||||||
_ = f.getPivotTableDataRange(&opts)
|
_ = f.getPivotTableDataRange(&opts)
|
||||||
}
|
}
|
||||||
fields := []string{"RowGrandTotals", "ColGrandTotals", "ShowDrill", "UseAutoFormatting", "PageOverThenDown", "MergeItem", "CompactData", "ShowError"}
|
setPtrFieldsVal([]string{
|
||||||
immutable, mutable := reflect.ValueOf(*pt), reflect.ValueOf(&opts).Elem()
|
"RowGrandTotals", "ColGrandTotals", "ShowDrill",
|
||||||
for _, field := range fields {
|
"UseAutoFormatting", "PageOverThenDown", "MergeItem", "CompactData", "ShowError",
|
||||||
immutableField := immutable.FieldByName(field)
|
}, reflect.ValueOf(*pt), reflect.ValueOf(&opts).Elem())
|
||||||
if immutableField.Kind() == reflect.Ptr && !immutableField.IsNil() && immutableField.Elem().Kind() == reflect.Bool {
|
|
||||||
mutable.FieldByName(field).SetBool(immutableField.Elem().Bool())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if si := pt.PivotTableStyleInfo; si != nil {
|
if si := pt.PivotTableStyleInfo; si != nil {
|
||||||
opts.ShowRowHeaders = si.ShowRowHeaders
|
opts.ShowRowHeaders = si.ShowRowHeaders
|
||||||
opts.ShowColHeaders = si.ShowColHeaders
|
opts.ShowColHeaders = si.ShowColHeaders
|
||||||
|
@ -982,17 +978,8 @@ func extractPivotTableField(data string, fld *xlsxPivotField) PivotTableField {
|
||||||
ShowAll: fld.ShowAll,
|
ShowAll: fld.ShowAll,
|
||||||
InsertBlankRow: fld.InsertBlankRow,
|
InsertBlankRow: fld.InsertBlankRow,
|
||||||
}
|
}
|
||||||
fields := []string{"Compact", "Name", "Outline", "Subtotal", "DefaultSubtotal"}
|
setPtrFieldsVal([]string{"Compact", "Name", "Outline", "DefaultSubtotal"},
|
||||||
immutable, mutable := reflect.ValueOf(*fld), reflect.ValueOf(&pivotTableField).Elem()
|
reflect.ValueOf(*fld), reflect.ValueOf(&pivotTableField).Elem())
|
||||||
for _, field := range fields {
|
|
||||||
immutableField := immutable.FieldByName(field)
|
|
||||||
if immutableField.Kind() == reflect.String {
|
|
||||||
mutable.FieldByName(field).SetString(immutableField.String())
|
|
||||||
}
|
|
||||||
if immutableField.Kind() == reflect.Ptr && !immutableField.IsNil() && immutableField.Elem().Kind() == reflect.Bool {
|
|
||||||
mutable.FieldByName(field).SetBool(immutableField.Elem().Bool())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pivotTableField
|
return pivotTableField
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
82
workbook.go
82
workbook.go
|
@ -16,12 +16,16 @@ import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetWorkbookProps provides a function to sets workbook properties.
|
// SetWorkbookProps provides a function to sets workbook properties.
|
||||||
func (f *File) SetWorkbookProps(opts *WorkbookPropsOptions) error {
|
func (f *File) SetWorkbookProps(opts *WorkbookPropsOptions) error {
|
||||||
|
if opts == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
wb, err := f.workbookReader()
|
wb, err := f.workbookReader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -29,19 +33,9 @@ func (f *File) SetWorkbookProps(opts *WorkbookPropsOptions) error {
|
||||||
if wb.WorkbookPr == nil {
|
if wb.WorkbookPr == nil {
|
||||||
wb.WorkbookPr = new(xlsxWorkbookPr)
|
wb.WorkbookPr = new(xlsxWorkbookPr)
|
||||||
}
|
}
|
||||||
if opts == nil {
|
setNoPtrFieldsVal([]string{"Date1904", "FilterPrivacy", "CodeName"},
|
||||||
return nil
|
reflect.ValueOf(*opts), reflect.ValueOf(wb.WorkbookPr).Elem())
|
||||||
}
|
return err
|
||||||
if opts.Date1904 != nil {
|
|
||||||
wb.WorkbookPr.Date1904 = *opts.Date1904
|
|
||||||
}
|
|
||||||
if opts.FilterPrivacy != nil {
|
|
||||||
wb.WorkbookPr.FilterPrivacy = *opts.FilterPrivacy
|
|
||||||
}
|
|
||||||
if opts.CodeName != nil {
|
|
||||||
wb.WorkbookPr.CodeName = *opts.CodeName
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWorkbookProps provides a function to gets workbook properties.
|
// GetWorkbookProps provides a function to gets workbook properties.
|
||||||
|
@ -51,11 +45,63 @@ func (f *File) GetWorkbookProps() (WorkbookPropsOptions, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return opts, err
|
return opts, err
|
||||||
}
|
}
|
||||||
if wb.WorkbookPr != nil {
|
if wb.WorkbookPr == nil {
|
||||||
opts.Date1904 = boolPtr(wb.WorkbookPr.Date1904)
|
return opts, err
|
||||||
opts.FilterPrivacy = boolPtr(wb.WorkbookPr.FilterPrivacy)
|
|
||||||
opts.CodeName = stringPtr(wb.WorkbookPr.CodeName)
|
|
||||||
}
|
}
|
||||||
|
setPtrFieldsVal([]string{"Date1904", "FilterPrivacy", "CodeName"},
|
||||||
|
reflect.ValueOf(*wb.WorkbookPr), reflect.ValueOf(&opts).Elem())
|
||||||
|
return opts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCalcProps provides a function to sets calculation properties.
|
||||||
|
func (f *File) SetCalcProps(opts *CalcPropsOptions) error {
|
||||||
|
if opts == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
wb, err := f.workbookReader()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if wb.CalcPr == nil {
|
||||||
|
wb.CalcPr = new(xlsxCalcPr)
|
||||||
|
}
|
||||||
|
setNoPtrFieldsVal([]string{
|
||||||
|
"CalcCompleted", "CalcOnSave", "ForceFullCalc", "FullCalcOnLoad", "FullPrecision", "Iterate",
|
||||||
|
"IterateDelta",
|
||||||
|
"CalcMode", "RefMode",
|
||||||
|
}, reflect.ValueOf(*opts), reflect.ValueOf(wb.CalcPr).Elem())
|
||||||
|
if opts.CalcID != nil {
|
||||||
|
wb.CalcPr.CalcID = int(*opts.CalcID)
|
||||||
|
}
|
||||||
|
if opts.ConcurrentManualCount != nil {
|
||||||
|
wb.CalcPr.ConcurrentManualCount = int(*opts.ConcurrentManualCount)
|
||||||
|
}
|
||||||
|
if opts.IterateCount != nil {
|
||||||
|
wb.CalcPr.IterateCount = int(*opts.IterateCount)
|
||||||
|
}
|
||||||
|
wb.CalcPr.ConcurrentCalc = opts.ConcurrentCalc
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCalcProps provides a function to gets calculation properties.
|
||||||
|
func (f *File) GetCalcProps() (CalcPropsOptions, error) {
|
||||||
|
var opts CalcPropsOptions
|
||||||
|
wb, err := f.workbookReader()
|
||||||
|
if err != nil {
|
||||||
|
return opts, err
|
||||||
|
}
|
||||||
|
if wb.CalcPr == nil {
|
||||||
|
return opts, err
|
||||||
|
}
|
||||||
|
setPtrFieldsVal([]string{
|
||||||
|
"CalcCompleted", "CalcOnSave", "ForceFullCalc", "FullCalcOnLoad", "FullPrecision", "Iterate",
|
||||||
|
"IterateDelta",
|
||||||
|
"CalcMode", "RefMode",
|
||||||
|
}, reflect.ValueOf(*wb.CalcPr), reflect.ValueOf(&opts).Elem())
|
||||||
|
opts.CalcID = uintPtr(uint(wb.CalcPr.CalcID))
|
||||||
|
opts.ConcurrentManualCount = uintPtr(uint(wb.CalcPr.ConcurrentManualCount))
|
||||||
|
opts.IterateCount = uintPtr(uint(wb.CalcPr.IterateCount))
|
||||||
|
opts.ConcurrentCalc = wb.CalcPr.ConcurrentCalc
|
||||||
return opts, err
|
return opts, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +145,7 @@ func (f *File) ProtectWorkbook(opts *WorkbookProtectionOptions) error {
|
||||||
wb.WorkbookProtection.WorkbookHashValue = hashValue
|
wb.WorkbookProtection.WorkbookHashValue = hashValue
|
||||||
wb.WorkbookProtection.WorkbookSpinCount = int(workbookProtectionSpinCount)
|
wb.WorkbookProtection.WorkbookSpinCount = int(workbookProtectionSpinCount)
|
||||||
}
|
}
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnprotectWorkbook provides a function to remove protection for workbook,
|
// UnprotectWorkbook provides a function to remove protection for workbook,
|
||||||
|
|
|
@ -21,6 +21,10 @@ func TestWorkbookProps(t *testing.T) {
|
||||||
opts, err := f.GetWorkbookProps()
|
opts, err := f.GetWorkbookProps()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, expected, opts)
|
assert.Equal(t, expected, opts)
|
||||||
|
wb.WorkbookPr = nil
|
||||||
|
opts, err = f.GetWorkbookProps()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, WorkbookPropsOptions{}, opts)
|
||||||
// Test set workbook properties with unsupported charset workbook
|
// Test set workbook properties with unsupported charset workbook
|
||||||
f.WorkBook = nil
|
f.WorkBook = nil
|
||||||
f.Pkg.Store(defaultXMLPathWorkbook, MacintoshCyrillicCharset)
|
f.Pkg.Store(defaultXMLPathWorkbook, MacintoshCyrillicCharset)
|
||||||
|
@ -32,6 +36,38 @@ func TestWorkbookProps(t *testing.T) {
|
||||||
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCalcProps(t *testing.T) {
|
||||||
|
f := NewFile()
|
||||||
|
assert.NoError(t, f.SetCalcProps(nil))
|
||||||
|
wb, err := f.workbookReader()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
wb.CalcPr = nil
|
||||||
|
expected := CalcPropsOptions{
|
||||||
|
FullCalcOnLoad: boolPtr(true),
|
||||||
|
CalcID: uintPtr(122211),
|
||||||
|
ConcurrentManualCount: uintPtr(5),
|
||||||
|
IterateCount: uintPtr(10),
|
||||||
|
ConcurrentCalc: boolPtr(true),
|
||||||
|
}
|
||||||
|
assert.NoError(t, f.SetCalcProps(&expected))
|
||||||
|
opts, err := f.GetCalcProps()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, expected, opts)
|
||||||
|
wb.CalcPr = nil
|
||||||
|
opts, err = f.GetCalcProps()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, CalcPropsOptions{}, opts)
|
||||||
|
// Test set workbook properties with unsupported charset workbook
|
||||||
|
f.WorkBook = nil
|
||||||
|
f.Pkg.Store(defaultXMLPathWorkbook, MacintoshCyrillicCharset)
|
||||||
|
assert.EqualError(t, f.SetCalcProps(&expected), "XML syntax error on line 1: invalid UTF-8")
|
||||||
|
// Test get workbook properties with unsupported charset workbook
|
||||||
|
f.WorkBook = nil
|
||||||
|
f.Pkg.Store(defaultXMLPathWorkbook, MacintoshCyrillicCharset)
|
||||||
|
_, err = f.GetCalcProps()
|
||||||
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
||||||
|
}
|
||||||
|
|
||||||
func TestDeleteWorkbookRels(t *testing.T) {
|
func TestDeleteWorkbookRels(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
// Test delete pivot table without worksheet relationships
|
// Test delete pivot table without worksheet relationships
|
||||||
|
|
|
@ -315,7 +315,7 @@ type xlsxDefinedName struct {
|
||||||
// displaying the results as values in the cells that contain the formulas.
|
// displaying the results as values in the cells that contain the formulas.
|
||||||
type xlsxCalcPr struct {
|
type xlsxCalcPr struct {
|
||||||
CalcCompleted bool `xml:"calcCompleted,attr,omitempty"`
|
CalcCompleted bool `xml:"calcCompleted,attr,omitempty"`
|
||||||
CalcID string `xml:"calcId,attr,omitempty"`
|
CalcID int `xml:"calcId,attr,omitempty"`
|
||||||
CalcMode string `xml:"calcMode,attr,omitempty"`
|
CalcMode string `xml:"calcMode,attr,omitempty"`
|
||||||
CalcOnSave bool `xml:"calcOnSave,attr,omitempty"`
|
CalcOnSave bool `xml:"calcOnSave,attr,omitempty"`
|
||||||
ConcurrentCalc *bool `xml:"concurrentCalc,attr"`
|
ConcurrentCalc *bool `xml:"concurrentCalc,attr"`
|
||||||
|
@ -384,6 +384,24 @@ type DefinedName struct {
|
||||||
Scope string
|
Scope string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CalcPropsOptions defines the collection of properties the application uses to
|
||||||
|
// record calculation status and details.
|
||||||
|
type CalcPropsOptions struct {
|
||||||
|
CalcID *uint `xml:"calcId,attr"`
|
||||||
|
CalcMode *string `xml:"calcMode,attr"`
|
||||||
|
FullCalcOnLoad *bool `xml:"fullCalcOnLoad,attr"`
|
||||||
|
RefMode *string `xml:"refMode,attr"`
|
||||||
|
Iterate *bool `xml:"iterate,attr"`
|
||||||
|
IterateCount *uint `xml:"iterateCount,attr"`
|
||||||
|
IterateDelta *float64 `xml:"iterateDelta,attr"`
|
||||||
|
FullPrecision *bool `xml:"fullPrecision,attr"`
|
||||||
|
CalcCompleted *bool `xml:"calcCompleted,attr"`
|
||||||
|
CalcOnSave *bool `xml:"calcOnSave,attr"`
|
||||||
|
ConcurrentCalc *bool `xml:"concurrentCalc,attr"`
|
||||||
|
ConcurrentManualCount *uint `xml:"concurrentManualCount,attr"`
|
||||||
|
ForceFullCalc *bool `xml:"forceFullCalc,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
// WorkbookPropsOptions directly maps the settings of workbook proprieties.
|
// WorkbookPropsOptions directly maps the settings of workbook proprieties.
|
||||||
type WorkbookPropsOptions struct {
|
type WorkbookPropsOptions struct {
|
||||||
Date1904 *bool
|
Date1904 *bool
|
||||||
|
|
Loading…
Reference in New Issue