calcchain.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. delete(f.XLSX, "xl/calcChain.xml")
  51. content := f.contentTypesReader()
  52. for k, v := range content.Overrides {
  53. if v.PartName == "/xl/calcChain.xml" {
  54. content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)
  55. }
  56. }
  57. }
  58. }
  59. type xlsxCalcChainCollection []xlsxCalcChainC
  60. // Filter provides a function to filter calculation chain.
  61. func (c xlsxCalcChainCollection) Filter(fn func(v xlsxCalcChainC) bool) []xlsxCalcChainC {
  62. var results []xlsxCalcChainC
  63. for _, v := range c {
  64. if fn(v) {
  65. results = append(results, v)
  66. }
  67. }
  68. return results
  69. }