From 4f0025aab07bb4cb290c38932619271c2cae7552 Mon Sep 17 00:00:00 2001 From: xuri Date: Fri, 13 Jan 2023 00:05:46 +0800 Subject: [PATCH] This closes #1447, add support for strict theme namespace - Support specify if applying number format style for the cell calculation result - Reduce cyclomatic complexities for the OpenReader function --- calc.go | 21 ++++++++---- excelize.go | 29 ++++++++++------ lib.go | 16 +++++---- merge.go | 2 +- xmlDrawing.go | 91 +++++++++++++++++++++++++++------------------------ 5 files changed, 94 insertions(+), 65 deletions(-) diff --git a/calc.go b/calc.go index b864a23e2f..7e1fa71e2d 100644 --- a/calc.go +++ b/calc.go @@ -767,20 +767,29 @@ type formulaFuncs struct { // YIELDMAT // Z.TEST // ZTEST -func (f *File) CalcCellValue(sheet, cell string) (result string, err error) { - var token formulaArg - token, err = f.calcCellValue(&calcContext{ +func (f *File) CalcCellValue(sheet, cell string, opts ...Options) (result string, err error) { + var ( + rawCellValue = parseOptions(opts...).RawCellValue + styleIdx int + token formulaArg + ) + if token, err = f.calcCellValue(&calcContext{ entry: fmt.Sprintf("%s!%s", sheet, cell), iterations: make(map[string]uint), - }, sheet, cell) + }, sheet, cell); err != nil { + return + } + if !rawCellValue { + styleIdx, _ = f.GetCellStyle(sheet, cell) + } result = token.Value() if isNum, precision, decimal := isNumeric(result); isNum { if precision > 15 { - result = strings.ToUpper(strconv.FormatFloat(decimal, 'G', 15, 64)) + result, err = f.formattedValue(styleIdx, strings.ToUpper(strconv.FormatFloat(decimal, 'G', 15, 64)), rawCellValue) return } if !strings.HasPrefix(result, "0") { - result = strings.ToUpper(strconv.FormatFloat(decimal, 'f', -1, 64)) + result, err = f.formattedValue(styleIdx, strings.ToUpper(strconv.FormatFloat(decimal, 'f', -1, 64)), rawCellValue) } } return diff --git a/excelize.go b/excelize.go index b41cd00a23..5a47f203b7 100644 --- a/excelize.go +++ b/excelize.go @@ -132,15 +132,9 @@ func newFile() *File { } } -// OpenReader read data stream from io.Reader and return a populated -// spreadsheet file. -func OpenReader(r io.Reader, opts ...Options) (*File, error) { - b, err := io.ReadAll(r) - if err != nil { - return nil, err - } - f := newFile() - f.options = parseOptions(opts...) +// checkOpenReaderOptions check and validate options field value for open +// reader. +func (f *File) checkOpenReaderOptions() error { if f.options.UnzipSizeLimit == 0 { f.options.UnzipSizeLimit = UnzipSizeLimit if f.options.UnzipXMLSizeLimit > f.options.UnzipSizeLimit { @@ -154,7 +148,22 @@ func OpenReader(r io.Reader, opts ...Options) (*File, error) { } } if f.options.UnzipXMLSizeLimit > f.options.UnzipSizeLimit { - return nil, ErrOptionsUnzipSizeLimit + return ErrOptionsUnzipSizeLimit + } + return nil +} + +// OpenReader read data stream from io.Reader and return a populated +// spreadsheet file. +func OpenReader(r io.Reader, opts ...Options) (*File, error) { + b, err := io.ReadAll(r) + if err != nil { + return nil, err + } + f := newFile() + f.options = parseOptions(opts...) + if err = f.checkOpenReaderOptions(); err != nil { + return nil, err } if bytes.Contains(b, oleIdentifier) { if b, err = Decrypt(b, f.options); err != nil { diff --git a/lib.go b/lib.go index e5637ec9f1..887946aef5 100644 --- a/lib.go +++ b/lib.go @@ -497,12 +497,16 @@ func (avb *attrValBool) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err // Transitional namespaces. func namespaceStrictToTransitional(content []byte) []byte { namespaceTranslationDic := map[string]string{ - StrictSourceRelationship: SourceRelationship.Value, - StrictSourceRelationshipOfficeDocument: SourceRelationshipOfficeDocument, - StrictSourceRelationshipChart: SourceRelationshipChart, - StrictSourceRelationshipComments: SourceRelationshipComments, - StrictSourceRelationshipImage: SourceRelationshipImage, - StrictNameSpaceSpreadSheet: NameSpaceSpreadSheet.Value, + StrictNameSpaceDocumentPropertiesVariantTypes: NameSpaceDocumentPropertiesVariantTypes.Value, + StrictNameSpaceDrawingMLMain: NameSpaceDrawingMLMain, + StrictNameSpaceExtendedProperties: NameSpaceExtendedProperties, + StrictNameSpaceSpreadSheet: NameSpaceSpreadSheet.Value, + StrictSourceRelationship: SourceRelationship.Value, + StrictSourceRelationshipChart: SourceRelationshipChart, + StrictSourceRelationshipComments: SourceRelationshipComments, + StrictSourceRelationshipExtendProperties: SourceRelationshipExtendProperties, + StrictSourceRelationshipImage: SourceRelationshipImage, + StrictSourceRelationshipOfficeDocument: SourceRelationshipOfficeDocument, } for s, n := range namespaceTranslationDic { content = bytesReplace(content, []byte(s), []byte(n), -1) diff --git a/merge.go b/merge.go index b3138aff6b..eb3fea30ca 100644 --- a/merge.go +++ b/merge.go @@ -41,7 +41,7 @@ func (mc *xlsxMergeCell) Rect() ([]int, error) { // B1(x1,y1) D1(x2,y1) // +------------------------+ // | | -// A4(x3,y3) | C4(x4,y3) | +// A4(x3,y3) | C4(x4,y3) | // +------------------------+ | // | | | | // | |B5(x1,y2) | D5(x2,y2)| diff --git a/xmlDrawing.go b/xmlDrawing.go index c3c524b59e..30b4d0942e 100644 --- a/xmlDrawing.go +++ b/xmlDrawing.go @@ -38,48 +38,55 @@ var ( // Source relationship and namespace. const ( - ContentTypeAddinMacro = "application/vnd.ms-excel.addin.macroEnabled.main+xml" - ContentTypeDrawing = "application/vnd.openxmlformats-officedocument.drawing+xml" - ContentTypeDrawingML = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" - ContentTypeMacro = "application/vnd.ms-excel.sheet.macroEnabled.main+xml" - ContentTypeSheetML = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" - ContentTypeSpreadSheetMLChartsheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml" - ContentTypeSpreadSheetMLComments = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml" - ContentTypeSpreadSheetMLPivotCacheDefinition = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml" - ContentTypeSpreadSheetMLPivotTable = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml" - ContentTypeSpreadSheetMLSharedStrings = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" - ContentTypeSpreadSheetMLTable = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml" - ContentTypeSpreadSheetMLWorksheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" - ContentTypeTemplate = "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml" - ContentTypeTemplateMacro = "application/vnd.ms-excel.template.macroEnabled.main+xml" - ContentTypeVBA = "application/vnd.ms-office.vbaProject" - ContentTypeVML = "application/vnd.openxmlformats-officedocument.vmlDrawing" - NameSpaceDublinCore = "http://purl.org/dc/elements/1.1/" - NameSpaceDublinCoreMetadataInitiative = "http://purl.org/dc/dcmitype/" - NameSpaceDublinCoreTerms = "http://purl.org/dc/terms/" - NameSpaceXML = "http://www.w3.org/XML/1998/namespace" - NameSpaceXMLSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance" - SourceRelationshipChart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart" - SourceRelationshipChartsheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet" - SourceRelationshipComments = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" - SourceRelationshipDialogsheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/dialogsheet" - SourceRelationshipDrawingML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" - SourceRelationshipDrawingVML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing" - SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" - SourceRelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" - SourceRelationshipOfficeDocument = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" - SourceRelationshipPivotCache = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition" - SourceRelationshipPivotTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable" - SourceRelationshipSharedStrings = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" - SourceRelationshipTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table" - SourceRelationshipVBAProject = "http://schemas.microsoft.com/office/2006/relationships/vbaProject" - SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" - StrictNameSpaceSpreadSheet = "http://purl.oclc.org/ooxml/spreadsheetml/main" - StrictSourceRelationship = "http://purl.oclc.org/ooxml/officeDocument/relationships" - StrictSourceRelationshipChart = "http://purl.oclc.org/ooxml/officeDocument/relationships/chart" - StrictSourceRelationshipComments = "http://purl.oclc.org/ooxml/officeDocument/relationships/comments" - StrictSourceRelationshipImage = "http://purl.oclc.org/ooxml/officeDocument/relationships/image" - StrictSourceRelationshipOfficeDocument = "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument" + ContentTypeAddinMacro = "application/vnd.ms-excel.addin.macroEnabled.main+xml" + ContentTypeDrawing = "application/vnd.openxmlformats-officedocument.drawing+xml" + ContentTypeDrawingML = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" + ContentTypeMacro = "application/vnd.ms-excel.sheet.macroEnabled.main+xml" + ContentTypeSheetML = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" + ContentTypeSpreadSheetMLChartsheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml" + ContentTypeSpreadSheetMLComments = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml" + ContentTypeSpreadSheetMLPivotCacheDefinition = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml" + ContentTypeSpreadSheetMLPivotTable = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml" + ContentTypeSpreadSheetMLSharedStrings = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" + ContentTypeSpreadSheetMLTable = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml" + ContentTypeSpreadSheetMLWorksheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" + ContentTypeTemplate = "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml" + ContentTypeTemplateMacro = "application/vnd.ms-excel.template.macroEnabled.main+xml" + ContentTypeVBA = "application/vnd.ms-office.vbaProject" + ContentTypeVML = "application/vnd.openxmlformats-officedocument.vmlDrawing" + NameSpaceDrawingMLMain = "http://schemas.openxmlformats.org/drawingml/2006/main" + NameSpaceDublinCore = "http://purl.org/dc/elements/1.1/" + NameSpaceDublinCoreMetadataInitiative = "http://purl.org/dc/dcmitype/" + NameSpaceDublinCoreTerms = "http://purl.org/dc/terms/" + NameSpaceExtendedProperties = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" + NameSpaceXML = "http://www.w3.org/XML/1998/namespace" + NameSpaceXMLSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance" + SourceRelationshipChart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart" + SourceRelationshipChartsheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet" + SourceRelationshipComments = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" + SourceRelationshipDialogsheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/dialogsheet" + SourceRelationshipDrawingML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" + SourceRelationshipDrawingVML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing" + SourceRelationshipExtendProperties = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" + SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" + SourceRelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" + SourceRelationshipOfficeDocument = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" + SourceRelationshipPivotCache = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition" + SourceRelationshipPivotTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable" + SourceRelationshipSharedStrings = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" + SourceRelationshipTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table" + SourceRelationshipVBAProject = "http://schemas.microsoft.com/office/2006/relationships/vbaProject" + SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" + StrictNameSpaceDocumentPropertiesVariantTypes = "http://purl.oclc.org/ooxml/officeDocument/docPropsVTypes" + StrictNameSpaceDrawingMLMain = "http://purl.oclc.org/ooxml/drawingml/main" + StrictNameSpaceExtendedProperties = "http://purl.oclc.org/ooxml/officeDocument/extendedProperties" + StrictNameSpaceSpreadSheet = "http://purl.oclc.org/ooxml/spreadsheetml/main" + StrictSourceRelationship = "http://purl.oclc.org/ooxml/officeDocument/relationships" + StrictSourceRelationshipChart = "http://purl.oclc.org/ooxml/officeDocument/relationships/chart" + StrictSourceRelationshipComments = "http://purl.oclc.org/ooxml/officeDocument/relationships/comments" + StrictSourceRelationshipExtendProperties = "http://purl.oclc.org/ooxml/officeDocument/relationships/extendedProperties" + StrictSourceRelationshipImage = "http://purl.oclc.org/ooxml/officeDocument/relationships/image" + StrictSourceRelationshipOfficeDocument = "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument" // ExtURIConditionalFormattings is the extLst child element // ([ISO/IEC29500-1:2016] section 18.2.10) of the worksheet element // ([ISO/IEC29500-1:2016] section 18.3.1.99) is extended by the addition of