lib_test.go 40 KB

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