file.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package xlsx
  2. import (
  3. "archive/zip"
  4. "encoding/xml"
  5. "fmt"
  6. )
  7. // File is a high level structure providing a slice of Sheet structs
  8. // to the user.
  9. type File struct {
  10. worksheets map[string]*zip.File
  11. referenceTable *RefTable
  12. styles *xlsxStyles
  13. Sheets map[string]*Sheet // sheet access by index
  14. }
  15. // Create a new File
  16. func NewFile() (file *File) {
  17. file = &File{};
  18. file.Sheets = make(map[string]*Sheet)
  19. return
  20. }
  21. // OpenFile() take the name of an XLSX file and returns a populated
  22. // xlsx.File struct for it.
  23. func OpenFile(filename string) (*File, error) {
  24. var f *zip.ReadCloser
  25. f, err := zip.OpenReader(filename)
  26. if err != nil {
  27. return nil, err
  28. }
  29. return ReadZip(f)
  30. }
  31. // Add a new Sheet, with the provided name, to a File
  32. func (f *File) AddSheet(sheetName string) (sheet *Sheet) {
  33. sheet = &Sheet{}
  34. f.Sheets[sheetName] = sheet
  35. return sheet
  36. }
  37. func (f *File) MarshallParts() (map[string]string, error) {
  38. var parts map[string]string
  39. var refTable *RefTable = NewSharedStringRefTable()
  40. var workbookRels WorkBookRels = make(WorkBookRels)
  41. var err error
  42. marshal := func(thing interface{}) (string, error) {
  43. body, err := xml.MarshalIndent(thing, " ", " ")
  44. if err != nil {
  45. return "", err
  46. }
  47. return xml.Header + string(body), nil
  48. }
  49. parts = make(map[string]string)
  50. sheetIndex := 1
  51. // _ here is sheet name.
  52. for _, sheet := range f.Sheets {
  53. xSheet := sheet.makeXLSXSheet(refTable)
  54. sheetId := fmt.Sprintf("rId%d", sheetIndex)
  55. sheetPath := fmt.Sprintf("worksheets/sheet%d.xml", sheetIndex)
  56. workbookRels[sheetId] = sheetPath
  57. parts[sheetPath], err = marshal(xSheet)
  58. if err != nil {
  59. return parts, err
  60. }
  61. sheetIndex++
  62. }
  63. parts[".rels"] = `<?xml version="1.0" encoding="UTF-8"?>
  64. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  65. <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
  66. <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
  67. <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  68. </Relationships>`
  69. parts["docProps/app.xml"] = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  70. <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
  71. <TotalTime>0</TotalTime>
  72. <Application>Go XLSX</Application>
  73. </Properties>`
  74. // TODO - do this properly, modification and revision information
  75. parts["docProps/core.xml"] = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  76. <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></cp:coreProperties>`
  77. xSST := refTable.makeXLSXSST()
  78. parts["xl/sharedStrings.xml"], err = marshal(xSST)
  79. sheetId := fmt.Sprintf("rId%d", sheetIndex)
  80. sheetPath := "sharedStrings.xml"
  81. workbookRels[sheetId] = sheetPath
  82. sheetIndex++
  83. if err != nil {
  84. return parts, err
  85. }
  86. xWRel := workbookRels.MakeXLSXWorkbookRels()
  87. parts["xl/_rels/workbook.xml.rels"], err = marshal(xWRel)
  88. if err != nil {
  89. return parts, err
  90. }
  91. return parts, nil
  92. }