calcchain.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright 2016 - 2020 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 files. Support reads and writes XLSX file generated by
  7. // Microsoft Excel™ 2007 and later. Support save file without losing original
  8. // charts of XLSX. This library needs Go version 1.10 or later.
  9. package excelize
  10. import (
  11. "bytes"
  12. "encoding/xml"
  13. "io"
  14. "log"
  15. )
  16. // calcChainReader provides a function to get the pointer to the structure
  17. // after deserialization of xl/calcChain.xml.
  18. func (f *File) calcChainReader() *xlsxCalcChain {
  19. var err error
  20. if f.CalcChain == nil {
  21. f.CalcChain = new(xlsxCalcChain)
  22. if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML("xl/calcChain.xml")))).
  23. Decode(f.CalcChain); err != nil && err != io.EOF {
  24. log.Printf("xml decode error: %s", err)
  25. }
  26. }
  27. return f.CalcChain
  28. }
  29. // calcChainWriter provides a function to save xl/calcChain.xml after
  30. // serialize structure.
  31. func (f *File) calcChainWriter() {
  32. if f.CalcChain != nil && f.CalcChain.C != nil {
  33. output, _ := xml.Marshal(f.CalcChain)
  34. f.saveFileList("xl/calcChain.xml", output)
  35. }
  36. }
  37. // deleteCalcChain provides a function to remove cell reference on the
  38. // calculation chain.
  39. func (f *File) deleteCalcChain(index int, axis string) {
  40. calc := f.calcChainReader()
  41. if calc != nil {
  42. calc.C = xlsxCalcChainCollection(calc.C).Filter(func(c xlsxCalcChainC) bool {
  43. return !((c.I == index && c.R == axis) || (c.I == index && axis == ""))
  44. })
  45. }
  46. if len(calc.C) == 0 {
  47. f.CalcChain = nil
  48. delete(f.XLSX, "xl/calcChain.xml")
  49. content := f.contentTypesReader()
  50. for k, v := range content.Overrides {
  51. if v.PartName == "/xl/calcChain.xml" {
  52. content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)
  53. }
  54. }
  55. }
  56. }
  57. type xlsxCalcChainCollection []xlsxCalcChainC
  58. // Filter provides a function to filter calculation chain.
  59. func (c xlsxCalcChainCollection) Filter(fn func(v xlsxCalcChainC) bool) []xlsxCalcChainC {
  60. var results []xlsxCalcChainC
  61. for _, v := range c {
  62. if fn(v) {
  63. results = append(results, v)
  64. }
  65. }
  66. return results
  67. }