lib_test.go 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  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. rangeString = "1:3"
  219. row = makeRowFromSpan(rangeString)
  220. length = len(row.Cells)
  221. c.Assert(length, Equals, 3)
  222. rangeString = "5:7" // Note - we ignore lower bound!
  223. row = makeRowFromSpan(rangeString)
  224. length = len(row.Cells)
  225. c.Assert(length, Equals, 7)
  226. rangeString = "1:1"
  227. row = makeRowFromSpan(rangeString)
  228. length = len(row.Cells)
  229. c.Assert(length, Equals, 1)
  230. }
  231. func (l *LibSuite) TestReadRowsFromSheet(c *C) {
  232. var sharedstringsXML = bytes.NewBufferString(`
  233. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  234. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  235. <si>
  236. <t>Foo</t>
  237. </si>
  238. <si>
  239. <t>Bar</t>
  240. </si>
  241. <si>
  242. <t xml:space="preserve">Baz </t>
  243. </si>
  244. <si>
  245. <t>Quuk</t>
  246. </si>
  247. </sst>`)
  248. var sheetxml = bytes.NewBufferString(`
  249. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  250. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  251. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  252. <dimension ref="A1:B2"/>
  253. <sheetViews>
  254. <sheetView tabSelected="1" workbookViewId="0">
  255. <selection activeCell="C2" sqref="C2"/>
  256. <pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
  257. </sheetView>
  258. </sheetViews>
  259. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  260. <sheetData>
  261. <row r="1" spans="1:2">
  262. <c r="A1" t="s">
  263. <v>0</v>
  264. </c>
  265. <c r="B1" t="s">
  266. <v>1</v>
  267. </c>
  268. </row>
  269. <row r="2" spans="1:2">
  270. <c r="A2" t="s">
  271. <v>2</v>
  272. </c>
  273. <c r="B2" t="s">
  274. <v>3</v>
  275. </c>
  276. </row>
  277. </sheetData>
  278. <pageMargins left="0.7" right="0.7"
  279. top="0.78740157499999996"
  280. bottom="0.78740157499999996"
  281. header="0.3"
  282. footer="0.3"/>
  283. </worksheet>`)
  284. worksheet := new(xlsxWorksheet)
  285. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  286. c.Assert(err, IsNil)
  287. sst := new(xlsxSST)
  288. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  289. c.Assert(err, IsNil)
  290. file := new(File)
  291. file.referenceTable = MakeSharedStringRefTable(sst)
  292. rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  293. c.Assert(maxRows, Equals, 2)
  294. c.Assert(maxCols, Equals, 2)
  295. row := rows[0]
  296. c.Assert(len(row.Cells), Equals, 2)
  297. cell1 := row.Cells[0]
  298. c.Assert(cell1.Value, Equals, "Foo")
  299. cell2 := row.Cells[1]
  300. c.Assert(cell2.Value, Equals, "Bar")
  301. col := cols[0]
  302. c.Assert(col.Min, Equals, 0)
  303. c.Assert(col.Max, Equals, 0)
  304. c.Assert(col.Hidden, Equals, false)
  305. c.Assert(len(worksheet.SheetViews.SheetView), Equals, 1)
  306. sheetView := worksheet.SheetViews.SheetView[0]
  307. c.Assert(sheetView.Pane, NotNil)
  308. pane := sheetView.Pane
  309. c.Assert(pane.XSplit, Equals, 0.0)
  310. c.Assert(pane.YSplit, Equals, 1.0)
  311. }
  312. // An invalid value in the "r" attribute in a <row> was causing a panic
  313. // in readRowsFromSheet. This test is a copy of TestReadRowsFromSheet,
  314. // with the important difference of the value 1048576 below in <row r="1048576", which is
  315. // higher than the number of rows in the sheet. That number itself isn't significant;
  316. // it just happens to be the value found to trigger the error in a user's file.
  317. func (l *LibSuite) TestReadRowsFromSheetBadR(c *C) {
  318. var sharedstringsXML = bytes.NewBufferString(`
  319. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  320. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  321. <si>
  322. <t>Foo</t>
  323. </si>
  324. <si>
  325. <t>Bar</t>
  326. </si>
  327. <si>
  328. <t xml:space="preserve">Baz </t>
  329. </si>
  330. <si>
  331. <t>Quuk</t>
  332. </si>
  333. </sst>`)
  334. var sheetxml = bytes.NewBufferString(`
  335. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  336. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  337. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  338. <dimension ref="A1:B2"/>
  339. <sheetViews>
  340. <sheetView tabSelected="1" workbookViewId="0">
  341. <selection activeCell="C2" sqref="C2"/>
  342. <pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
  343. </sheetView>
  344. </sheetViews>
  345. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  346. <sheetData>
  347. <row r="1" spans="1:2">
  348. <c r="A1" t="s">
  349. <v>0</v>
  350. </c>
  351. <c r="B1" t="s">
  352. <v>1</v>
  353. </c>
  354. </row>
  355. <row r="1048576" spans="1:2">
  356. <c r="A2" t="s">
  357. <v>2</v>
  358. </c>
  359. <c r="B2" t="s">
  360. <v>3</v>
  361. </c>
  362. </row>
  363. </sheetData>
  364. <pageMargins left="0.7" right="0.7"
  365. top="0.78740157499999996"
  366. bottom="0.78740157499999996"
  367. header="0.3"
  368. footer="0.3"/>
  369. </worksheet>`)
  370. worksheet := new(xlsxWorksheet)
  371. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  372. c.Assert(err, IsNil)
  373. sst := new(xlsxSST)
  374. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  375. c.Assert(err, IsNil)
  376. file := new(File)
  377. file.referenceTable = MakeSharedStringRefTable(sst)
  378. // Discarding all return values; this test is a regression for
  379. // a panic due to an "index out of range."
  380. readRowsFromSheet(worksheet, file)
  381. }
  382. func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyRows(c *C) {
  383. var sharedstringsXML = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  384. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2"><si><t>ABC</t></si><si><t>DEF</t></si></sst>`)
  385. var sheetxml = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  386. <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">
  387. <dimension ref="A4:A5"/>
  388. <sheetViews>
  389. <sheetView tabSelected="1" workbookViewId="0">
  390. <selection activeCell="A2" sqref="A2"/>
  391. </sheetView>
  392. </sheetViews>
  393. <sheetFormatPr baseColWidth="10" defaultRowHeight="15" x14ac:dyDescent="0"/>
  394. <sheetData>
  395. <row r="4" spans="1:1">
  396. <c r="A4" t="s">
  397. <v>0</v>
  398. </c>
  399. </row>
  400. <row r="5" spans="1:1">
  401. <c r="A5" t="s">
  402. <v>1</v>
  403. </c>
  404. </row>
  405. </sheetData>
  406. <pageMargins left="0.75" right="0.75" top="1" bottom="1" header="0.5" footer="0.5"/>
  407. <pageSetup paperSize="9" orientation="portrait" horizontalDpi="4294967292" verticalDpi="4294967292"/>
  408. <extLst>
  409. <ext uri="{64002731-A6B0-56B0-2670-7721B7C09600}" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main">
  410. <mx:PLV Mode="0" OnePage="0" WScale="0"/>
  411. </ext>
  412. </extLst>
  413. </worksheet>
  414. `)
  415. worksheet := new(xlsxWorksheet)
  416. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  417. c.Assert(err, IsNil)
  418. sst := new(xlsxSST)
  419. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  420. c.Assert(err, IsNil)
  421. file := new(File)
  422. file.referenceTable = MakeSharedStringRefTable(sst)
  423. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  424. c.Assert(maxRows, Equals, 5)
  425. c.Assert(maxCols, Equals, 1)
  426. c.Assert(len(rows[0].Cells), Equals, 0)
  427. c.Assert(len(rows[1].Cells), Equals, 0)
  428. c.Assert(len(rows[2].Cells), Equals, 0)
  429. c.Assert(len(rows[3].Cells), Equals, 1)
  430. c.Assert(rows[3].Cells[0].String(), Equals, "ABC")
  431. c.Assert(len(rows[4].Cells), Equals, 1)
  432. c.Assert(rows[4].Cells[0].String(), Equals, "DEF")
  433. }
  434. func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyCols(c *C) {
  435. var sharedstringsXML = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  436. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2"><si><t>ABC</t></si><si><t>DEF</t></si></sst>`)
  437. var sheetxml = bytes.NewBufferString(`<?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" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
  439. <dimension ref="C1:D2"/>
  440. <sheetViews>
  441. <sheetView tabSelected="1" workbookViewId="0">
  442. <selection activeCell="A2" sqref="A2"/>
  443. </sheetView>
  444. </sheetViews>
  445. <sheetFormatPr baseColWidth="10" defaultRowHeight="15" x14ac:dyDescent="0"/>
  446. <cols>
  447. <col min="3" max="3" width="17" customWidth="1"/>
  448. <col min="4" max="4" width="18" customWidth="1"/>
  449. </cols>
  450. <sheetData>
  451. <row r="1" spans="3:4">
  452. <c r="C1" t="s"><v>0</v></c>
  453. <c r="D1" t="s"><v>1</v></c>
  454. </row>
  455. <row r="2" spans="3:4">
  456. <c r="C2" t="s"><v>0</v></c>
  457. <c r="D2" t="s"><v>1</v></c>
  458. </row>
  459. </sheetData>
  460. <pageMargins left="0.75" right="0.75" top="1" bottom="1" header="0.5" footer="0.5"/>
  461. <pageSetup paperSize="9" orientation="portrait" horizontalDpi="4294967292" verticalDpi="4294967292"/>
  462. <extLst>
  463. <ext uri="{64002731-A6B0-56B0-2670-7721B7C09600}" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main">
  464. <mx:PLV Mode="0" OnePage="0" WScale="0"/>
  465. </ext>
  466. </extLst>
  467. </worksheet>
  468. `)
  469. worksheet := new(xlsxWorksheet)
  470. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  471. c.Assert(err, IsNil)
  472. sst := new(xlsxSST)
  473. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  474. c.Assert(err, IsNil)
  475. file := new(File)
  476. file.referenceTable = MakeSharedStringRefTable(sst)
  477. rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  478. c.Assert(maxRows, Equals, 2)
  479. c.Assert(maxCols, Equals, 4)
  480. c.Assert(len(rows[0].Cells), Equals, 4)
  481. c.Assert(rows[0].Cells[0].String(), Equals, "")
  482. c.Assert(rows[0].Cells[1].String(), Equals, "")
  483. c.Assert(rows[0].Cells[2].String(), Equals, "ABC")
  484. c.Assert(rows[0].Cells[3].String(), Equals, "DEF")
  485. c.Assert(len(rows[1].Cells), Equals, 4)
  486. c.Assert(rows[1].Cells[0].String(), Equals, "")
  487. c.Assert(rows[1].Cells[1].String(), Equals, "")
  488. c.Assert(rows[1].Cells[2].String(), Equals, "ABC")
  489. c.Assert(rows[1].Cells[3].String(), Equals, "DEF")
  490. c.Assert(len(cols), Equals, 4)
  491. c.Assert(cols[0].Width, Equals, 0.0)
  492. c.Assert(cols[1].Width, Equals, 0.0)
  493. c.Assert(cols[2].Width, Equals, 17.0)
  494. c.Assert(cols[3].Width, Equals, 18.0)
  495. }
  496. func (l *LibSuite) TestReadRowsFromSheetWithEmptyCells(c *C) {
  497. var sharedstringsXML = bytes.NewBufferString(`
  498. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  499. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="8" uniqueCount="5">
  500. <si>
  501. <t>Bob</t>
  502. </si>
  503. <si>
  504. <t>Alice</t>
  505. </si>
  506. <si>
  507. <t>Sue</t>
  508. </si>
  509. <si>
  510. <t>Yes</t>
  511. </si>
  512. <si>
  513. <t>No</t>
  514. </si>
  515. </sst>
  516. `)
  517. var sheetxml = bytes.NewBufferString(`
  518. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  519. <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"/>
  520. <sheetData>
  521. <row r="1" spans="1:3">
  522. <c r="A1" t="s">
  523. <v>
  524. 0
  525. </v>
  526. </c>
  527. <c r="B1" t="s">
  528. <v>
  529. 1
  530. </v>
  531. </c>
  532. <c r="C1" t="s">
  533. <v>
  534. 2
  535. </v>
  536. </c>
  537. </row>
  538. <row r="2" spans="1:3">
  539. <c r="A2" t="s">
  540. <v>
  541. 3
  542. </v>
  543. </c>
  544. <c r="B2" t="s">
  545. <v>
  546. 4
  547. </v>
  548. </c>
  549. <c r="C2" t="s">
  550. <v>
  551. 3
  552. </v>
  553. </c>
  554. </row>
  555. <row r="3" spans="1:3">
  556. <c r="A3" t="s">
  557. <v>
  558. 4
  559. </v>
  560. </c>
  561. <c r="C3" t="s">
  562. <v>
  563. 3
  564. </v>
  565. </c>
  566. </row>
  567. </sheetData>
  568. <pageMargins left="0.7" right="0.7" top="0.78740157499999996" bottom="0.78740157499999996" header="0.3" footer="0.3"/>
  569. </worksheet>
  570. `)
  571. worksheet := new(xlsxWorksheet)
  572. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  573. c.Assert(err, IsNil)
  574. sst := new(xlsxSST)
  575. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  576. c.Assert(err, IsNil)
  577. file := new(File)
  578. file.referenceTable = MakeSharedStringRefTable(sst)
  579. rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  580. c.Assert(maxRows, Equals, 3)
  581. c.Assert(maxCols, Equals, 3)
  582. row := rows[2]
  583. c.Assert(len(row.Cells), Equals, 3)
  584. cell1 := row.Cells[0]
  585. c.Assert(cell1.Value, Equals, "No")
  586. cell2 := row.Cells[1]
  587. c.Assert(cell2.Value, Equals, "")
  588. cell3 := row.Cells[2]
  589. c.Assert(cell3.Value, Equals, "Yes")
  590. col := cols[0]
  591. c.Assert(col.Min, Equals, 0)
  592. c.Assert(col.Max, Equals, 0)
  593. c.Assert(col.Hidden, Equals, false)
  594. }
  595. func (l *LibSuite) TestReadRowsFromSheetWithTrailingEmptyCells(c *C) {
  596. var row *Row
  597. var cell1, cell2, cell3, cell4 *Cell
  598. var sharedstringsXML = bytes.NewBufferString(`
  599. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  600. <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>`)
  601. var sheetxml = bytes.NewBufferString(`
  602. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  603. <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>
  604. `)
  605. worksheet := new(xlsxWorksheet)
  606. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  607. c.Assert(err, IsNil)
  608. sst := new(xlsxSST)
  609. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  610. c.Assert(err, IsNil)
  611. file := new(File)
  612. file.referenceTable = MakeSharedStringRefTable(sst)
  613. rows, _, maxCol, maxRow := readRowsFromSheet(worksheet, file)
  614. c.Assert(maxCol, Equals, 4)
  615. c.Assert(maxRow, Equals, 8)
  616. row = rows[0]
  617. c.Assert(len(row.Cells), Equals, 4)
  618. cell1 = row.Cells[0]
  619. c.Assert(cell1.Value, Equals, "A")
  620. cell2 = row.Cells[1]
  621. c.Assert(cell2.Value, Equals, "B")
  622. cell3 = row.Cells[2]
  623. c.Assert(cell3.Value, Equals, "C")
  624. cell4 = row.Cells[3]
  625. c.Assert(cell4.Value, Equals, "D")
  626. row = rows[1]
  627. c.Assert(len(row.Cells), Equals, 4)
  628. cell1 = row.Cells[0]
  629. c.Assert(cell1.Value, Equals, "1")
  630. cell2 = row.Cells[1]
  631. c.Assert(cell2.Value, Equals, "")
  632. cell3 = row.Cells[2]
  633. c.Assert(cell3.Value, Equals, "")
  634. cell4 = row.Cells[3]
  635. c.Assert(cell4.Value, Equals, "")
  636. }
  637. func (l *LibSuite) TestReadRowsFromSheetWithMultipleSpans(c *C) {
  638. var sharedstringsXML = bytes.NewBufferString(`
  639. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  640. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  641. <si>
  642. <t>Foo</t>
  643. </si>
  644. <si>
  645. <t>Bar</t>
  646. </si>
  647. <si>
  648. <t xml:space="preserve">Baz </t>
  649. </si>
  650. <si>
  651. <t>Quuk</t>
  652. </si>
  653. </sst>`)
  654. var sheetxml = bytes.NewBufferString(`
  655. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  656. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  657. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  658. <dimension ref="A1:D2"/>
  659. <sheetViews>
  660. <sheetView tabSelected="1" workbookViewId="0">
  661. <selection activeCell="C2" sqref="C2"/>
  662. </sheetView>
  663. </sheetViews>
  664. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  665. <sheetData>
  666. <row r="1" spans="1:2 3:4">
  667. <c r="A1" t="s">
  668. <v>0</v>
  669. </c>
  670. <c r="B1" t="s">
  671. <v>1</v>
  672. </c>
  673. <c r="C1" t="s">
  674. <v>0</v>
  675. </c>
  676. <c r="D1" t="s">
  677. <v>1</v>
  678. </c>
  679. </row>
  680. <row r="2" spans="1:2 3:4">
  681. <c r="A2" t="s">
  682. <v>2</v>
  683. </c>
  684. <c r="B2" t="s">
  685. <v>3</v>
  686. </c>
  687. <c r="C2" t="s">
  688. <v>2</v>
  689. </c>
  690. <c r="D2" t="s">
  691. <v>3</v>
  692. </c>
  693. </row>
  694. </sheetData>
  695. <pageMargins left="0.7" right="0.7"
  696. top="0.78740157499999996"
  697. bottom="0.78740157499999996"
  698. header="0.3"
  699. footer="0.3"/>
  700. </worksheet>`)
  701. worksheet := new(xlsxWorksheet)
  702. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  703. c.Assert(err, IsNil)
  704. sst := new(xlsxSST)
  705. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  706. c.Assert(err, IsNil)
  707. file := new(File)
  708. file.referenceTable = MakeSharedStringRefTable(sst)
  709. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  710. c.Assert(maxRows, Equals, 2)
  711. c.Assert(maxCols, Equals, 4)
  712. row := rows[0]
  713. c.Assert(len(row.Cells), Equals, 4)
  714. cell1 := row.Cells[0]
  715. c.Assert(cell1.Value, Equals, "Foo")
  716. cell2 := row.Cells[1]
  717. c.Assert(cell2.Value, Equals, "Bar")
  718. cell3 := row.Cells[2]
  719. c.Assert(cell3.Value, Equals, "Foo")
  720. cell4 := row.Cells[3]
  721. c.Assert(cell4.Value, Equals, "Bar")
  722. }
  723. func (l *LibSuite) TestReadRowsFromSheetWithMultipleTypes(c *C) {
  724. var sharedstringsXML = bytes.NewBufferString(`
  725. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  726. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
  727. <si>
  728. <t>Hello World</t>
  729. </si>
  730. </sst>`)
  731. var sheetxml = bytes.NewBufferString(`
  732. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  733. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  734. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  735. <dimension ref="A1:F1"/>
  736. <sheetViews>
  737. <sheetView tabSelected="1" workbookViewId="0">
  738. <selection activeCell="C1" sqref="C1"/>
  739. </sheetView>
  740. </sheetViews>
  741. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  742. <sheetData>
  743. <row r="1" spans="1:6">
  744. <c r="A1" t="s">
  745. <v>0</v>
  746. </c>
  747. <c r="B1">
  748. <v>12345</v>
  749. </c>
  750. <c r="C1">
  751. <v>1.024</v>
  752. </c>
  753. <c r="D1" t="b">
  754. <v>1</v>
  755. </c>
  756. <c r="E1">
  757. <f>10+20</f>
  758. <v>30</v>
  759. </c>
  760. <c r="F1" t="e">
  761. <f>10/0</f>
  762. <v>#DIV/0!</v>
  763. </c>
  764. </row>
  765. </sheetData>
  766. <pageMargins left="0.7" right="0.7"
  767. top="0.78740157499999996"
  768. bottom="0.78740157499999996"
  769. header="0.3"
  770. footer="0.3"/>
  771. </worksheet>`)
  772. worksheet := new(xlsxWorksheet)
  773. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  774. c.Assert(err, IsNil)
  775. sst := new(xlsxSST)
  776. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  777. c.Assert(err, IsNil)
  778. file := new(File)
  779. file.referenceTable = MakeSharedStringRefTable(sst)
  780. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  781. c.Assert(maxRows, Equals, 1)
  782. c.Assert(maxCols, Equals, 6)
  783. row := rows[0]
  784. c.Assert(len(row.Cells), Equals, 6)
  785. cell1 := row.Cells[0]
  786. c.Assert(cell1.Type(), Equals, CellTypeString)
  787. c.Assert(cell1.String(), Equals, "Hello World")
  788. cell2 := row.Cells[1]
  789. c.Assert(cell2.Type(), Equals, CellTypeNumeric)
  790. intValue, _ := cell2.Int()
  791. c.Assert(intValue, Equals, 12345)
  792. cell3 := row.Cells[2]
  793. c.Assert(cell3.Type(), Equals, CellTypeNumeric)
  794. float, _ := cell3.Float()
  795. c.Assert(float, Equals, 1.024)
  796. cell4 := row.Cells[3]
  797. c.Assert(cell4.Type(), Equals, CellTypeBool)
  798. c.Assert(cell4.Bool(), Equals, true)
  799. cell5 := row.Cells[4]
  800. c.Assert(cell5.Type(), Equals, CellTypeFormula)
  801. c.Assert(cell5.Formula(), Equals, "10+20")
  802. c.Assert(cell5.Value, Equals, "30")
  803. cell6 := row.Cells[5]
  804. c.Assert(cell6.Type(), Equals, CellTypeError)
  805. c.Assert(cell6.Formula(), Equals, "10/0")
  806. c.Assert(cell6.Value, Equals, "#DIV/0!")
  807. }
  808. func (l *LibSuite) TestReadRowsFromSheetWithHiddenColumn(c *C) {
  809. var sharedstringsXML = bytes.NewBufferString(`
  810. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  811. <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  812. <si><t>This is a test.</t></si>
  813. <si><t>This should be invisible.</t></si>
  814. </sst>`)
  815. var sheetxml = bytes.NewBufferString(`
  816. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  817. <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"
  818. 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"
  819. xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  820. <sheetViews><sheetView workbookViewId="0"/>
  821. </sheetViews>
  822. <sheetFormatPr customHeight="1" defaultColWidth="14.43" defaultRowHeight="15.75"/>
  823. <cols>
  824. <col hidden="1" max="2" min="2"/>
  825. </cols>
  826. <sheetData>
  827. <row r="1">
  828. <c r="A1" s="1" t="s"><v>0</v></c>
  829. <c r="B1" s="1" t="s"><v>1</v></c>
  830. </row>
  831. </sheetData><drawing r:id="rId1"/></worksheet>`)
  832. worksheet := new(xlsxWorksheet)
  833. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  834. c.Assert(err, IsNil)
  835. sst := new(xlsxSST)
  836. err = xml.NewDecoder(sharedstringsXML).Decode(sst)
  837. c.Assert(err, IsNil)
  838. file := new(File)
  839. file.referenceTable = MakeSharedStringRefTable(sst)
  840. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  841. c.Assert(maxRows, Equals, 1)
  842. c.Assert(maxCols, Equals, 2)
  843. row := rows[0]
  844. c.Assert(len(row.Cells), Equals, 2)
  845. cell1 := row.Cells[0]
  846. c.Assert(cell1.Type(), Equals, CellTypeString)
  847. c.Assert(cell1.String(), Equals, "This is a test.")
  848. c.Assert(cell1.Hidden, Equals, false)
  849. cell2 := row.Cells[1]
  850. c.Assert(cell2.Type(), Equals, CellTypeString)
  851. c.Assert(cell2.String(), Equals, "This should be invisible.")
  852. c.Assert(cell2.Hidden, Equals, true)
  853. }
  854. // When converting the xlsxRow to a Row we create a as many cells as we find.
  855. func (l *LibSuite) TestReadRowFromRaw(c *C) {
  856. var rawRow xlsxRow
  857. var cell xlsxC
  858. var row *Row
  859. rawRow = xlsxRow{}
  860. cell = xlsxC{R: "A1"}
  861. cell = xlsxC{R: "A2"}
  862. rawRow.C = append(rawRow.C, cell)
  863. row = makeRowFromRaw(rawRow)
  864. c.Assert(row, NotNil)
  865. c.Assert(row.Cells, HasLen, 1)
  866. }
  867. // When a cell claims it is at a position greater than its ordinal
  868. // position in the file we make up the missing cells.
  869. func (l *LibSuite) TestReadRowFromRawWithMissingCells(c *C) {
  870. var rawRow xlsxRow
  871. var cell xlsxC
  872. var row *Row
  873. rawRow = xlsxRow{}
  874. cell = xlsxC{R: "A1"}
  875. rawRow.C = append(rawRow.C, cell)
  876. cell = xlsxC{R: "E1"}
  877. rawRow.C = append(rawRow.C, cell)
  878. row = makeRowFromRaw(rawRow)
  879. c.Assert(row, NotNil)
  880. c.Assert(row.Cells, HasLen, 5)
  881. }
  882. // We can cope with missing coordinate references
  883. func (l *LibSuite) TestReadRowFromRawWithPartialCoordinates(c *C) {
  884. var rawRow xlsxRow
  885. var cell xlsxC
  886. var row *Row
  887. rawRow = xlsxRow{}
  888. cell = xlsxC{R: "A1"}
  889. rawRow.C = append(rawRow.C, cell)
  890. cell = xlsxC{}
  891. rawRow.C = append(rawRow.C, cell)
  892. cell = xlsxC{R: "Z:1"}
  893. rawRow.C = append(rawRow.C, cell)
  894. cell = xlsxC{}
  895. rawRow.C = append(rawRow.C, cell)
  896. row = makeRowFromRaw(rawRow)
  897. c.Assert(row, NotNil)
  898. c.Assert(row.Cells, HasLen, 27)
  899. }
  900. func (l *LibSuite) TestSharedFormulas(c *C) {
  901. var sheetxml = bytes.NewBufferString(`
  902. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  903. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
  904. xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  905. <dimension ref="A1:C2"/>
  906. <sheetViews>
  907. <sheetView tabSelected="1" workbookViewId="0">
  908. <selection activeCell="C1" sqref="C1"/>
  909. </sheetView>
  910. </sheetViews>
  911. <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
  912. <sheetData>
  913. <row r="1" spans="1:3">
  914. <c r="A1">
  915. <v>1</v>
  916. </c>
  917. <c r="B1">
  918. <v>2</v>
  919. </c>
  920. <c r="C1">
  921. <v>3</v>
  922. </c>
  923. </row>
  924. <row r="2" spans="1:3">
  925. <c r="A2">
  926. <v>2</v>
  927. <f t="shared" ref="A2:C2" si="0">2*A1</f>
  928. </c>
  929. <c r="B2">
  930. <v>4</v>
  931. <f t="shared" si="0"/>
  932. </c>
  933. <c r="C2">
  934. <v>6</v>
  935. <f t="shared" si="0"/>
  936. </c>
  937. </row>
  938. </sheetData>
  939. <pageMargins left="0.7" right="0.7"
  940. top="0.78740157499999996"
  941. bottom="0.78740157499999996"
  942. header="0.3"
  943. footer="0.3"/>
  944. </worksheet>`)
  945. worksheet := new(xlsxWorksheet)
  946. err := xml.NewDecoder(sheetxml).Decode(worksheet)
  947. c.Assert(err, IsNil)
  948. file := new(File)
  949. rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
  950. c.Assert(maxCols, Equals, 3)
  951. c.Assert(maxRows, Equals, 2)
  952. row := rows[1]
  953. c.Assert(row.Cells[1].Formula(), Equals, "2*B1")
  954. c.Assert(row.Cells[2].Formula(), Equals, "2*C1")
  955. }
  956. // Avoid panic when cell.F.T is "e" (for error)
  957. func (l *LibSuite) TestFormulaForCellPanic(c *C) {
  958. cell := xlsxC{R: "A1"}
  959. // This line would panic before the fix.
  960. sharedFormulas := make(map[int]sharedFormula)
  961. // Not really an important test; getting here without a
  962. // panic is the real win.
  963. c.Assert(formulaForCell(cell, sharedFormulas), Equals, "")
  964. }