From 841ff4a03e2b30378f6bb2930752c8e9dcfe0dca Mon Sep 17 00:00:00 2001 From: Aplulu Date: Tue, 9 Apr 2019 23:18:31 +0900 Subject: Fix out of range panic when removing formula. Fix file corruption issue when deleting a sheet containing a formula. --- calcchain.go | 22 ++++++++++++++++------ cell.go | 2 +- sheet.go | 1 + 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/calcchain.go b/calcchain.go index 285a3e9..6fbdcd7 100644 --- a/calcchain.go +++ b/calcchain.go @@ -33,14 +33,12 @@ func (f *File) calcChainWriter() { // deleteCalcChain provides a function to remove cell reference on the // calculation chain. -func (f *File) deleteCalcChain(axis string) { +func (f *File) deleteCalcChain(index int, axis string) { calc := f.calcChainReader() if calc != nil { - for i, c := range calc.C { - if c.R == axis { - calc.C = append(calc.C[:i], calc.C[i+1:]...) - } - } + calc.C = xlsxCalcChainCollection(calc.C).Filter(func(c xlsxCalcChainC) bool { + return !((c.I == index && c.R == axis) || (c.I == index && axis == "")) + }) } if len(calc.C) == 0 { f.CalcChain = nil @@ -53,3 +51,15 @@ func (f *File) deleteCalcChain(axis string) { } } } + +type xlsxCalcChainCollection []xlsxCalcChainC + +func (c xlsxCalcChainCollection) Filter(fn func(v xlsxCalcChainC) bool) []xlsxCalcChainC { + results := make([]xlsxCalcChainC, 0) + for _, v := range c { + if fn(v) { + results = append(results, v) + } + } + return results +} diff --git a/cell.go b/cell.go index a1b6dbf..36f2d93 100644 --- a/cell.go +++ b/cell.go @@ -235,7 +235,7 @@ func (f *File) SetCellFormula(sheet, axis, formula string) error { } if formula == "" { cellData.F = nil - f.deleteCalcChain(axis) + f.deleteCalcChain(f.GetSheetIndex(sheet), axis) return err } diff --git a/sheet.go b/sheet.go index ec4df77..9960ef8 100644 --- a/sheet.go +++ b/sheet.go @@ -403,6 +403,7 @@ func (f *File) DeleteSheet(name string) { rels := "xl/worksheets/_rels/sheet" + strconv.Itoa(v.SheetID) + ".xml.rels" target := f.deleteSheetFromWorkbookRels(v.ID) f.deleteSheetFromContentTypes(target) + f.deleteCalcChain(v.SheetID, "") // Delete CalcChain delete(f.sheetMap, name) delete(f.XLSX, sheet) delete(f.XLSX, rels) -- cgit v1.2.1