lib_test.go 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  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. // which they are contained from the XLSX file, even when the
  12. // worksheet files have arbitrary, non-numeric names.
  13. func (l *LibSuite) TestReadWorkbookRelationsFromZipFileWithFunnyNames(c *C) {
  14. var xlsxFile *File
  15. var err error
  16. xlsxFile, err = OpenFile("./testdocs/testrels.xlsx")
  17. c.Assert(err, IsNil)
  18. bob := xlsxFile.Sheet["Bob"]
  19. row1 := bob.Rows[0]
  20. cell1 := row1.Cells[0]
  21. c.Assert(cell1.String(), Equals, "I am Bob")
  22. }
  23. // We can marshal WorkBookRels to an xml file
  24. func (l *LibSuite) TestWorkBookRelsMarshal(c *C) {
  25. var rels WorkBookRels = make(WorkBookRels)
  26. rels["rId1"] = "worksheets/sheet.xml"
  27. expectedXML := `<?xml version="1.0" encoding="UTF-8"?>
  28. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Target="worksheets/sheet.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"></Relationship><Relationship Id="rId2" Target="sharedStrings.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"></Relationship><Relationship Id="rId3" Target="theme/theme1.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"></Relationship><Relationship Id="rId4" Target="styles.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"></Relationship></Relationships>`
  29. xRels := rels.MakeXLSXWorkbookRels()
  30. output := bytes.NewBufferString(xml.Header)
  31. body, err := xml.Marshal(xRels)
  32. c.Assert(err, IsNil)
  33. c.Assert(body, NotNil)
  34. _, err = output.Write(body)
  35. c.Assert(err, IsNil)
  36. c.Assert(output.String(), Equals, expectedXML)
  37. }
  38. // Excel column codes are a special form of base26 that doesn't allow
  39. // zeros, except in the least significant part of the code. Test we
  40. // can smoosh the numbers in a normal base26 representation (presented
  41. // as a slice of integers) down to this form.
  42. func (l *LibSuite) TestSmooshBase26Slice(c *C) {
  43. input := []int{20, 0, 1}
  44. expected := []int{19, 26, 1}
  45. c.Assert(smooshBase26Slice(input), DeepEquals, expected)
  46. }
  47. // formatColumnName converts slices of base26 integers to alphabetical
  48. // column names. Note that the least signifcant character has a
  49. // different numeric offset (Yuck!)
  50. func (l *LibSuite) TestFormatColumnName(c *C) {
  51. c.Assert(formatColumnName([]int{0}), Equals, "A")
  52. c.Assert(formatColumnName([]int{25}), Equals, "Z")
  53. c.Assert(formatColumnName([]int{1, 25}), Equals, "AZ")
  54. c.Assert(formatColumnName([]int{26, 25}), Equals, "ZZ")
  55. c.Assert(formatColumnName([]int{26, 26, 25}), Equals, "ZZZ")
  56. }
  57. // getLargestDenominator returns the largest power of a provided value
  58. // that can fit within a given value.
  59. func (l *LibSuite) TestGetLargestDenominator(c *C) {
  60. d, p := getLargestDenominator(0, 1, 2, 0)
  61. c.Assert(d, Equals, 1)
  62. c.Assert(p, Equals, 0)
  63. d, p = getLargestDenominator(1, 1, 2, 0)
  64. c.Assert(d, Equals, 1)
  65. c.Assert(p, Equals, 0)
  66. d, p = getLargestDenominator(2, 1, 2, 0)
  67. c.Assert(d, Equals, 2)
  68. c.Assert(p, Equals, 1)
  69. d, p = getLargestDenominator(4, 1, 2, 0)
  70. c.Assert(d, Equals, 4)
  71. c.Assert(p, Equals, 2)
  72. d, p = getLargestDenominator(8, 1, 2, 0)
  73. c.Assert(d, Equals, 8)
  74. c.Assert(p, Equals, 3)
  75. d, p = getLargestDenominator(9, 1, 2, 0)
  76. c.Assert(d, Equals, 8)
  77. c.Assert(p, Equals, 3)
  78. d, p = getLargestDenominator(15, 1, 2, 0)
  79. c.Assert(d, Equals, 8)
  80. c.Assert(p, Equals, 3)
  81. d, p = getLargestDenominator(16, 1, 2, 0)
  82. c.Assert(d, Equals, 16)
  83. c.Assert(p, Equals, 4)
  84. }
  85. func (l *LibSuite) TestLettersToNumeric(c *C) {
  86. cases := map[string]int{"A": 0, "G": 6, "z": 25, "AA": 26, "Az": 51,
  87. "BA": 52, "BZ": 77, "ZA": 26*26 + 0, "ZZ": 26*26 + 25,
  88. "AAA": 26*26 + 26 + 0, "AMI": 1022}
  89. for input, ans := range cases {
  90. output := lettersToNumeric(input)
  91. c.Assert(output, Equals, ans)
  92. }
  93. }
  94. func (l *LibSuite) TestNumericToLetters(c *C) {
  95. cases := map[string]int{
  96. "A": 0,
  97. "G": 6,
  98. "Z": 25,
  99. "AA": 26,
  100. "AZ": 51,
  101. "BA": 52,
  102. "BZ": 77, "ZA": 26 * 26, "ZB": 26*26 + 1,
  103. "ZZ": 26*26 + 25,
  104. "AAA": 26*26 + 26 + 0, "AMI": 1022}
  105. for ans, input := range cases {
  106. output := numericToLetters(input)
  107. c.Assert(output, Equals, ans)
  108. }
  109. }
  110. func (l *LibSuite) TestLetterOnlyMapFunction(c *C) {
  111. var input string = "ABC123"
  112. var output string = strings.Map(letterOnlyMapF, input)
  113. c.Assert(output, Equals, "ABC")
  114. input = "abc123"
  115. output = strings.Map(letterOnlyMapF, input)
  116. c.Assert(output, Equals, "ABC")
  117. }
  118. func (l *LibSuite) TestIntOnlyMapFunction(c *C) {
  119. var input string = "ABC123"
  120. var output string = strings.Map(intOnlyMapF, input)
  121. c.Assert(output, Equals, "123")
  122. }
  123. func (l *LibSuite) TestGetCoordsFromCellIDString(c *C) {
  124. var cellIDString string = "A3"
  125. var x, y int
  126. var err error
  127. x, y, err = getCoordsFromCellIDString(cellIDString)
  128. c.Assert(err, IsNil)
  129. c.Assert(x, Equals, 0)
  130. c.Assert(y, Equals, 2)
  131. }
  132. func (l *LibSuite) TestGetCellIDStringFromCoords(c *C) {
  133. c.Assert(getCellIDStringFromCoords(0, 0), Equals, "A1")
  134. c.Assert(getCellIDStringFromCoords(2, 2), Equals, "C3")
  135. }
  136. func (l *LibSuite) TestGetMaxMinFromDimensionRef(c *C) {
  137. var dimensionRef string = "A1:B2"
  138. var minx, miny, maxx, maxy int
  139. var err error
  140. minx, miny, maxx, maxy, err = getMaxMinFromDimensionRef(dimensionRef)
  141. c.Assert(err, IsNil)
  142. c.Assert(minx, Equals, 0)
  143. c.Assert(miny, Equals, 0)
  144. c.Assert(maxx, Equals, 1)
  145. c.Assert(maxy, Equals, 1)
  146. }
  147. func (l *LibSuite) TestCalculateMaxMinFromWorksheet(c *C) {
  148. var sheetxml = bytes.NewBufferString(`
  149. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  150. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  151. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
  152. xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main"
  153. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  154. xmlns:mv="urn:schemas-microsoft-com:mac:vml"
  155. xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
  156. xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"
  157. xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main">
  158. <sheetViews>
  159. <sheetView workbookViewId="0"/>
  160. </sheetViews>
  161. <sheetFormatPr customHeight="1" defaultColWidth="14.43" defaultRowHeight="15.75"/>
  162. <sheetData>
  163. <row r="1">
  164. <c t="s" s="1" r="A1">
  165. <v>0</v>
  166. </c>
  167. <c t="s" s="1" r="B1">
  168. <v>1</v>
  169. </c>
  170. </row>
  171. <row r="2">
  172. <c t="s" s="1" r="A2">
  173. <v>2</v>
  174. </c>
  175. <c t="s" s="1" r="B2">
  176. <v>3</v>
  177. </c>
  178. </row>
  179. </sheetData>
  180. <drawing r:id="rId1"/>
  181. </worksheet>`)
  182. worksheet := new(xlsxWorksheet)
  183. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  184. c.Assert(err, IsNil)
  185. minx, miny, maxx, maxy, err := calculateMaxMinFromWorksheet(worksheet)
  186. c.Assert(err, IsNil)
  187. c.Assert(minx, Equals, 0)
  188. c.Assert(miny, Equals, 0)
  189. c.Assert(maxx, Equals, 1)
  190. c.Assert(maxy, Equals, 1)
  191. }
  192. func (l *LibSuite) TestGetRangeFromString(c *C) {
  193. var rangeString string
  194. var lower, upper int
  195. var err error
  196. rangeString = "1:3"
  197. lower, upper, err = getRangeFromString(rangeString)
  198. c.Assert(err, IsNil)
  199. c.Assert(lower, Equals, 1)
  200. c.Assert(upper, Equals, 3)
  201. }
  202. func (l *LibSuite) TestMakeRowFromSpan(c *C) {
  203. var rangeString string
  204. var row *Row
  205. var length int
  206. rangeString = "1:3"
  207. row = makeRowFromSpan(rangeString)
  208. length = len(row.Cells)
  209. c.Assert(length, Equals, 3)
  210. rangeString = "5:7" // Note - we ignore lower bound!
  211. row = makeRowFromSpan(rangeString)
  212. length = len(row.Cells)
  213. c.Assert(length, Equals, 7)
  214. rangeString = "1:1"
  215. row = makeRowFromSpan(rangeString)
  216. length = len(row.Cells)
  217. c.Assert(length, Equals, 1)
  218. }
  219. func (l *LibSuite) TestReadRowsFromSheet(c *C) {
  220. var sharedstringsXML = bytes.NewBufferString(`
  221. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  222. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  223. <si>
  224. <t>Foo</t>
  225. </si>
  226. <si>
  227. <t>Bar</t>
  228. </si>
  229. <si>
  230. <t xml:space="preserve">Baz </t>
  231. </si>
  232. <si>
  233. <t>Quuk</t>
  234. </si>
  235. </sst>`)
  236. var sheetxml = bytes.NewBufferString(`
  237. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  238. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  239. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  240. <dimension ref="A1:B2"/>
  241. <sheetViews>
  242. <sheetView tabSelected="1" workbookViewId="0">
  243. <selection activeCell="C2" sqref="C2"/>
  244. <pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
  245. </sheetView>
  246. </sheetViews>
  247. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  248. <sheetData>
  249. <row r="1" spans="1:2">
  250. <c r="A1" t="s">
  251. <v>0</v>
  252. </c>
  253. <c r="B1" t="s">
  254. <v>1</v>
  255. </c>
  256. </row>
  257. <row r="2" spans="1:2">
  258. <c r="A2" t="s">
  259. <v>2</v>
  260. </c>
  261. <c r="B2" t="s">
  262. <v>3</v>
  263. </c>
  264. </row>
  265. </sheetData>
  266. <pageMargins left="0.7" right="0.7"
  267. top="0.78740157499999996"
  268. bottom="0.78740157499999996"
  269. header="0.3"
  270. footer="0.3"/>
  271. </worksheet>`)
  272. worksheet := new(xlsxWorksheet)
  273. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  274. c.Assert(err, IsNil)
  275. sst := new(xlsxSST)
  276. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  277. c.Assert(err, IsNil)
  278. file := new(File)
  279. file.referenceTable = MakeSharedStringRefTable(sst)
  280. rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  281. c.Assert(maxRows, Equals, 2)
  282. c.Assert(maxCols, Equals, 2)
  283. row := rows[0]
  284. c.Assert(len(row.Cells), Equals, 2)
  285. cell1 := row.Cells[0]
  286. c.Assert(cell1.Value, Equals, "Foo")
  287. cell2 := row.Cells[1]
  288. c.Assert(cell2.Value, Equals, "Bar")
  289. col := cols[0]
  290. c.Assert(col.Min, Equals, 0)
  291. c.Assert(col.Max, Equals, 0)
  292. c.Assert(col.Hidden, Equals, false)
  293. c.Assert(len(worksheet.SheetViews.SheetView), Equals, 1)
  294. sheetView := worksheet.SheetViews.SheetView[0]
  295. c.Assert(sheetView.Pane, NotNil)
  296. pane := sheetView.Pane
  297. c.Assert(pane.XSplit, Equals, 0.0)
  298. c.Assert(pane.YSplit, Equals, 1.0)
  299. }
  300. // An invalid value in the "r" attribute in a <row> was causing a panic
  301. // in readRowsFromSheet. This test is a copy of TestReadRowsFromSheet,
  302. // with the important difference of the value 1048576 below in <row r="1048576", which is
  303. // higher than the number of rows in the sheet. That number itself isn't significant;
  304. // it just happens to be the value found to trigger the error in a user's file.
  305. func (l *LibSuite) TestReadRowsFromSheetBadR(c *C) {
  306. var sharedstringsXML = bytes.NewBufferString(`
  307. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  308. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  309. <si>
  310. <t>Foo</t>
  311. </si>
  312. <si>
  313. <t>Bar</t>
  314. </si>
  315. <si>
  316. <t xml:space="preserve">Baz </t>
  317. </si>
  318. <si>
  319. <t>Quuk</t>
  320. </si>
  321. </sst>`)
  322. var sheetxml = bytes.NewBufferString(`
  323. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  324. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  325. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  326. <dimension ref="A1:B2"/>
  327. <sheetViews>
  328. <sheetView tabSelected="1" workbookViewId="0">
  329. <selection activeCell="C2" sqref="C2"/>
  330. <pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
  331. </sheetView>
  332. </sheetViews>
  333. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  334. <sheetData>
  335. <row r="1" spans="1:2">
  336. <c r="A1" t="s">
  337. <v>0</v>
  338. </c>
  339. <c r="B1" t="s">
  340. <v>1</v>
  341. </c>
  342. </row>
  343. <row r="1048576" spans="1:2">
  344. <c r="A2" t="s">
  345. <v>2</v>
  346. </c>
  347. <c r="B2" t="s">
  348. <v>3</v>
  349. </c>
  350. </row>
  351. </sheetData>
  352. <pageMargins left="0.7" right="0.7"
  353. top="0.78740157499999996"
  354. bottom="0.78740157499999996"
  355. header="0.3"
  356. footer="0.3"/>
  357. </worksheet>`)
  358. worksheet := new(xlsxWorksheet)
  359. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  360. c.Assert(err, IsNil)
  361. sst := new(xlsxSST)
  362. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  363. c.Assert(err, IsNil)
  364. file := new(File)
  365. file.referenceTable = MakeSharedStringRefTable(sst)
  366. // Discarding all return values; this test is a regression for
  367. // a panic due to an "index out of range."
  368. readRowsFromSheet(worksheet, file)
  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. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  412. c.Assert(maxRows, Equals, 5)
  413. c.Assert(maxCols, Equals, 1)
  414. c.Assert(len(rows[0].Cells), Equals, 0)
  415. c.Assert(len(rows[1].Cells), Equals, 0)
  416. c.Assert(len(rows[2].Cells), Equals, 0)
  417. c.Assert(len(rows[3].Cells), Equals, 1)
  418. c.Assert(rows[3].Cells[0].String(), Equals, "ABC")
  419. c.Assert(len(rows[4].Cells), Equals, 1)
  420. c.Assert(rows[4].Cells[0].String(), Equals, "DEF")
  421. }
  422. func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyCols(c *C) {
  423. var sharedstringsXML = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  424. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2"><si><t>ABC</t></si><si><t>DEF</t></si></sst>`)
  425. var sheetxml = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  426. <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">
  427. <dimension ref="C1:D2"/>
  428. <sheetViews>
  429. <sheetView tabSelected="1" workbookViewId="0">
  430. <selection activeCell="A2" sqref="A2"/>
  431. </sheetView>
  432. </sheetViews>
  433. <sheetFormatPr baseColWidth="10" defaultRowHeight="15" x14ac:dyDescent="0"/>
  434. <cols>
  435. <col min="3" max="3" width="17" customWidth="1"/>
  436. <col min="4" max="4" width="18" customWidth="1"/>
  437. </cols>
  438. <sheetData>
  439. <row r="1" spans="3:4">
  440. <c r="C1" t="s"><v>0</v></c>
  441. <c r="D1" t="s"><v>1</v></c>
  442. </row>
  443. <row r="2" spans="3:4">
  444. <c r="C2" t="s"><v>0</v></c>
  445. <c r="D2" t="s"><v>1</v></c>
  446. </row>
  447. </sheetData>
  448. <pageMargins left="0.75" right="0.75" top="1" bottom="1" header="0.5" footer="0.5"/>
  449. <pageSetup paperSize="9" orientation="portrait" horizontalDpi="4294967292" verticalDpi="4294967292"/>
  450. <extLst>
  451. <ext uri="{64002731-A6B0-56B0-2670-7721B7C09600}" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main">
  452. <mx:PLV Mode="0" OnePage="0" WScale="0"/>
  453. </ext>
  454. </extLst>
  455. </worksheet>
  456. `)
  457. worksheet := new(xlsxWorksheet)
  458. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  459. c.Assert(err, IsNil)
  460. sst := new(xlsxSST)
  461. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  462. c.Assert(err, IsNil)
  463. file := new(File)
  464. file.referenceTable = MakeSharedStringRefTable(sst)
  465. rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  466. c.Assert(maxRows, Equals, 2)
  467. c.Assert(maxCols, Equals, 4)
  468. c.Assert(len(rows[0].Cells), Equals, 4)
  469. c.Assert(rows[0].Cells[0].String(), Equals, "")
  470. c.Assert(rows[0].Cells[1].String(), Equals, "")
  471. c.Assert(rows[0].Cells[2].String(), Equals, "ABC")
  472. c.Assert(rows[0].Cells[3].String(), Equals, "DEF")
  473. c.Assert(len(rows[1].Cells), Equals, 4)
  474. c.Assert(rows[1].Cells[0].String(), Equals, "")
  475. c.Assert(rows[1].Cells[1].String(), Equals, "")
  476. c.Assert(rows[1].Cells[2].String(), Equals, "ABC")
  477. c.Assert(rows[1].Cells[3].String(), Equals, "DEF")
  478. c.Assert(len(cols), Equals, 4)
  479. c.Assert(cols[0].Width, Equals, 0.0)
  480. c.Assert(cols[1].Width, Equals, 0.0)
  481. c.Assert(cols[2].Width, Equals, 17.0)
  482. c.Assert(cols[3].Width, Equals, 18.0)
  483. }
  484. func (l *LibSuite) TestReadRowsFromSheetWithEmptyCells(c *C) {
  485. var sharedstringsXML = bytes.NewBufferString(`
  486. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  487. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="8" uniqueCount="5">
  488. <si>
  489. <t>Bob</t>
  490. </si>
  491. <si>
  492. <t>Alice</t>
  493. </si>
  494. <si>
  495. <t>Sue</t>
  496. </si>
  497. <si>
  498. <t>Yes</t>
  499. </si>
  500. <si>
  501. <t>No</t>
  502. </si>
  503. </sst>
  504. `)
  505. var sheetxml = bytes.NewBufferString(`
  506. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  507. <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"/>
  508. <sheetData>
  509. <row r="1" spans="1:3">
  510. <c r="A1" t="s">
  511. <v>
  512. 0
  513. </v>
  514. </c>
  515. <c r="B1" t="s">
  516. <v>
  517. 1
  518. </v>
  519. </c>
  520. <c r="C1" t="s">
  521. <v>
  522. 2
  523. </v>
  524. </c>
  525. </row>
  526. <row r="2" spans="1:3">
  527. <c r="A2" t="s">
  528. <v>
  529. 3
  530. </v>
  531. </c>
  532. <c r="B2" t="s">
  533. <v>
  534. 4
  535. </v>
  536. </c>
  537. <c r="C2" t="s">
  538. <v>
  539. 3
  540. </v>
  541. </c>
  542. </row>
  543. <row r="3" spans="1:3">
  544. <c r="A3" t="s">
  545. <v>
  546. 4
  547. </v>
  548. </c>
  549. <c r="C3" t="s">
  550. <v>
  551. 3
  552. </v>
  553. </c>
  554. </row>
  555. </sheetData>
  556. <pageMargins left="0.7" right="0.7" top="0.78740157499999996" bottom="0.78740157499999996" header="0.3" footer="0.3"/>
  557. </worksheet>
  558. `)
  559. worksheet := new(xlsxWorksheet)
  560. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  561. c.Assert(err, IsNil)
  562. sst := new(xlsxSST)
  563. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  564. c.Assert(err, IsNil)
  565. file := new(File)
  566. file.referenceTable = MakeSharedStringRefTable(sst)
  567. rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  568. c.Assert(maxRows, Equals, 3)
  569. c.Assert(maxCols, Equals, 3)
  570. row := rows[2]
  571. c.Assert(len(row.Cells), Equals, 3)
  572. cell1 := row.Cells[0]
  573. c.Assert(cell1.Value, Equals, "No")
  574. cell2 := row.Cells[1]
  575. c.Assert(cell2.Value, Equals, "")
  576. cell3 := row.Cells[2]
  577. c.Assert(cell3.Value, Equals, "Yes")
  578. col := cols[0]
  579. c.Assert(col.Min, Equals, 0)
  580. c.Assert(col.Max, Equals, 0)
  581. c.Assert(col.Hidden, Equals, false)
  582. }
  583. func (l *LibSuite) TestReadRowsFromSheetWithTrailingEmptyCells(c *C) {
  584. var row *Row
  585. var cell1, cell2, cell3, cell4 *Cell
  586. var sharedstringsXML = bytes.NewBufferString(`
  587. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  588. <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>`)
  589. var sheetxml = bytes.NewBufferString(`
  590. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  591. <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>
  592. `)
  593. worksheet := new(xlsxWorksheet)
  594. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  595. c.Assert(err, IsNil)
  596. sst := new(xlsxSST)
  597. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  598. c.Assert(err, IsNil)
  599. file := new(File)
  600. file.referenceTable = MakeSharedStringRefTable(sst)
  601. rows, _, maxCol, maxRow := readRowsFromSheet(worksheet, file)
  602. c.Assert(maxCol, Equals, 4)
  603. c.Assert(maxRow, Equals, 8)
  604. row = rows[0]
  605. c.Assert(len(row.Cells), Equals, 4)
  606. cell1 = row.Cells[0]
  607. c.Assert(cell1.Value, Equals, "A")
  608. cell2 = row.Cells[1]
  609. c.Assert(cell2.Value, Equals, "B")
  610. cell3 = row.Cells[2]
  611. c.Assert(cell3.Value, Equals, "C")
  612. cell4 = row.Cells[3]
  613. c.Assert(cell4.Value, Equals, "D")
  614. row = rows[1]
  615. c.Assert(len(row.Cells), Equals, 4)
  616. cell1 = row.Cells[0]
  617. c.Assert(cell1.Value, Equals, "1")
  618. cell2 = row.Cells[1]
  619. c.Assert(cell2.Value, Equals, "")
  620. cell3 = row.Cells[2]
  621. c.Assert(cell3.Value, Equals, "")
  622. cell4 = row.Cells[3]
  623. c.Assert(cell4.Value, Equals, "")
  624. }
  625. func (l *LibSuite) TestReadRowsFromSheetWithMultipleSpans(c *C) {
  626. var sharedstringsXML = bytes.NewBufferString(`
  627. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  628. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  629. <si>
  630. <t>Foo</t>
  631. </si>
  632. <si>
  633. <t>Bar</t>
  634. </si>
  635. <si>
  636. <t xml:space="preserve">Baz </t>
  637. </si>
  638. <si>
  639. <t>Quuk</t>
  640. </si>
  641. </sst>`)
  642. var sheetxml = bytes.NewBufferString(`
  643. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  644. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  645. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  646. <dimension ref="A1:D2"/>
  647. <sheetViews>
  648. <sheetView tabSelected="1" workbookViewId="0">
  649. <selection activeCell="C2" sqref="C2"/>
  650. </sheetView>
  651. </sheetViews>
  652. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  653. <sheetData>
  654. <row r="1" spans="1:2 3:4">
  655. <c r="A1" t="s">
  656. <v>0</v>
  657. </c>
  658. <c r="B1" t="s">
  659. <v>1</v>
  660. </c>
  661. <c r="C1" t="s">
  662. <v>0</v>
  663. </c>
  664. <c r="D1" t="s">
  665. <v>1</v>
  666. </c>
  667. </row>
  668. <row r="2" spans="1:2 3:4">
  669. <c r="A2" t="s">
  670. <v>2</v>
  671. </c>
  672. <c r="B2" t="s">
  673. <v>3</v>
  674. </c>
  675. <c r="C2" t="s">
  676. <v>2</v>
  677. </c>
  678. <c r="D2" t="s">
  679. <v>3</v>
  680. </c>
  681. </row>
  682. </sheetData>
  683. <pageMargins left="0.7" right="0.7"
  684. top="0.78740157499999996"
  685. bottom="0.78740157499999996"
  686. header="0.3"
  687. footer="0.3"/>
  688. </worksheet>`)
  689. worksheet := new(xlsxWorksheet)
  690. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  691. c.Assert(err, IsNil)
  692. sst := new(xlsxSST)
  693. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  694. c.Assert(err, IsNil)
  695. file := new(File)
  696. file.referenceTable = MakeSharedStringRefTable(sst)
  697. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  698. c.Assert(maxRows, Equals, 2)
  699. c.Assert(maxCols, Equals, 4)
  700. row := rows[0]
  701. c.Assert(len(row.Cells), Equals, 4)
  702. cell1 := row.Cells[0]
  703. c.Assert(cell1.Value, Equals, "Foo")
  704. cell2 := row.Cells[1]
  705. c.Assert(cell2.Value, Equals, "Bar")
  706. cell3 := row.Cells[2]
  707. c.Assert(cell3.Value, Equals, "Foo")
  708. cell4 := row.Cells[3]
  709. c.Assert(cell4.Value, Equals, "Bar")
  710. }
  711. func (l *LibSuite) TestReadRowsFromSheetWithMultipleTypes(c *C) {
  712. var sharedstringsXML = bytes.NewBufferString(`
  713. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  714. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  715. <si>
  716. <t>Hello World</t>
  717. </si>
  718. </sst>`)
  719. var sheetxml = bytes.NewBufferString(`
  720. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  721. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  722. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  723. <dimension ref="A1:F1"/>
  724. <sheetViews>
  725. <sheetView tabSelected="1" workbookViewId="0">
  726. <selection activeCell="C1" sqref="C1"/>
  727. </sheetView>
  728. </sheetViews>
  729. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  730. <sheetData>
  731. <row r="1" spans="1:6">
  732. <c r="A1" t="s">
  733. <v>0</v>
  734. </c>
  735. <c r="B1">
  736. <v>12345</v>
  737. </c>
  738. <c r="C1">
  739. <v>1.024</v>
  740. </c>
  741. <c r="D1" t="b">
  742. <v>1</v>
  743. </c>
  744. <c r="E1">
  745. <f>10+20</f>
  746. <v>30</v>
  747. </c>
  748. <c r="F1" t="e">
  749. <f>10/0</f>
  750. <v>#DIV/0!</v>
  751. </c>
  752. </row>
  753. </sheetData>
  754. <pageMargins left="0.7" right="0.7"
  755. top="0.78740157499999996"
  756. bottom="0.78740157499999996"
  757. header="0.3"
  758. footer="0.3"/>
  759. </worksheet>`)
  760. worksheet := new(xlsxWorksheet)
  761. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  762. c.Assert(err, IsNil)
  763. sst := new(xlsxSST)
  764. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  765. c.Assert(err, IsNil)
  766. file := new(File)
  767. file.referenceTable = MakeSharedStringRefTable(sst)
  768. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  769. c.Assert(maxRows, Equals, 1)
  770. c.Assert(maxCols, Equals, 6)
  771. row := rows[0]
  772. c.Assert(len(row.Cells), Equals, 6)
  773. cell1 := row.Cells[0]
  774. c.Assert(cell1.Type(), Equals, CellTypeString)
  775. c.Assert(cell1.String(), Equals, "Hello World")
  776. cell2 := row.Cells[1]
  777. c.Assert(cell2.Type(), Equals, CellTypeNumeric)
  778. intValue, _ := cell2.Int()
  779. c.Assert(intValue, Equals, 12345)
  780. cell3 := row.Cells[2]
  781. c.Assert(cell3.Type(), Equals, CellTypeNumeric)
  782. float, _ := cell3.Float()
  783. c.Assert(float, Equals, 1.024)
  784. cell4 := row.Cells[3]
  785. c.Assert(cell4.Type(), Equals, CellTypeBool)
  786. c.Assert(cell4.Bool(), Equals, true)
  787. cell5 := row.Cells[4]
  788. c.Assert(cell5.Type(), Equals, CellTypeFormula)
  789. c.Assert(cell5.Formula(), Equals, "10+20")
  790. c.Assert(cell5.Value, Equals, "30")
  791. cell6 := row.Cells[5]
  792. c.Assert(cell6.Type(), Equals, CellTypeError)
  793. c.Assert(cell6.Formula(), Equals, "10/0")
  794. c.Assert(cell6.Value, Equals, "#DIV/0!")
  795. }
  796. func (l *LibSuite) TestReadRowsFromSheetWithHiddenColumn(c *C) {
  797. var sharedstringsXML = bytes.NewBufferString(`
  798. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  799. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  800. <si><t>This is a test.</t></si>
  801. <si><t>This should be invisible.</t></si>
  802. </sst>`)
  803. var sheetxml = bytes.NewBufferString(`
  804. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  805. <worksheet xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main"
  806. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"
  807. xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  808. <sheetViews><sheetView workbookViewId="0"/>
  809. </sheetViews>
  810. <sheetFormatPr customHeight="1" defaultColWidth="14.43" defaultRowHeight="15.75"/>
  811. <cols>
  812. <col hidden="1" max="2" min="2"/>
  813. </cols>
  814. <sheetData>
  815. <row r="1">
  816. <c r="A1" s="1" t="s"><v>0</v></c>
  817. <c r="B1" s="1" t="s"><v>1</v></c>
  818. </row>
  819. </sheetData><drawing r:id="rId1"/></worksheet>`)
  820. worksheet := new(xlsxWorksheet)
  821. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  822. c.Assert(err, IsNil)
  823. sst := new(xlsxSST)
  824. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  825. c.Assert(err, IsNil)
  826. file := new(File)
  827. file.referenceTable = MakeSharedStringRefTable(sst)
  828. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  829. c.Assert(maxRows, Equals, 1)
  830. c.Assert(maxCols, Equals, 2)
  831. row := rows[0]
  832. c.Assert(len(row.Cells), Equals, 2)
  833. cell1 := row.Cells[0]
  834. c.Assert(cell1.Type(), Equals, CellTypeString)
  835. c.Assert(cell1.String(), Equals, "This is a test.")
  836. c.Assert(cell1.Hidden, Equals, false)
  837. cell2 := row.Cells[1]
  838. c.Assert(cell2.Type(), Equals, CellTypeString)
  839. c.Assert(cell2.String(), Equals, "This should be invisible.")
  840. c.Assert(cell2.Hidden, Equals, true)
  841. }
  842. // When converting the xlsxRow to a Row we create a as many cells as we find.
  843. func (l *LibSuite) TestReadRowFromRaw(c *C) {
  844. var rawRow xlsxRow
  845. var cell xlsxC
  846. var row *Row
  847. rawRow = xlsxRow{}
  848. cell = xlsxC{R: "A1"}
  849. cell = xlsxC{R: "A2"}
  850. rawRow.C = append(rawRow.C, cell)
  851. row = makeRowFromRaw(rawRow)
  852. c.Assert(row, NotNil)
  853. c.Assert(row.Cells, HasLen, 1)
  854. }
  855. // When a cell claims it is at a position greater than its ordinal
  856. // position in the file we make up the missing cells.
  857. func (l *LibSuite) TestReadRowFromRawWithMissingCells(c *C) {
  858. var rawRow xlsxRow
  859. var cell xlsxC
  860. var row *Row
  861. rawRow = xlsxRow{}
  862. cell = xlsxC{R: "A1"}
  863. rawRow.C = append(rawRow.C, cell)
  864. cell = xlsxC{R: "E1"}
  865. rawRow.C = append(rawRow.C, cell)
  866. row = makeRowFromRaw(rawRow)
  867. c.Assert(row, NotNil)
  868. c.Assert(row.Cells, HasLen, 5)
  869. }
  870. // We can cope with missing coordinate references
  871. func (l *LibSuite) TestReadRowFromRawWithPartialCoordinates(c *C) {
  872. var rawRow xlsxRow
  873. var cell xlsxC
  874. var row *Row
  875. rawRow = xlsxRow{}
  876. cell = xlsxC{R: "A1"}
  877. rawRow.C = append(rawRow.C, cell)
  878. cell = xlsxC{}
  879. rawRow.C = append(rawRow.C, cell)
  880. cell = xlsxC{R: "Z:1"}
  881. rawRow.C = append(rawRow.C, cell)
  882. cell = xlsxC{}
  883. rawRow.C = append(rawRow.C, cell)
  884. row = makeRowFromRaw(rawRow)
  885. c.Assert(row, NotNil)
  886. c.Assert(row.Cells, HasLen, 27)
  887. }
  888. func (l *LibSuite) TestSharedFormulas(c *C) {
  889. var sheetxml = bytes.NewBufferString(`
  890. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  891. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  892. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  893. <dimension ref="A1:C2"/>
  894. <sheetViews>
  895. <sheetView tabSelected="1" workbookViewId="0">
  896. <selection activeCell="C1" sqref="C1"/>
  897. </sheetView>
  898. </sheetViews>
  899. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  900. <sheetData>
  901. <row r="1" spans="1:3">
  902. <c r="A1">
  903. <v>1</v>
  904. </c>
  905. <c r="B1">
  906. <v>2</v>
  907. </c>
  908. <c r="C1">
  909. <v>3</v>
  910. </c>
  911. </row>
  912. <row r="2" spans="1:3">
  913. <c r="A2">
  914. <v>2</v>
  915. <f t="shared" ref="A2:C2" si="0">2*A1</f>
  916. </c>
  917. <c r="B2">
  918. <v>4</v>
  919. <f t="shared" si="0"/>
  920. </c>
  921. <c r="C2">
  922. <v>6</v>
  923. <f t="shared" si="0"/>
  924. </c>
  925. </row>
  926. </sheetData>
  927. <pageMargins left="0.7" right="0.7"
  928. top="0.78740157499999996"
  929. bottom="0.78740157499999996"
  930. header="0.3"
  931. footer="0.3"/>
  932. </worksheet>`)
  933. worksheet := new(xlsxWorksheet)
  934. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  935. c.Assert(err, IsNil)
  936. file := new(File)
  937. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  938. c.Assert(maxCols, Equals, 3)
  939. c.Assert(maxRows, Equals, 2)
  940. row := rows[1]
  941. c.Assert(row.Cells[1].Formula(), Equals, "2*B1")
  942. c.Assert(row.Cells[2].Formula(), Equals, "2*C1")
  943. }
  944. // Avoid panic when cell.F.T is "e" (for error)
  945. func (l *LibSuite) TestFormulaForCellPanic(c *C) {
  946. cell := xlsxC{R: "A1"}
  947. // This line would panic before the fix.
  948. sharedFormulas := make(map[int]sharedFormula)
  949. // Not really an important test; getting here without a
  950. // panic is the real win.
  951. c.Assert(formulaForCell(cell, sharedFormulas), Equals, "")
  952. }