lib_test.go 18 KB

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