lib_test.go 41 KB

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