workbook.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package xlsx
  2. import (
  3. "archive/zip"
  4. "encoding/xml"
  5. "fmt"
  6. "io"
  7. "strings"
  8. )
  9. // xlsxWorkbook directly maps the workbook element from the namespace
  10. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  11. // currently I have not checked it for completeness - it does as much
  12. // as I need.
  13. type xlsxWorkbook struct {
  14. FileVersion xlsxFileVersion `xml:"fileVersion"`
  15. WorkbookPr xlsxWorkbookPr `xml:"workbookPr"`
  16. BookViews xlsxBookViews `xml:"bookViews"`
  17. Sheets xlsxSheets `xml:"sheets"`
  18. DefinedNames xlsxDefinedNames `xml:"definedNames"`
  19. CalcPr xlsxCalcPr `xml:"calcPr"`
  20. }
  21. // xlsxFileVersion directly maps the fileVersion element from the
  22. // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main
  23. // - currently I have not checked it for completeness - it does as
  24. // much as I need.
  25. type xlsxFileVersion struct {
  26. AppName string `xml:"appName,attr"`
  27. LastEdited string `xml:"lastEdited,attr"`
  28. LowestEdited string `xml:"lowestEdited,attr"`
  29. RupBuild string `xml:"rupBuild,attr"`
  30. }
  31. // xlsxWorkbookPr directly maps the workbookPr element from the
  32. // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main
  33. // - currently I have not checked it for completeness - it does as
  34. // much as I need.
  35. type xlsxWorkbookPr struct {
  36. DefaultThemeVersion string `xml:"defaultThemeVersion,attr"`
  37. }
  38. // xlsxBookViews directly maps the bookViews element from the
  39. // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main
  40. // - currently I have not checked it for completeness - it does as
  41. // much as I need.
  42. type xlsxBookViews struct {
  43. WorkBookView []xlsxWorkBookView `xml:"workbookView"`
  44. }
  45. // xlsxWorkBookView directly maps the workbookView element from the
  46. // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main
  47. // - currently I have not checked it for completeness - it does as
  48. // much as I need.
  49. type xlsxWorkBookView struct {
  50. XWindow string `xml:"xWindow,attr"`
  51. YWindow string `xml:"yWindow,attr"`
  52. WindowWidth string `xml:"windowWidth,attr"`
  53. WindowHeight string `xml:"windowHeight,attr"`
  54. }
  55. // xlsxSheets directly maps the sheets element from the namespace
  56. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  57. // currently I have not checked it for completeness - it does as much
  58. // as I need.
  59. type xlsxSheets struct {
  60. Sheet []xlsxSheet `xml:"sheet"`
  61. }
  62. // xlsxSheet directly maps the sheet element from the namespace
  63. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  64. // currently I have not checked it for completeness - it does as much
  65. // as I need.
  66. type xlsxSheet struct {
  67. Name string `xml:"name,attr"`
  68. SheetId string `xml:"sheetId,attr"`
  69. Id string `xml:"id,attr"`
  70. }
  71. // xlsxDefinedNames directly maps the definedNames element from the
  72. // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main
  73. // - currently I have not checked it for completeness - it does as
  74. // much as I need.
  75. type xlsxDefinedNames struct {
  76. DefinedName []xlsxDefinedName `xml:"definedName"`
  77. }
  78. // xlsxDefinedName directly maps the definedName element from the
  79. // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main
  80. // - currently I have not checked it for completeness - it does as
  81. // much as I need.
  82. type xlsxDefinedName struct {
  83. Data string `xml:",chardata"`
  84. Name string `xml:"name,attr"`
  85. LocalSheetID string `xml:"localSheetId,attr"`
  86. }
  87. // xlsxCalcPr directly maps the calcPr element from the namespace
  88. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  89. // currently I have not checked it for completeness - it does as much
  90. // as I need.
  91. type xlsxCalcPr struct {
  92. CalcId string `xml:"calcId,attr"`
  93. }
  94. // getWorksheetFromSheet() is an internal helper function to open a
  95. // sheetN.xml file, refered to by an xlsx.xlsxSheet struct, from the XLSX
  96. // file and unmarshal it an xlsx.xlsxWorksheet struct
  97. func getWorksheetFromSheet(sheet xlsxSheet, worksheets map[string]*zip.File) (*xlsxWorksheet, error) {
  98. var rc io.ReadCloser
  99. var decoder *xml.Decoder
  100. var worksheet *xlsxWorksheet
  101. var error error
  102. var sheetName string
  103. worksheet = new(xlsxWorksheet)
  104. if sheet.SheetId != "" {
  105. sheetName = fmt.Sprintf("sheet%s", sheet.SheetId)
  106. } else {
  107. sheetName = fmt.Sprintf("sheet%s", sheet.Id)
  108. }
  109. f, ok := worksheets[sheetName]
  110. if !ok {
  111. // excel created from mac MsExcel,will have a sheets Id as "rId1",
  112. // but has a sheet file named "sheet1" and "_rels/sheet1.xml."
  113. // this work around will open it
  114. for sheetName, f = range worksheets {
  115. //do not want "_rels/sheet1.xml."
  116. if strings.Contains(sheetName, "_") {
  117. continue
  118. }
  119. break
  120. }
  121. if f == nil {
  122. return nil, fmt.Errorf("not found sheet file sheetId:%s", sheet.Id)
  123. }
  124. }
  125. rc, error = f.Open()
  126. if error != nil {
  127. return nil, error
  128. }
  129. decoder = xml.NewDecoder(rc)
  130. error = decoder.Decode(worksheet)
  131. if error != nil {
  132. return nil, error
  133. }
  134. return worksheet, nil
  135. }