sharedstrings.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package xlsx
  2. // xlsxSST directly maps the sst element from the namespace
  3. // http://schemas.openxmlformats.org/spreadsheetml/2006/main currently
  4. // I have not checked this for completeness - it does as much as need.
  5. type xlsxSST struct {
  6. Count int `xml:"count,attr"`
  7. UniqueCount int `xml:"uniqueCount,attr"`
  8. SI []xlsxSI `xml:"si"`
  9. }
  10. // xlsxSI directly maps the si element from the namespace
  11. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  12. // currently I have not checked this for completeness - it does as
  13. // much as I need.
  14. type xlsxSI struct {
  15. T string `xml:"t"`
  16. R []xlsxR `xml:"r"`
  17. }
  18. // xlsxR directly maps the r element from the namespace
  19. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  20. // currently I have not checked this for completeness - it does as
  21. // much as I need.
  22. type xlsxR struct {
  23. T string `xml:"t"`
  24. }
  25. type RefTable struct {
  26. indexedStrings []string
  27. knownStrings map[string]int
  28. }
  29. // NewSharedStringRefTable() creates a new, empty RefTable.
  30. func NewSharedStringRefTable() *RefTable {
  31. rt := RefTable{}
  32. rt.knownStrings = make(map[string]int)
  33. return &rt
  34. }
  35. // MakeSharedStringRefTable() takes an xlsxSST struct and converts
  36. // it's contents to an slice of strings used to refer to string values
  37. // by numeric index - this is the model used within XLSX worksheet (a
  38. // numeric reference is stored to a shared cell value).
  39. func MakeSharedStringRefTable(source *xlsxSST) *RefTable {
  40. reftable := NewSharedStringRefTable()
  41. for _, si := range source.SI {
  42. if len(si.R) > 0 {
  43. newString := ""
  44. for j := 0; j < len(si.R); j++ {
  45. newString = newString + si.R[j].T
  46. }
  47. reftable.AddString(newString)
  48. } else {
  49. reftable.AddString(si.T)
  50. }
  51. }
  52. return reftable
  53. }
  54. // makeXlsxSST() takes a RefTable and returns and
  55. // equivalent xlsxSST representation.
  56. func (rt *RefTable) makeXLSXSST() xlsxSST {
  57. sst := xlsxSST{}
  58. sst.Count = len(rt.indexedStrings)
  59. sst.UniqueCount = sst.Count
  60. for _, ref := range rt.indexedStrings {
  61. si := xlsxSI{}
  62. si.T = ref
  63. sst.SI = append(sst.SI, si)
  64. }
  65. return sst
  66. }
  67. // Resolvesharedstring() looks up a string value by numeric index from
  68. // a provided reference table (just a slice of strings in the correct
  69. // order). This function only exists to provide clarity or purpose
  70. // via it's name.
  71. func (rt *RefTable) ResolveSharedString(index int) string {
  72. return rt.indexedStrings[index]
  73. }
  74. // AddString adds a string to the reference table and return it's
  75. // numeric index. If the string already exists then it simply returns
  76. // the existing index.
  77. func (rt *RefTable) AddString(str string) int {
  78. index, ok := rt.knownStrings[str]
  79. if ok {
  80. return index
  81. }
  82. rt.indexedStrings = append(rt.indexedStrings, str)
  83. index = len(rt.indexedStrings) - 1
  84. rt.knownStrings[str] = index
  85. return index
  86. }
  87. func (rt *RefTable) Length() int {
  88. return len(rt.indexedStrings)
  89. }