lib_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. package xlsx
  2. import (
  3. "bytes"
  4. "encoding/xml"
  5. // "strconv"
  6. . "gopkg.in/check.v1"
  7. "strings"
  8. )
  9. type LibSuite struct{}
  10. var _ = Suite(&LibSuite{})
  11. // Test that we can correctly extract a reference table from the
  12. // sharedStrings.xml file embedded in the XLSX file and return a
  13. // reference table of string values from it.
  14. func (l *LibSuite) TestReadSharedStringsFromZipFile(c *C) {
  15. var xlsxFile *File
  16. var err error
  17. xlsxFile, err = OpenFile("testfile.xlsx")
  18. c.Assert(err, IsNil)
  19. c.Assert(xlsxFile.referenceTable, NotNil)
  20. }
  21. // Helper function used to test contents of a given xlsxXf against
  22. // expectations.
  23. func testXf(c *C, result, expected *xlsxXf) {
  24. c.Assert(result.ApplyAlignment, Equals, expected.ApplyAlignment)
  25. c.Assert(result.ApplyBorder, Equals, expected.ApplyBorder)
  26. c.Assert(result.ApplyFont, Equals, expected.ApplyFont)
  27. c.Assert(result.ApplyFill, Equals, expected.ApplyFill)
  28. c.Assert(result.ApplyProtection, Equals, expected.ApplyProtection)
  29. c.Assert(result.BorderId, Equals, expected.BorderId)
  30. c.Assert(result.FillId, Equals, expected.FillId)
  31. c.Assert(result.FontId, Equals, expected.FontId)
  32. c.Assert(result.NumFmtId, Equals, expected.NumFmtId)
  33. }
  34. // We can correctly extract a style table from the style.xml file
  35. // embedded in the XLSX file and return a styles struct from it.
  36. func (l *LibSuite) TestReadStylesFromZipFile(c *C) {
  37. var xlsxFile *File
  38. var err error
  39. var fontCount, fillCount, borderCount, cellStyleXfCount, cellXfCount int
  40. var font xlsxFont
  41. var fill xlsxFill
  42. var border xlsxBorder
  43. var xf xlsxXf
  44. xlsxFile, err = OpenFile("testfile.xlsx")
  45. c.Assert(err, IsNil)
  46. c.Assert(xlsxFile.styles, NotNil)
  47. fontCount = len(xlsxFile.styles.Fonts)
  48. c.Assert(fontCount, Equals, 4)
  49. font = xlsxFile.styles.Fonts[0]
  50. c.Assert(font.Sz.Val, Equals, "11")
  51. c.Assert(font.Name.Val, Equals, "Calibri")
  52. fillCount = len(xlsxFile.styles.Fills)
  53. c.Assert(fillCount, Equals, 3)
  54. fill = xlsxFile.styles.Fills[2]
  55. c.Assert(fill.PatternFill.PatternType, Equals, "solid")
  56. borderCount = len(xlsxFile.styles.Borders)
  57. c.Assert(borderCount, Equals, 2)
  58. border = xlsxFile.styles.Borders[1]
  59. c.Assert(border.Left.Style, Equals, "thin")
  60. c.Assert(border.Right.Style, Equals, "thin")
  61. c.Assert(border.Top.Style, Equals, "thin")
  62. c.Assert(border.Bottom.Style, Equals, "thin")
  63. cellStyleXfCount = len(xlsxFile.styles.CellStyleXfs)
  64. c.Assert(cellStyleXfCount, Equals, 20)
  65. xf = xlsxFile.styles.CellStyleXfs[0]
  66. expectedXf := &xlsxXf{
  67. ApplyAlignment: true,
  68. ApplyBorder: true,
  69. ApplyFont: true,
  70. ApplyFill: false,
  71. ApplyProtection: true,
  72. BorderId: 0,
  73. FillId: 0,
  74. FontId: 0,
  75. NumFmtId: 164}
  76. testXf(c, &xf, expectedXf)
  77. cellXfCount = len(xlsxFile.styles.CellXfs)
  78. c.Assert(cellXfCount, Equals, 3)
  79. xf = xlsxFile.styles.CellXfs[0]
  80. expectedXf = &xlsxXf{
  81. ApplyAlignment: false,
  82. ApplyBorder: false,
  83. ApplyFont: false,
  84. ApplyFill: false,
  85. ApplyProtection: false,
  86. BorderId: 0,
  87. FillId: 0,
  88. FontId: 0,
  89. NumFmtId: 164}
  90. testXf(c, &xf, expectedXf)
  91. }
  92. // We can correctly extract a map of relationship Ids to the worksheet files in
  93. // which they are contained from the XLSX file.
  94. func (l *LibSuite) TestReadWorkbookRelationsFromZipFile(c *C) {
  95. var xlsxFile *File
  96. var err error
  97. xlsxFile, err = OpenFile("testfile.xlsx")
  98. c.Assert(err, IsNil)
  99. c.Assert(len(xlsxFile.Sheets), Equals, 3)
  100. sheet, ok := xlsxFile.Sheets["Tabelle1"]
  101. c.Assert(ok, Equals, true)
  102. c.Assert(sheet, NotNil)
  103. }
  104. // which they are contained from the XLSX file, even when the
  105. // worksheet files have arbitrary, non-numeric names.
  106. func (l *LibSuite) TestReadWorkbookRelationsFromZipFileWithFunnyNames(c *C) {
  107. var xlsxFile *File
  108. var err error
  109. xlsxFile, err = OpenFile("testrels.xlsx")
  110. c.Assert(err, IsNil)
  111. bob := xlsxFile.Sheets["Bob"]
  112. row1 := bob.Rows[0]
  113. cell1 := row1.Cells[0]
  114. c.Assert(cell1.String(), Equals, "I am Bob")
  115. }
  116. // We can marshal WorkBookRels to an xml file
  117. func (l *LibSuite) TestWorkBookRelsMarshal(c *C) {
  118. var rels WorkBookRels = make(WorkBookRels)
  119. rels["rId1"] = "worksheets/sheet.xml"
  120. expectedXML := `<?xml version="1.0" encoding="UTF-8"?>
  121. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  122. <Relationship Id="rId1" Target="worksheets/sheet.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"></Relationship>
  123. </Relationships>`
  124. xRels := rels.MakeXLSXWorkbookRels()
  125. output := bytes.NewBufferString(xml.Header)
  126. body, err := xml.MarshalIndent(xRels, " ", " ")
  127. c.Assert(err, IsNil)
  128. c.Assert(body, NotNil)
  129. _, err = output.Write(body)
  130. c.Assert(err, IsNil)
  131. c.Assert(output.String(), Equals, expectedXML)
  132. }
  133. // Excel column codes are a special form of base26 that doesn't allow
  134. // zeros, except in the least significant part of the code. Test we
  135. // can smoosh the numbers in a normal base26 representation (presented
  136. // as a slice of integers) down to this form.
  137. func (l *LibSuite) TestSmooshBase26Slice(c *C) {
  138. input := []int{20, 0, 1}
  139. expected := []int{19, 26, 1}
  140. c.Assert(smooshBase26Slice(input), DeepEquals, expected)
  141. }
  142. // formatColumnName converts slices of base26 integers to alphabetical
  143. // column names. Note that the least signifcant character has a
  144. // different numeric offset (Yuck!)
  145. func (l *LibSuite) TestFormatColumnName(c *C) {
  146. c.Assert(formatColumnName([]int{0}), Equals, "A")
  147. c.Assert(formatColumnName([]int{25}), Equals, "Z")
  148. c.Assert(formatColumnName([]int{1, 25}), Equals, "AZ")
  149. c.Assert(formatColumnName([]int{26, 25}), Equals, "ZZ")
  150. c.Assert(formatColumnName([]int{26, 26, 25}), Equals, "ZZZ")
  151. }
  152. // getLargestDenominator returns the largest power of a provided value
  153. // that can fit within a given value.
  154. func (l *LibSuite) TestGetLargestDenominator(c *C) {
  155. d, p := getLargestDenominator(0, 1, 2, 0)
  156. c.Assert(d, Equals, 1)
  157. c.Assert(p, Equals, 0)
  158. d, p = getLargestDenominator(1, 1, 2, 0)
  159. c.Assert(d, Equals, 1)
  160. c.Assert(p, Equals, 0)
  161. d, p = getLargestDenominator(2, 1, 2, 0)
  162. c.Assert(d, Equals, 2)
  163. c.Assert(p, Equals, 1)
  164. d, p = getLargestDenominator(4, 1, 2, 0)
  165. c.Assert(d, Equals, 4)
  166. c.Assert(p, Equals, 2)
  167. d, p = getLargestDenominator(8, 1, 2, 0)
  168. c.Assert(d, Equals, 8)
  169. c.Assert(p, Equals, 3)
  170. d, p = getLargestDenominator(9, 1, 2, 0)
  171. c.Assert(d, Equals, 8)
  172. c.Assert(p, Equals, 3)
  173. d, p = getLargestDenominator(15,1, 2, 0)
  174. c.Assert(d, Equals, 8)
  175. c.Assert(p, Equals, 3)
  176. d, p = getLargestDenominator(16,1, 2, 0)
  177. c.Assert(d, Equals, 16)
  178. c.Assert(p, Equals, 4)
  179. }
  180. func (l *LibSuite) TestLettersToNumeric(c *C) {
  181. cases := map[string]int{"A": 0, "G": 6, "z": 25, "AA": 26, "Az": 51,
  182. "BA": 52, "BZ": 77, "ZA": 26*26 + 0, "ZZ": 26*26 + 25,
  183. "AAA": 26*26 + 26 + 0, "AMI": 1022}
  184. for input, ans := range cases {
  185. output := lettersToNumeric(input)
  186. c.Assert(output, Equals, ans)
  187. }
  188. }
  189. func (l *LibSuite) TestNumericToLetters(c *C) {
  190. cases := map[string]int{
  191. "A": 0,
  192. "G": 6,
  193. "Z": 25,
  194. "AA": 26,
  195. "AZ": 51,
  196. "BA": 52,
  197. "BZ": 77, "ZA": 26*26, "ZB": 26*26 + 1,
  198. "ZZ": 26*26 + 25,
  199. "AAA": 26*26 + 26 + 0, "AMI": 1022}
  200. for ans, input := range cases {
  201. output := numericToLetters(input)
  202. c.Assert(output, Equals, ans)
  203. }
  204. }
  205. func (l *LibSuite) TestLetterOnlyMapFunction(c *C) {
  206. var input string = "ABC123"
  207. var output string = strings.Map(letterOnlyMapF, input)
  208. c.Assert(output, Equals, "ABC")
  209. input = "abc123"
  210. output = strings.Map(letterOnlyMapF, input)
  211. c.Assert(output, Equals, "ABC")
  212. }
  213. func (l *LibSuite) TestIntOnlyMapFunction(c *C) {
  214. var input string = "ABC123"
  215. var output string = strings.Map(intOnlyMapF, input)
  216. c.Assert(output, Equals, "123")
  217. }
  218. func (l *LibSuite) TestGetCoordsFromCellIDString(c *C) {
  219. var cellIDString string = "A3"
  220. var x, y int
  221. var err error
  222. x, y, err = getCoordsFromCellIDString(cellIDString)
  223. c.Assert(err, IsNil)
  224. c.Assert(x, Equals, 0)
  225. c.Assert(y, Equals, 2)
  226. }
  227. func (l *LibSuite) TestGetCellIDStringFromCoords(c *C){
  228. c.Assert(getCellIDStringFromCoords(0, 0), Equals, "A1")
  229. c.Assert(getCellIDStringFromCoords(2, 2), Equals, "C3")
  230. }
  231. func (l *LibSuite) TestGetMaxMinFromDimensionRef(c *C) {
  232. var dimensionRef string = "A1:B2"
  233. var minx, miny, maxx, maxy int
  234. var err error
  235. minx, miny, maxx, maxy, err = getMaxMinFromDimensionRef(dimensionRef)
  236. c.Assert(err, IsNil)
  237. c.Assert(minx, Equals, 0)
  238. c.Assert(miny, Equals, 0)
  239. c.Assert(maxx, Equals, 1)
  240. c.Assert(maxy, Equals, 1)
  241. }
  242. func (l *LibSuite) TestGetRangeFromString(c *C) {
  243. var rangeString string
  244. var lower, upper int
  245. var err error
  246. rangeString = "1:3"
  247. lower, upper, err = getRangeFromString(rangeString)
  248. c.Assert(err, IsNil)
  249. c.Assert(lower, Equals, 1)
  250. c.Assert(upper, Equals, 3)
  251. }
  252. func (l *LibSuite) TestMakeRowFromSpan(c *C) {
  253. var rangeString string
  254. var row *Row
  255. var length int
  256. rangeString = "1:3"
  257. row = makeRowFromSpan(rangeString)
  258. length = len(row.Cells)
  259. c.Assert(length, Equals, 3)
  260. rangeString = "5:7" // Note - we ignore lower bound!
  261. row = makeRowFromSpan(rangeString)
  262. length = len(row.Cells)
  263. c.Assert(length, Equals, 7)
  264. rangeString = "1:1"
  265. row = makeRowFromSpan(rangeString)
  266. length = len(row.Cells)
  267. c.Assert(length, Equals, 1)
  268. }
  269. func (l *LibSuite) TestReadRowsFromSheet(c *C) {
  270. var sharedstringsXML = bytes.NewBufferString(`
  271. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  272. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  273. <si>
  274. <t>Foo</t>
  275. </si>
  276. <si>
  277. <t>Bar</t>
  278. </si>
  279. <si>
  280. <t xml:space="preserve">Baz </t>
  281. </si>
  282. <si>
  283. <t>Quuk</t>
  284. </si>
  285. </sst>`)
  286. var sheetxml = bytes.NewBufferString(`
  287. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  288. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  289. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  290. <dimension ref="A1:B2"/>
  291. <sheetViews>
  292. <sheetView tabSelected="1" workbookViewId="0">
  293. <selection activeCell="C2" sqref="C2"/>
  294. </sheetView>
  295. </sheetViews>
  296. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  297. <sheetData>
  298. <row r="1" spans="1:2">
  299. <c r="A1" t="s">
  300. <v>0</v>
  301. </c>
  302. <c r="B1" t="s">
  303. <v>1</v>
  304. </c>
  305. </row>
  306. <row r="2" spans="1:2">
  307. <c r="A2" t="s">
  308. <v>2</v>
  309. </c>
  310. <c r="B2" t="s">
  311. <v>3</v>
  312. </c>
  313. </row>
  314. </sheetData>
  315. <pageMargins left="0.7" right="0.7"
  316. top="0.78740157499999996"
  317. bottom="0.78740157499999996"
  318. header="0.3"
  319. footer="0.3"/>
  320. </worksheet>`)
  321. worksheet := new(xlsxWorksheet)
  322. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  323. c.Assert(err, IsNil)
  324. sst := new(xlsxSST)
  325. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  326. c.Assert(err, IsNil)
  327. file := new(File)
  328. file.referenceTable = MakeSharedStringRefTable(sst)
  329. rows, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  330. c.Assert(maxRows, Equals, 2)
  331. c.Assert(maxCols, Equals, 2)
  332. row := rows[0]
  333. c.Assert(len(row.Cells), Equals, 2)
  334. cell1 := row.Cells[0]
  335. c.Assert(cell1.String(), Equals, "Foo")
  336. cell2 := row.Cells[1]
  337. c.Assert(cell2.String(), Equals, "Bar")
  338. }
  339. func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyRows(c *C) {
  340. var sharedstringsXML = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  341. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2"><si><t>ABC</t></si><si><t>DEF</t></si></sst>`)
  342. var sheetxml = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  343. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
  344. <dimension ref="A4:A5"/>
  345. <sheetViews>
  346. <sheetView tabSelected="1" workbookViewId="0">
  347. <selection activeCell="A2" sqref="A2"/>
  348. </sheetView>
  349. </sheetViews>
  350. <sheetFormatPr baseColWidth="10" defaultRowHeight="15" x14ac:dyDescent="0"/>
  351. <sheetData>
  352. <row r="4" spans="1:1">
  353. <c r="A4" t="s">
  354. <v>0</v>
  355. </c>
  356. </row>
  357. <row r="5" spans="1:1">
  358. <c r="A5" t="s">
  359. <v>1</v>
  360. </c>
  361. </row>
  362. </sheetData>
  363. <pageMargins left="0.75" right="0.75" top="1" bottom="1" header="0.5" footer="0.5"/>
  364. <pageSetup paperSize="9" orientation="portrait" horizontalDpi="4294967292" verticalDpi="4294967292"/>
  365. <extLst>
  366. <ext uri="{64002731-A6B0-56B0-2670-7721B7C09600}" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main">
  367. <mx:PLV Mode="0" OnePage="0" WScale="0"/>
  368. </ext>
  369. </extLst>
  370. </worksheet>
  371. `)
  372. worksheet := new(xlsxWorksheet)
  373. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  374. c.Assert(err, IsNil)
  375. sst := new(xlsxSST)
  376. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  377. c.Assert(err, IsNil)
  378. file := new(File)
  379. file.referenceTable = MakeSharedStringRefTable(sst)
  380. _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  381. c.Assert(maxRows, Equals, 2)
  382. c.Assert(maxCols, Equals, 1)
  383. }
  384. func (l *LibSuite) TestReadRowsFromSheetWithEmptyCells(c *C) {
  385. var sharedstringsXML = bytes.NewBufferString(`
  386. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  387. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="8" uniqueCount="5">
  388. <si>
  389. <t>Bob</t>
  390. </si>
  391. <si>
  392. <t>Alice</t>
  393. </si>
  394. <si>
  395. <t>Sue</t>
  396. </si>
  397. <si>
  398. <t>Yes</t>
  399. </si>
  400. <si>
  401. <t>No</t>
  402. </si>
  403. </sst>
  404. `)
  405. var sheetxml = bytes.NewBufferString(`
  406. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  407. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><dimension ref="A1:C3"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"><selection activeCell="D3" sqref="D3"/></sheetView></sheetViews><sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  408. <sheetData>
  409. <row r="1" spans="1:3">
  410. <c r="A1" t="s">
  411. <v>
  412. 0
  413. </v>
  414. </c>
  415. <c r="B1" t="s">
  416. <v>
  417. 1
  418. </v>
  419. </c>
  420. <c r="C1" t="s">
  421. <v>
  422. 2
  423. </v>
  424. </c>
  425. </row>
  426. <row r="2" spans="1:3">
  427. <c r="A2" t="s">
  428. <v>
  429. 3
  430. </v>
  431. </c>
  432. <c r="B2" t="s">
  433. <v>
  434. 4
  435. </v>
  436. </c>
  437. <c r="C2" t="s">
  438. <v>
  439. 3
  440. </v>
  441. </c>
  442. </row>
  443. <row r="3" spans="1:3">
  444. <c r="A3" t="s">
  445. <v>
  446. 4
  447. </v>
  448. </c>
  449. <c r="C3" t="s">
  450. <v>
  451. 3
  452. </v>
  453. </c>
  454. </row>
  455. </sheetData>
  456. <pageMargins left="0.7" right="0.7" top="0.78740157499999996" bottom="0.78740157499999996" header="0.3" footer="0.3"/>
  457. </worksheet>
  458. `)
  459. worksheet := new(xlsxWorksheet)
  460. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  461. c.Assert(err, IsNil)
  462. sst := new(xlsxSST)
  463. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  464. c.Assert(err, IsNil)
  465. file := new(File)
  466. file.referenceTable = MakeSharedStringRefTable(sst)
  467. rows, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  468. c.Assert(maxRows, Equals, 3)
  469. c.Assert(maxCols, Equals, 3)
  470. row := rows[2]
  471. c.Assert(len(row.Cells), Equals, 3)
  472. cell1 := row.Cells[0]
  473. c.Assert(cell1.String(), Equals, "No")
  474. cell2 := row.Cells[1]
  475. c.Assert(cell2.String(), Equals, "")
  476. cell3 := row.Cells[2]
  477. c.Assert(cell3.String(), Equals, "Yes")
  478. }
  479. func (l *LibSuite) TestReadRowsFromSheetWithTrailingEmptyCells(c *C) {
  480. var row *Row
  481. var cell1, cell2, cell3, cell4 *Cell
  482. var sharedstringsXML = bytes.NewBufferString(`
  483. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  484. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4"><si><t>A</t></si><si><t>B</t></si><si><t>C</t></si><si><t>D</t></si></sst>`)
  485. var sheetxml = bytes.NewBufferString(`
  486. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  487. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><dimension ref="A1:D8"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"><selection activeCell="A7" sqref="A7"/></sheetView></sheetViews><sheetFormatPr baseColWidth="10" defaultRowHeight="15"/><sheetData><row r="1" spans="1:4"><c r="A1" t="s"><v>0</v></c><c r="B1" t="s"><v>1</v></c><c r="C1" t="s"><v>2</v></c><c r="D1" t="s"><v>3</v></c></row><row r="2" spans="1:4"><c r="A2"><v>1</v></c></row><row r="3" spans="1:4"><c r="B3"><v>1</v></c></row><row r="4" spans="1:4"><c r="C4"><v>1</v></c></row><row r="5" spans="1:4"><c r="D5"><v>1</v></c></row><row r="6" spans="1:4"><c r="C6"><v>1</v></c></row><row r="7" spans="1:4"><c r="B7"><v>1</v></c></row><row r="8" spans="1:4"><c r="A8"><v>1</v></c></row></sheetData><pageMargins left="0.7" right="0.7" top="0.78740157499999996" bottom="0.78740157499999996" header="0.3" footer="0.3"/></worksheet>
  488. `)
  489. worksheet := new(xlsxWorksheet)
  490. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  491. c.Assert(err, IsNil)
  492. sst := new(xlsxSST)
  493. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  494. c.Assert(err, IsNil)
  495. file := new(File)
  496. file.referenceTable = MakeSharedStringRefTable(sst)
  497. rows, maxCol, maxRow := readRowsFromSheet(worksheet, file)
  498. c.Assert(maxCol, Equals, 4)
  499. c.Assert(maxRow, Equals, 8)
  500. row = rows[0]
  501. c.Assert(len(row.Cells), Equals, 4)
  502. cell1 = row.Cells[0]
  503. c.Assert(cell1.String(), Equals, "A")
  504. cell2 = row.Cells[1]
  505. c.Assert(cell2.String(), Equals, "B")
  506. cell3 = row.Cells[2]
  507. c.Assert(cell3.String(), Equals, "C")
  508. cell4 = row.Cells[3]
  509. c.Assert(cell4.String(), Equals, "D")
  510. row = rows[1]
  511. c.Assert(len(row.Cells), Equals, 4)
  512. cell1 = row.Cells[0]
  513. c.Assert(cell1.String(), Equals, "1")
  514. cell2 = row.Cells[1]
  515. c.Assert(cell2.String(), Equals, "")
  516. cell3 = row.Cells[2]
  517. c.Assert(cell3.String(), Equals, "")
  518. cell4 = row.Cells[3]
  519. c.Assert(cell4.String(), Equals, "")
  520. }