lib_test.go 34 KB

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