file_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package xlsx
  2. import (
  3. "encoding/xml"
  4. "path/filepath"
  5. . "gopkg.in/check.v1"
  6. )
  7. type FileSuite struct {}
  8. var _ = Suite(&FileSuite{})
  9. // Test we can correctly open a XSLX file and return a xlsx.File
  10. // struct.
  11. func (l *FileSuite) TestOpenFile(c *C) {
  12. var xlsxFile *File
  13. var error error
  14. xlsxFile, error = OpenFile("testfile.xlsx")
  15. c.Assert(error, IsNil)
  16. c.Assert(xlsxFile, NotNil)
  17. }
  18. // Test we can create a File object from scratch
  19. func (l *FileSuite) TestCreateFile(c *C) {
  20. var xlsxFile *File
  21. xlsxFile = NewFile()
  22. c.Assert(xlsxFile, NotNil)
  23. }
  24. // Test that when we open a real XLSX file we create xlsx.Sheet
  25. // objects for the sheets inside the file and that these sheets are
  26. // themselves correct.
  27. func (l *FileSuite) TestCreateSheet(c *C) {
  28. var xlsxFile *File
  29. var err error
  30. var sheet *Sheet
  31. var row *Row
  32. xlsxFile, err = OpenFile("testfile.xlsx")
  33. c.Assert(err, IsNil)
  34. c.Assert(xlsxFile, NotNil)
  35. sheetLen := len(xlsxFile.Sheets)
  36. c.Assert(sheetLen, Equals, 3)
  37. sheet = xlsxFile.Sheets["Tabelle1"]
  38. rowLen := len(sheet.Rows)
  39. c.Assert(rowLen, Equals, 2)
  40. row = sheet.Rows[0]
  41. c.Assert(len(row.Cells), Equals, 2)
  42. cell := row.Cells[0]
  43. cellstring := cell.String()
  44. c.Assert(cellstring, Equals, "Foo")
  45. }
  46. // Test that we can add a sheet to a File
  47. func (l *FileSuite) TestAddSheet(c *C) {
  48. var f *File
  49. f = NewFile()
  50. sheet := f.AddSheet("MySheet")
  51. c.Assert(sheet, NotNil)
  52. c.Assert(len(f.Sheets), Equals, 1)
  53. c.Assert(f.Sheets["MySheet"], Equals, sheet)
  54. }
  55. // Test that we can create a Workbook and marshal it to XML.
  56. func (l *FileSuite) TestMarshalWorkbook(c *C) {
  57. var f *File
  58. f = NewFile()
  59. f.AddSheet("MyFirstSheet")
  60. f.AddSheet("MySecondSheet")
  61. workbook := f.makeWorkbook()
  62. workbook.Sheets.Sheet[0] = xlsxSheet{
  63. Name: "MyFirstSheet",
  64. SheetId: "1",
  65. Id: "rId1"}
  66. workbook.Sheets.Sheet[1] = xlsxSheet{
  67. Name: "MySecondSheet",
  68. SheetId: "2",
  69. Id: "rId2"}
  70. expectedWorkbook := `<?xml version="1.0" encoding="UTF-8"?>
  71. <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  72. <fileVersion appName="Go XLSX"></fileVersion>
  73. <workbookPr date1904="false"></workbookPr>
  74. <bookViews>
  75. <workbookView></workbookView>
  76. </bookViews>
  77. <sheets>
  78. <sheet name="MyFirstSheet" sheetId="1" xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id="rId1"></sheet>
  79. <sheet name="MySecondSheet" sheetId="2" xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id="rId2"></sheet>
  80. </sheets>
  81. <definedNames></definedNames>
  82. <calcPr></calcPr>
  83. </workbook>`
  84. output, err := xml.MarshalIndent(workbook, " ", " ")
  85. c.Assert(err, IsNil)
  86. stringOutput := xml.Header + string(output)
  87. c.Assert(stringOutput, Equals, expectedWorkbook)
  88. }
  89. // Test that we can marshall a File to a collection of xml files
  90. func (l *FileSuite) TestMarshalFile(c *C) {
  91. var f *File
  92. f = NewFile()
  93. sheet1 := f.AddSheet("MySheet")
  94. row1 := sheet1.AddRow()
  95. cell1 := row1.AddCell()
  96. cell1.Value = "A cell!"
  97. sheet2 := f.AddSheet("AnotherSheet")
  98. row2 := sheet2.AddRow()
  99. cell2 := row2.AddCell()
  100. cell2.Value = "A cell!"
  101. parts, err := f.MarshallParts()
  102. c.Assert(err, IsNil)
  103. c.Assert(len(parts), Equals, 10)
  104. // sheets
  105. expectedSheet := `<?xml version="1.0" encoding="UTF-8"?>
  106. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  107. <dimension ref="A1:A1"></dimension>
  108. <sheetData>
  109. <row r="1">
  110. <c r="A1" t="s">
  111. <v>0</v>
  112. </c>
  113. </row>
  114. </sheetData>
  115. </worksheet>`
  116. c.Assert(parts["xl/worksheets/sheet1.xml"], Equals, expectedSheet)
  117. c.Assert(parts["xl/worksheets/sheet2.xml"], Equals, expectedSheet)
  118. // .rels.xml
  119. expectedRels := `<?xml version="1.0" encoding="UTF-8"?>
  120. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  121. <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
  122. <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
  123. <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  124. </Relationships>`
  125. c.Assert(parts["_rels/.rels"], Equals, expectedRels)
  126. // app.xml
  127. expectedApp := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  128. <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
  129. <TotalTime>0</TotalTime>
  130. <Application>Go XLSX</Application>
  131. </Properties>`
  132. c.Assert(parts["docProps/app.xml"], Equals, expectedApp)
  133. // core.xml
  134. expectedCore := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  135. <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>`
  136. c.Assert(parts["docProps/core.xml"], Equals, expectedCore)
  137. // sharedStrings.xml
  138. expectedXLSXSST := `<?xml version="1.0" encoding="UTF-8"?>
  139. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1">
  140. <si>
  141. <t>A cell!</t>
  142. </si>
  143. </sst>`
  144. c.Assert(parts["xl/sharedStrings.xml"], Equals, expectedXLSXSST)
  145. // workbook.xml.rels
  146. expectedXLSXWorkbookRels := `<?xml version="1.0" encoding="UTF-8"?>
  147. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  148. <Relationship Id="rId1" Target="worksheets/sheet1.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"></Relationship>
  149. <Relationship Id="rId2" Target="worksheets/sheet2.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"></Relationship>
  150. <Relationship Id="rId3" Target="sharedStrings.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"></Relationship>
  151. <Relationship Id="rId4" Target="styles.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"></Relationship>
  152. </Relationships>`
  153. c.Assert(parts["xl/_rels/workbook.xml.rels"], Equals, expectedXLSXWorkbookRels)
  154. // workbook.xml
  155. expectedWorkbook := `<?xml version="1.0" encoding="UTF-8"?>
  156. <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  157. <fileVersion appName="Go XLSX"></fileVersion>
  158. <workbookPr date1904="false"></workbookPr>
  159. <bookViews>
  160. <workbookView></workbookView>
  161. </bookViews>
  162. <sheets>
  163. <sheet name="MySheet" sheetId="1" xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id="rId1"></sheet>
  164. <sheet name="AnotherSheet" sheetId="2" xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id="rId2"></sheet>
  165. </sheets>
  166. <definedNames></definedNames>
  167. <calcPr></calcPr>
  168. </workbook>`
  169. c.Assert(parts["xl/workbook.xml"], Equals, expectedWorkbook)
  170. // [Content_Types].xml
  171. expectedContentTypes := `<?xml version="1.0" encoding="UTF-8"?>
  172. <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  173. <Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"></Override>
  174. <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"></Override>
  175. <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"></Override>
  176. <Override PartName="/xl/_rels/workbook.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"></Override>
  177. <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"></Override>
  178. <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"></Override>
  179. <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"></Override>
  180. <Override PartName="xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"></Override>
  181. <Override PartName="xl/worksheets/sheet2.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"></Override>
  182. <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"></Default>
  183. <Default Extension="xml" ContentType="application/xml"></Default>
  184. </Types>`
  185. c.Assert(parts["[Content_Types].xml"], Equals, expectedContentTypes)
  186. // styles.xml
  187. //
  188. // For now we only allow simple string data in the
  189. // spreadsheet. Style support will follow.
  190. expectedStyles := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  191. <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  192. </styleSheet>`
  193. c.Assert(parts["xl/styles.xml"], Equals, expectedStyles)
  194. }
  195. // We can save a File as a valid XLSX file at a given path.
  196. func (l *FileSuite) TestSaveFile(c *C) {
  197. var tmpPath string = c.MkDir()
  198. var f *File
  199. f = NewFile()
  200. sheet1 := f.AddSheet("MySheet")
  201. row1 := sheet1.AddRow()
  202. cell1 := row1.AddCell()
  203. cell1.Value = "A cell!"
  204. sheet2 := f.AddSheet("AnotherSheet")
  205. row2 := sheet2.AddRow()
  206. cell2 := row2.AddCell()
  207. cell2.Value = "A cell!"
  208. xlsxPath := filepath.Join(tmpPath, "TestSaveFile.xlsx")
  209. err := f.Save(xlsxPath)
  210. c.Assert(err, IsNil)
  211. // Let's eat our own dog food
  212. xlsxFile, err := OpenFile(xlsxPath)
  213. c.Assert(err, IsNil)
  214. c.Assert(xlsxFile, NotNil)
  215. c.Assert(len(xlsxFile.Sheets), Equals, 2)
  216. sheet1, ok := xlsxFile.Sheets["MySheet"]
  217. c.Assert(ok, Equals, true)
  218. c.Assert(len(sheet1.Rows), Equals, 1)
  219. row1 = sheet1.Rows[0]
  220. c.Assert(len(row1.Cells), Equals, 1)
  221. cell1 = row1.Cells[0]
  222. c.Assert(cell1.Value, Equals, "A cell!")
  223. c.Assert(cell1.String(), Equals, "A cell!")
  224. }