calcchain.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright 2016 - 2021 The excelize Authors. All rights reserved. Use of
  2. // this source code is governed by a BSD-style license that can be found in
  3. // the LICENSE file.
  4. //
  5. // Package excelize providing a set of functions that allow you to write to
  6. // and read from XLSX / XLSM / XLTM files. Supports reading and writing
  7. // spreadsheet documents generated by Microsoft Excel™ 2007 and later. Supports
  8. // complex components by high compatibility, and provided streaming API for
  9. // generating or reading data from a worksheet with huge amounts of data. This
  10. // library needs Go version 1.15 or later.
  11. package excelize
  12. import (
  13. "bytes"
  14. "encoding/xml"
  15. "io"
  16. "log"
  17. )
  18. // calcChainReader provides a function to get the pointer to the structure
  19. // after deserialization of xl/calcChain.xml.
  20. func (f *File) calcChainReader() *xlsxCalcChain {
  21. var err error
  22. if f.CalcChain == nil {
  23. f.CalcChain = new(xlsxCalcChain)
  24. if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML("xl/calcChain.xml")))).
  25. Decode(f.CalcChain); err != nil && err != io.EOF {
  26. log.Printf("xml decode error: %s", err)
  27. }
  28. }
  29. return f.CalcChain
  30. }
  31. // calcChainWriter provides a function to save xl/calcChain.xml after
  32. // serialize structure.
  33. func (f *File) calcChainWriter() {
  34. if f.CalcChain != nil && f.CalcChain.C != nil {
  35. output, _ := xml.Marshal(f.CalcChain)
  36. f.saveFileList("xl/calcChain.xml", output)
  37. }
  38. }
  39. // deleteCalcChain provides a function to remove cell reference on the
  40. // calculation chain.
  41. func (f *File) deleteCalcChain(index int, axis string) {
  42. calc := f.calcChainReader()
  43. if calc != nil {
  44. calc.C = xlsxCalcChainCollection(calc.C).Filter(func(c xlsxCalcChainC) bool {
  45. return !((c.I == index && c.R == axis) || (c.I == index && axis == ""))
  46. })
  47. }
  48. if len(calc.C) == 0 {
  49. f.CalcChain = nil
  50. f.Pkg.Delete("xl/calcChain.xml")
  51. content := f.contentTypesReader()
  52. content.Lock()
  53. defer content.Unlock()
  54. for k, v := range content.Overrides {
  55. if v.PartName == "/xl/calcChain.xml" {
  56. content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)
  57. }
  58. }
  59. }
  60. }
  61. type xlsxCalcChainCollection []xlsxCalcChainC
  62. // Filter provides a function to filter calculation chain.
  63. func (c xlsxCalcChainCollection) Filter(fn func(v xlsxCalcChainC) bool) []xlsxCalcChainC {
  64. var results []xlsxCalcChainC
  65. for _, v := range c {
  66. if fn(v) {
  67. results = append(results, v)
  68. }
  69. }
  70. return results
  71. }