12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349 |
- package xlsx
- import (
- "bytes"
- "encoding/xml"
- "os"
- "strings"
- . "gopkg.in/check.v1"
- )
- type LibSuite struct{}
- var _ = Suite(&LibSuite{})
- // Attempting to open a file without workbook.xml.rels returns an error.
- func (l *LibSuite) TestReadZipReaderWithFileWithNoWorkbookRels(c *C) {
- _, err := OpenFile("./testdocs/badfile_noWorkbookRels.xlsx")
- c.Assert(err, NotNil)
- c.Assert(err.Error(), Equals, "xl/_rels/workbook.xml.rels not found in input xlsx.")
- }
- // Attempting to open a file with no worksheets returns an error.
- func (l *LibSuite) TestReadZipReaderWithFileWithNoWorksheets(c *C) {
- _, err := OpenFile("./testdocs/badfile_noWorksheets.xlsx")
- c.Assert(err, NotNil)
- c.Assert(err.Error(), Equals, "Input xlsx contains no worksheets.")
- }
- // Attempt to read data from a file with inlined string sheet data.
- func (l *LibSuite) TestReadWithInlineStrings(c *C) {
- var xlsxFile *File
- var err error
- xlsxFile, err = OpenFile("./testdocs/inlineStrings.xlsx")
- c.Assert(err, IsNil)
- sheet := xlsxFile.Sheets[0]
- r1 := sheet.Rows[0]
- c1 := r1.Cells[1]
- val, err := c1.FormattedValue()
- if err != nil {
- c.Error(err)
- return
- }
- if val == "" {
- c.Error("Expected a string value")
- return
- }
- c.Assert(val, Equals, "HL Retail - North America - Activity by Day - MTD")
- }
- // which they are contained from the XLSX file, even when the
- // worksheet files have arbitrary, non-numeric names.
- func (l *LibSuite) TestReadWorkbookRelationsFromZipFileWithFunnyNames(c *C) {
- var xlsxFile *File
- var err error
- xlsxFile, err = OpenFile("./testdocs/testrels.xlsx")
- c.Assert(err, IsNil)
- bob := xlsxFile.Sheet["Bob"]
- row1 := bob.Rows[0]
- cell1 := row1.Cells[0]
- if val, err := cell1.FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "I am Bob")
- }
- }
- // We can marshal WorkBookRels to an xml file
- func (l *LibSuite) TestWorkBookRelsMarshal(c *C) {
- var rels WorkBookRels = make(WorkBookRels)
- rels["rId1"] = "worksheets/sheet.xml"
- expectedXML := `<?xml version="1.0" encoding="UTF-8"?>
- <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>`
- xRels := rels.MakeXLSXWorkbookRels()
- output := bytes.NewBufferString(xml.Header)
- body, err := xml.Marshal(xRels)
- c.Assert(err, IsNil)
- c.Assert(body, NotNil)
- _, err = output.Write(body)
- c.Assert(err, IsNil)
- c.Assert(output.String(), Equals, expectedXML)
- }
- // Excel column codes are a special form of base26 that doesn't allow
- // zeros, except in the least significant part of the code. Test we
- // can smoosh the numbers in a normal base26 representation (presented
- // as a slice of integers) down to this form.
- func (l *LibSuite) TestSmooshBase26Slice(c *C) {
- input := []int{20, 0, 1}
- expected := []int{19, 26, 1}
- c.Assert(smooshBase26Slice(input), DeepEquals, expected)
- }
- // formatColumnName converts slices of base26 integers to alphabetical
- // column names. Note that the least signifcant character has a
- // different numeric offset (Yuck!)
- func (l *LibSuite) TestFormatColumnName(c *C) {
- c.Assert(formatColumnName([]int{0}), Equals, "A")
- c.Assert(formatColumnName([]int{25}), Equals, "Z")
- c.Assert(formatColumnName([]int{1, 25}), Equals, "AZ")
- c.Assert(formatColumnName([]int{26, 25}), Equals, "ZZ")
- c.Assert(formatColumnName([]int{26, 26, 25}), Equals, "ZZZ")
- }
- // getLargestDenominator returns the largest power of a provided value
- // that can fit within a given value.
- func (l *LibSuite) TestGetLargestDenominator(c *C) {
- d, p := getLargestDenominator(0, 1, 2, 0)
- c.Assert(d, Equals, 1)
- c.Assert(p, Equals, 0)
- d, p = getLargestDenominator(1, 1, 2, 0)
- c.Assert(d, Equals, 1)
- c.Assert(p, Equals, 0)
- d, p = getLargestDenominator(2, 1, 2, 0)
- c.Assert(d, Equals, 2)
- c.Assert(p, Equals, 1)
- d, p = getLargestDenominator(4, 1, 2, 0)
- c.Assert(d, Equals, 4)
- c.Assert(p, Equals, 2)
- d, p = getLargestDenominator(8, 1, 2, 0)
- c.Assert(d, Equals, 8)
- c.Assert(p, Equals, 3)
- d, p = getLargestDenominator(9, 1, 2, 0)
- c.Assert(d, Equals, 8)
- c.Assert(p, Equals, 3)
- d, p = getLargestDenominator(15, 1, 2, 0)
- c.Assert(d, Equals, 8)
- c.Assert(p, Equals, 3)
- d, p = getLargestDenominator(16, 1, 2, 0)
- c.Assert(d, Equals, 16)
- c.Assert(p, Equals, 4)
- }
- func (l *LibSuite) TestLettersToNumeric(c *C) {
- cases := map[string]int{"A": 0, "G": 6, "z": 25, "AA": 26, "Az": 51,
- "BA": 52, "BZ": 77, "ZA": 26*26 + 0, "ZZ": 26*26 + 25,
- "AAA": 26*26 + 26 + 0, "AMI": 1022}
- for input, ans := range cases {
- output := lettersToNumeric(input)
- c.Assert(output, Equals, ans)
- }
- }
- func (l *LibSuite) TestNumericToLetters(c *C) {
- cases := map[string]int{
- "A": 0,
- "G": 6,
- "Z": 25,
- "AA": 26,
- "AZ": 51,
- "BA": 52,
- "BZ": 77, "ZA": 26 * 26, "ZB": 26*26 + 1,
- "ZZ": 26*26 + 25,
- "AAA": 26*26 + 26 + 0, "AMI": 1022}
- for ans, input := range cases {
- output := numericToLetters(input)
- c.Assert(output, Equals, ans)
- }
- }
- func (l *LibSuite) TestLetterOnlyMapFunction(c *C) {
- var input string = "ABC123"
- var output string = strings.Map(letterOnlyMapF, input)
- c.Assert(output, Equals, "ABC")
- input = "abc123"
- output = strings.Map(letterOnlyMapF, input)
- c.Assert(output, Equals, "ABC")
- }
- func (l *LibSuite) TestIntOnlyMapFunction(c *C) {
- var input string = "ABC123"
- var output string = strings.Map(intOnlyMapF, input)
- c.Assert(output, Equals, "123")
- }
- func (l *LibSuite) TestGetCoordsFromCellIDString(c *C) {
- var cellIDString string = "A3"
- var x, y int
- var err error
- x, y, err = GetCoordsFromCellIDString(cellIDString)
- c.Assert(err, IsNil)
- c.Assert(x, Equals, 0)
- c.Assert(y, Equals, 2)
- }
- func (l *LibSuite) TestGetCellIDStringFromCoords(c *C) {
- c.Assert(GetCellIDStringFromCoords(0, 0), Equals, "A1")
- c.Assert(GetCellIDStringFromCoords(2, 2), Equals, "C3")
- }
- func (l *LibSuite) TestGetMaxMinFromDimensionRef(c *C) {
- var dimensionRef string = "A1:B2"
- var minx, miny, maxx, maxy int
- var err error
- minx, miny, maxx, maxy, err = getMaxMinFromDimensionRef(dimensionRef)
- c.Assert(err, IsNil)
- c.Assert(minx, Equals, 0)
- c.Assert(miny, Equals, 0)
- c.Assert(maxx, Equals, 1)
- c.Assert(maxy, Equals, 1)
- }
- func (l *LibSuite) TestCalculateMaxMinFromWorksheet(c *C) {
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <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">
- <sheetViews>
- <sheetView workbookViewId="0"/>
- </sheetViews>
- <sheetFormatPr customHeight="1" defaultColWidth="14.43" defaultRowHeight="15.75"/>
- <sheetData>
- <row r="1">
- <c t="s" s="1" r="A1">
- <v>0</v>
- </c>
- <c t="s" s="1" r="B1">
- <v>1</v>
- </c>
- </row>
- <row r="2">
- <c t="s" s="1" r="A2">
- <v>2</v>
- </c>
- <c t="s" s="1" r="B2">
- <v>3</v>
- </c>
- </row>
- </sheetData>
- <drawing r:id="rId1"/>
- </worksheet>`)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- minx, miny, maxx, maxy, err := calculateMaxMinFromWorksheet(worksheet)
- c.Assert(err, IsNil)
- c.Assert(minx, Equals, 0)
- c.Assert(miny, Equals, 0)
- c.Assert(maxx, Equals, 1)
- c.Assert(maxy, Equals, 1)
- }
- func (l *LibSuite) TestGetRangeFromString(c *C) {
- var rangeString string
- var lower, upper int
- var err error
- rangeString = "1:3"
- lower, upper, err = getRangeFromString(rangeString)
- c.Assert(err, IsNil)
- c.Assert(lower, Equals, 1)
- c.Assert(upper, Equals, 3)
- }
- func (l *LibSuite) TestMakeRowFromSpan(c *C) {
- var rangeString string
- var row *Row
- var length int
- var sheet *Sheet
- sheet = new(Sheet)
- rangeString = "1:3"
- row = makeRowFromSpan(rangeString, sheet)
- length = len(row.Cells)
- c.Assert(length, Equals, 3)
- c.Assert(row.Sheet, Equals, sheet)
- rangeString = "5:7" // Note - we ignore lower bound!
- row = makeRowFromSpan(rangeString, sheet)
- length = len(row.Cells)
- c.Assert(length, Equals, 7)
- c.Assert(row.Sheet, Equals, sheet)
- rangeString = "1:1"
- row = makeRowFromSpan(rangeString, sheet)
- length = len(row.Cells)
- c.Assert(length, Equals, 1)
- c.Assert(row.Sheet, Equals, sheet)
- }
- func (l *LibSuite) TestReadRowsFromSheet(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
- <si>
- <t>Foo</t>
- </si>
- <si>
- <t>Bar</t>
- </si>
- <si>
- <t xml:space="preserve">Baz </t>
- </si>
- <si>
- <t>Quuk</t>
- </si>
- </sst>`)
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
- xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
- <dimension ref="A1:B2"/>
- <sheetViews>
- <sheetView tabSelected="1" workbookViewId="0">
- <selection activeCell="C2" sqref="C2"/>
- <pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
- </sheetView>
- </sheetViews>
- <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
- <sheetData>
- <row r="1" spans="1:2" ht="123.45" customHeight="1">
- <c r="A1" t="s">
- <v>0</v>
- </c>
- <c r="B1" t="s">
- <v>1</v>
- </c>
- </row>
- <row r="2" spans="1:2">
- <c r="A2" t="s">
- <v>2</v>
- </c>
- <c r="B2" t="s">
- <v>3</v>
- </c>
- </row>
- </sheetData>
- <pageMargins left="0.7" right="0.7"
- top="0.78740157499999996"
- bottom="0.78740157499999996"
- header="0.3"
- footer="0.3"/>
- </worksheet>`)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxRows, Equals, 2)
- c.Assert(maxCols, Equals, 2)
- row := rows[0]
- c.Assert(row.Sheet, Equals, sheet)
- c.Assert(len(row.Cells), Equals, 2)
- c.Assert(row.Height, Equals, 123.45)
- c.Assert(row.isCustom, Equals, true)
- cell1 := row.Cells[0]
- c.Assert(cell1.Value, Equals, "Foo")
- cell2 := row.Cells[1]
- c.Assert(cell2.Value, Equals, "Bar")
- col := cols[0]
- c.Assert(col.Min, Equals, 0)
- c.Assert(col.Max, Equals, 0)
- c.Assert(col.Hidden, Equals, false)
- c.Assert(len(worksheet.SheetViews.SheetView), Equals, 1)
- sheetView := worksheet.SheetViews.SheetView[0]
- c.Assert(sheetView.Pane, NotNil)
- pane := sheetView.Pane
- c.Assert(pane.XSplit, Equals, 0.0)
- c.Assert(pane.YSplit, Equals, 1.0)
- }
- func (l *LibSuite) TestReadRowsFromSheetWithMergeCells(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="3" uniqueCount="3">
- <si>
- <t>Value A</t>
- </si>
- <si>
- <t>Value B</t>
- </si>
- <si>
- <t>Value C</t>
- </si>
- </sst>
- `)
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <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">
- <sheetViews>
- <sheetView workbookViewId="0"/>
- </sheetViews>
- <sheetFormatPr customHeight="1" defaultColWidth="17.29" defaultRowHeight="15.0"/>
- <cols>
- <col customWidth="1" min="1" max="6" width="14.43"/>
- </cols>
- <sheetData>
- <row r="1" ht="15.75" customHeight="1">
- <c r="A1" s="1" t="s">
- <v>0</v>
- </c>
- </row>
- <row r="2" ht="15.75" customHeight="1">
- <c r="A2" s="1" t="s">
- <v>1</v>
- </c>
- <c r="B2" s="1" t="s">
- <v>2</v>
- </c>
- </row>
- </sheetData>
- <mergeCells count="1">
- <mergeCell ref="A1:B1"/>
- </mergeCells>
- <drawing r:id="rId1"/>
- </worksheet>`)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, _, _, _ := readRowsFromSheet(worksheet, file, sheet)
- row := rows[0] //
- cell1 := row.Cells[0]
- c.Assert(cell1.HMerge, Equals, 1)
- c.Assert(cell1.VMerge, Equals, 0)
- }
- // An invalid value in the "r" attribute in a <row> was causing a panic
- // in readRowsFromSheet. This test is a copy of TestReadRowsFromSheet,
- // with the important difference of the value 1048576 below in <row r="1048576", which is
- // higher than the number of rows in the sheet. That number itself isn't significant;
- // it just happens to be the value found to trigger the error in a user's file.
- func (l *LibSuite) TestReadRowsFromSheetBadR(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
- <si>
- <t>Foo</t>
- </si>
- <si>
- <t>Bar</t>
- </si>
- <si>
- <t xml:space="preserve">Baz </t>
- </si>
- <si>
- <t>Quuk</t>
- </si>
- </sst>`)
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
- xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
- <dimension ref="A1:B2"/>
- <sheetViews>
- <sheetView tabSelected="1" workbookViewId="0">
- <selection activeCell="C2" sqref="C2"/>
- <pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
- </sheetView>
- </sheetViews>
- <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
- <sheetData>
- <row r="1" spans="1:2">
- <c r="A1" t="s">
- <v>0</v>
- </c>
- <c r="B1" t="s">
- <v>1</v>
- </c>
- </row>
- <row r="1048576" spans="1:2">
- <c r="A2" t="s">
- <v>2</v>
- </c>
- <c r="B2" t="s">
- <v>3</v>
- </c>
- </row>
- </sheetData>
- <pageMargins left="0.7" right="0.7"
- top="0.78740157499999996"
- bottom="0.78740157499999996"
- header="0.3"
- footer="0.3"/>
- </worksheet>`)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- // Discarding all return values; this test is a regression for
- // a panic due to an "index out of range."
- readRowsFromSheet(worksheet, file, sheet)
- }
- func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyRows(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2"><si><t>ABC</t></si><si><t>DEF</t></si></sst>`)
- var sheetxml = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <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">
- <dimension ref="A4:A5"/>
- <sheetViews>
- <sheetView tabSelected="1" workbookViewId="0">
- <selection activeCell="A2" sqref="A2"/>
- </sheetView>
- </sheetViews>
- <sheetFormatPr baseColWidth="10" defaultRowHeight="15" x14ac:dyDescent="0"/>
- <sheetData>
- <row r="4" spans="1:1">
- <c r="A4" t="s">
- <v>0</v>
- </c>
- </row>
- <row r="5" spans="1:1">
- <c r="A5" t="s">
- <v>1</v>
- </c>
- </row>
- </sheetData>
- <pageMargins left="0.75" right="0.75" top="1" bottom="1" header="0.5" footer="0.5"/>
- <pageSetup paperSize="9" orientation="portrait" horizontalDpi="4294967292" verticalDpi="4294967292"/>
- <extLst>
- <ext uri="{64002731-A6B0-56B0-2670-7721B7C09600}" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main">
- <mx:PLV Mode="0" OnePage="0" WScale="0"/>
- </ext>
- </extLst>
- </worksheet>
- `)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxRows, Equals, 5)
- c.Assert(maxCols, Equals, 1)
- c.Assert(len(rows[0].Cells), Equals, 0)
- c.Assert(len(rows[1].Cells), Equals, 0)
- c.Assert(len(rows[2].Cells), Equals, 0)
- c.Assert(len(rows[3].Cells), Equals, 1)
- if val, err := rows[3].Cells[0].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "ABC")
- }
- c.Assert(len(rows[4].Cells), Equals, 1)
- if val, err := rows[4].Cells[0].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "DEF")
- }
- }
- func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyCols(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2"><si><t>ABC</t></si><si><t>DEF</t></si></sst>`)
- var sheetxml = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <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">
- <dimension ref="C1:D2"/>
- <sheetViews>
- <sheetView tabSelected="1" workbookViewId="0">
- <selection activeCell="A2" sqref="A2"/>
- </sheetView>
- </sheetViews>
- <sheetFormatPr baseColWidth="10" defaultRowHeight="15" x14ac:dyDescent="0"/>
- <cols>
- <col min="3" max="3" width="17" customWidth="1"/>
- <col min="4" max="4" width="18" customWidth="1"/>
- </cols>
- <sheetData>
- <row r="1" spans="3:4">
- <c r="C1" t="s"><v>0</v></c>
- <c r="D1" t="s"><v>1</v></c>
- </row>
- <row r="2" spans="3:4">
- <c r="C2" t="s"><v>0</v></c>
- <c r="D2" t="s"><v>1</v></c>
- </row>
- </sheetData>
- <pageMargins left="0.75" right="0.75" top="1" bottom="1" header="0.5" footer="0.5"/>
- <pageSetup paperSize="9" orientation="portrait" horizontalDpi="4294967292" verticalDpi="4294967292"/>
- <extLst>
- <ext uri="{64002731-A6B0-56B0-2670-7721B7C09600}" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main">
- <mx:PLV Mode="0" OnePage="0" WScale="0"/>
- </ext>
- </extLst>
- </worksheet>
- `)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxRows, Equals, 2)
- c.Assert(maxCols, Equals, 4)
- c.Assert(len(rows[0].Cells), Equals, 4)
- if val, err := rows[0].Cells[0].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "")
- }
- if val, err := rows[0].Cells[1].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "")
- }
- if val, err := rows[0].Cells[2].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "ABC")
- }
- if val, err := rows[0].Cells[3].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "DEF")
- }
- c.Assert(len(rows[1].Cells), Equals, 4)
- if val, err := rows[1].Cells[0].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "")
- }
- if val, err := rows[1].Cells[1].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "")
- }
- if val, err := rows[1].Cells[2].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "ABC")
- }
- if val, err := rows[1].Cells[3].FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "DEF")
- }
- c.Assert(len(cols), Equals, 4)
- c.Assert(cols[0].Width, Equals, 0.0)
- c.Assert(cols[1].Width, Equals, 0.0)
- c.Assert(cols[2].Width, Equals, 17.0)
- c.Assert(cols[3].Width, Equals, 18.0)
- }
- func (l *LibSuite) TestReadRowsFromSheetWithEmptyCells(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="8" uniqueCount="5">
- <si>
- <t>Bob</t>
- </si>
- <si>
- <t>Alice</t>
- </si>
- <si>
- <t>Sue</t>
- </si>
- <si>
- <t>Yes</t>
- </si>
- <si>
- <t>No</t>
- </si>
- </sst>
- `)
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <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"/>
- <sheetData>
- <row r="1" spans="1:3">
- <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>
- </row>
- <row r="2" spans="1:3">
- <c r="A2" t="s">
- <v>
- 3
- </v>
- </c>
- <c r="B2" t="s">
- <v>
- 4
- </v>
- </c>
- <c r="C2" t="s">
- <v>
- 3
- </v>
- </c>
- </row>
- <row r="3" spans="1:3">
- <c r="A3" t="s">
- <v>
- 4
- </v>
- </c>
- <c r="C3" t="s">
- <v>
- 3
- </v>
- </c>
- </row>
- </sheetData>
- <pageMargins left="0.7" right="0.7" top="0.78740157499999996" bottom="0.78740157499999996" header="0.3" footer="0.3"/>
- </worksheet>
- `)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxRows, Equals, 3)
- c.Assert(maxCols, Equals, 3)
- row := rows[2]
- c.Assert(row.Sheet, Equals, sheet)
- c.Assert(len(row.Cells), Equals, 3)
- cell1 := row.Cells[0]
- c.Assert(cell1.Value, Equals, "No")
- cell2 := row.Cells[1]
- c.Assert(cell2.Value, Equals, "")
- cell3 := row.Cells[2]
- c.Assert(cell3.Value, Equals, "Yes")
- col := cols[0]
- c.Assert(col.Min, Equals, 0)
- c.Assert(col.Max, Equals, 0)
- c.Assert(col.Hidden, Equals, false)
- }
- func (l *LibSuite) TestReadRowsFromSheetWithTrailingEmptyCells(c *C) {
- var row *Row
- var cell1, cell2, cell3, cell4 *Cell
- var sharedstringsXML = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <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>`)
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <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>
- `)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, _, maxCol, maxRow := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxCol, Equals, 4)
- c.Assert(maxRow, Equals, 8)
- row = rows[0]
- c.Assert(row.Sheet, Equals, sheet)
- c.Assert(len(row.Cells), Equals, 4)
- cell1 = row.Cells[0]
- c.Assert(cell1.Value, Equals, "A")
- cell2 = row.Cells[1]
- c.Assert(cell2.Value, Equals, "B")
- cell3 = row.Cells[2]
- c.Assert(cell3.Value, Equals, "C")
- cell4 = row.Cells[3]
- c.Assert(cell4.Value, Equals, "D")
- row = rows[1]
- c.Assert(row.Sheet, Equals, sheet)
- c.Assert(len(row.Cells), Equals, 4)
- cell1 = row.Cells[0]
- c.Assert(cell1.Value, Equals, "1")
- cell2 = row.Cells[1]
- c.Assert(cell2.Value, Equals, "")
- cell3 = row.Cells[2]
- c.Assert(cell3.Value, Equals, "")
- cell4 = row.Cells[3]
- c.Assert(cell4.Value, Equals, "")
- }
- func (l *LibSuite) TestReadRowsFromSheetWithMultipleSpans(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
- <si>
- <t>Foo</t>
- </si>
- <si>
- <t>Bar</t>
- </si>
- <si>
- <t xml:space="preserve">Baz </t>
- </si>
- <si>
- <t>Quuk</t>
- </si>
- </sst>`)
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
- xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
- <dimension ref="A1:D2"/>
- <sheetViews>
- <sheetView tabSelected="1" workbookViewId="0">
- <selection activeCell="C2" sqref="C2"/>
- </sheetView>
- </sheetViews>
- <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
- <sheetData>
- <row r="1" spans="1:2 3: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>0</v>
- </c>
- <c r="D1" t="s">
- <v>1</v>
- </c>
- </row>
- <row r="2" spans="1:2 3:4">
- <c r="A2" t="s">
- <v>2</v>
- </c>
- <c r="B2" t="s">
- <v>3</v>
- </c>
- <c r="C2" t="s">
- <v>2</v>
- </c>
- <c r="D2" t="s">
- <v>3</v>
- </c>
- </row>
- </sheetData>
- <pageMargins left="0.7" right="0.7"
- top="0.78740157499999996"
- bottom="0.78740157499999996"
- header="0.3"
- footer="0.3"/>
- </worksheet>`)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxRows, Equals, 2)
- c.Assert(maxCols, Equals, 4)
- row := rows[0]
- c.Assert(row.Sheet, Equals, sheet)
- c.Assert(len(row.Cells), Equals, 4)
- cell1 := row.Cells[0]
- c.Assert(cell1.Value, Equals, "Foo")
- cell2 := row.Cells[1]
- c.Assert(cell2.Value, Equals, "Bar")
- cell3 := row.Cells[2]
- c.Assert(cell3.Value, Equals, "Foo")
- cell4 := row.Cells[3]
- c.Assert(cell4.Value, Equals, "Bar")
- }
- func (l *LibSuite) TestReadRowsFromSheetWithMultipleTypes(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
- <si>
- <t>Hello World</t>
- </si>
- </sst>`)
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
- xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
- <dimension ref="A1:F1"/>
- <sheetViews>
- <sheetView tabSelected="1" workbookViewId="0">
- <selection activeCell="C1" sqref="C1"/>
- </sheetView>
- </sheetViews>
- <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
- <sheetData>
- <row r="1" spans="1:6">
- <c r="A1" t="s">
- <v>0</v>
- </c>
- <c r="B1">
- <v>12345</v>
- </c>
- <c r="C1">
- <v>1.024</v>
- </c>
- <c r="D1" t="b">
- <v>1</v>
- </c>
- <c r="E1">
- <f>10+20</f>
- <v>30</v>
- </c>
- <c r="F1" t="e">
- <f>10/0</f>
- <v>#DIV/0!</v>
- </c>
- </row>
- </sheetData>
- <pageMargins left="0.7" right="0.7"
- top="0.78740157499999996"
- bottom="0.78740157499999996"
- header="0.3"
- footer="0.3"/>
- </worksheet>`)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxRows, Equals, 1)
- c.Assert(maxCols, Equals, 6)
- row := rows[0]
- c.Assert(row.Sheet, Equals, sheet)
- c.Assert(len(row.Cells), Equals, 6)
- cell1 := row.Cells[0]
- c.Assert(cell1.Type(), Equals, CellTypeString)
- if val, err := cell1.FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "Hello World")
- }
- cell2 := row.Cells[1]
- c.Assert(cell2.Type(), Equals, CellTypeNumeric)
- intValue, _ := cell2.Int()
- c.Assert(intValue, Equals, 12345)
- cell3 := row.Cells[2]
- c.Assert(cell3.Type(), Equals, CellTypeNumeric)
- float, _ := cell3.Float()
- c.Assert(float, Equals, 1.024)
- cell4 := row.Cells[3]
- c.Assert(cell4.Type(), Equals, CellTypeBool)
- c.Assert(cell4.Bool(), Equals, true)
- cell5 := row.Cells[4]
- c.Assert(cell5.Type(), Equals, CellTypeFormula)
- c.Assert(cell5.Formula(), Equals, "10+20")
- c.Assert(cell5.Value, Equals, "30")
- cell6 := row.Cells[5]
- c.Assert(cell6.Type(), Equals, CellTypeError)
- c.Assert(cell6.Formula(), Equals, "10/0")
- c.Assert(cell6.Value, Equals, "#DIV/0!")
- }
- func (l *LibSuite) TestReadRowsFromSheetWithHiddenColumn(c *C) {
- var sharedstringsXML = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
- <si><t>This is a test.</t></si>
- <si><t>This should be invisible.</t></si>
- </sst>`)
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <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"
- 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"
- xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
- <sheetViews><sheetView workbookViewId="0"/>
- </sheetViews>
- <sheetFormatPr customHeight="1" defaultColWidth="14.43" defaultRowHeight="15.75"/>
- <cols>
- <col hidden="1" max="2" min="2"/>
- </cols>
- <sheetData>
- <row r="1">
- <c r="A1" s="1" t="s"><v>0</v></c>
- <c r="B1" s="1" t="s"><v>1</v></c>
- </row>
- </sheetData><drawing r:id="rId1"/></worksheet>`)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- sst := new(xlsxSST)
- err = xml.NewDecoder(sharedstringsXML).Decode(sst)
- c.Assert(err, IsNil)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxRows, Equals, 1)
- c.Assert(maxCols, Equals, 2)
- row := rows[0]
- c.Assert(row.Sheet, Equals, sheet)
- c.Assert(len(row.Cells), Equals, 2)
- cell1 := row.Cells[0]
- c.Assert(cell1.Type(), Equals, CellTypeString)
- if val, err := cell1.FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "This is a test.")
- }
- c.Assert(cell1.Hidden, Equals, false)
- cell2 := row.Cells[1]
- c.Assert(cell2.Type(), Equals, CellTypeString)
- if val, err := cell2.FormattedValue(); err != nil {
- c.Error(err)
- } else {
- c.Assert(val, Equals, "This should be invisible.")
- }
- c.Assert(cell2.Hidden, Equals, true)
- }
- // When converting the xlsxRow to a Row we create a as many cells as we find.
- func (l *LibSuite) TestReadRowFromRaw(c *C) {
- var rawRow xlsxRow
- var cell xlsxC
- var row *Row
- rawRow = xlsxRow{}
- cell = xlsxC{R: "A1"}
- cell = xlsxC{R: "A2"}
- rawRow.C = append(rawRow.C, cell)
- sheet := new(Sheet)
- row = makeRowFromRaw(rawRow, sheet)
- c.Assert(row, NotNil)
- c.Assert(row.Cells, HasLen, 1)
- c.Assert(row.Sheet, Equals, sheet)
- }
- // When a cell claims it is at a position greater than its ordinal
- // position in the file we make up the missing cells.
- func (l *LibSuite) TestReadRowFromRawWithMissingCells(c *C) {
- var rawRow xlsxRow
- var cell xlsxC
- var row *Row
- rawRow = xlsxRow{}
- cell = xlsxC{R: "A1"}
- rawRow.C = append(rawRow.C, cell)
- cell = xlsxC{R: "E1"}
- rawRow.C = append(rawRow.C, cell)
- sheet := new(Sheet)
- row = makeRowFromRaw(rawRow, sheet)
- c.Assert(row, NotNil)
- c.Assert(row.Cells, HasLen, 5)
- c.Assert(row.Sheet, Equals, sheet)
- }
- // We can cope with missing coordinate references
- func (l *LibSuite) TestReadRowFromRawWithPartialCoordinates(c *C) {
- var rawRow xlsxRow
- var cell xlsxC
- var row *Row
- rawRow = xlsxRow{}
- cell = xlsxC{R: "A1"}
- rawRow.C = append(rawRow.C, cell)
- cell = xlsxC{}
- rawRow.C = append(rawRow.C, cell)
- cell = xlsxC{R: "Z:1"}
- rawRow.C = append(rawRow.C, cell)
- cell = xlsxC{}
- rawRow.C = append(rawRow.C, cell)
- sheet := new(Sheet)
- row = makeRowFromRaw(rawRow, sheet)
- c.Assert(row, NotNil)
- c.Assert(row.Cells, HasLen, 27)
- c.Assert(row.Sheet, Equals, sheet)
- }
- func (l *LibSuite) TestSharedFormulas(c *C) {
- var sheetxml = bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
- xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
- <dimension ref="A1:C2"/>
- <sheetViews>
- <sheetView tabSelected="1" workbookViewId="0">
- <selection activeCell="C1" sqref="C1"/>
- </sheetView>
- </sheetViews>
- <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
- <sheetData>
- <row r="1" spans="1:3">
- <c r="A1">
- <v>1</v>
- </c>
- <c r="B1">
- <v>2</v>
- </c>
- <c r="C1">
- <v>3</v>
- </c>
- </row>
- <row r="2" spans="1:3">
- <c r="A2">
- <v>2</v>
- <f t="shared" ref="A2:C2" si="0">2*A1</f>
- </c>
- <c r="B2">
- <v>4</v>
- <f t="shared" si="0"/>
- </c>
- <c r="C2">
- <v>6</v>
- <f t="shared" si="0"/>
- </c>
- </row>
- </sheetData>
- <pageMargins left="0.7" right="0.7"
- top="0.78740157499999996"
- bottom="0.78740157499999996"
- header="0.3"
- footer="0.3"/>
- </worksheet>`)
- worksheet := new(xlsxWorksheet)
- err := xml.NewDecoder(sheetxml).Decode(worksheet)
- c.Assert(err, IsNil)
- file := new(File)
- sheet := new(Sheet)
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
- c.Assert(maxCols, Equals, 3)
- c.Assert(maxRows, Equals, 2)
- row := rows[1]
- c.Assert(row.Cells[1].Formula(), Equals, "2*B1")
- c.Assert(row.Cells[2].Formula(), Equals, "2*C1")
- }
- // Test shared formulas that have absolute references ($) in them
- func (l *LibSuite) TestSharedFormulasWithAbsoluteReferences(c *C) {
- formulas := []string{
- "A1",
- "$A1",
- "A$1",
- "$A$1",
- "A1+B1",
- "$A1+B1",
- "$A$1+B1",
- "A1+$B1",
- "A1+B$1",
- "A1+$B$1",
- "$A$1+$B$1",
- `IF(C23>=E$12,"Q4",IF(C23>=$D$12,"Q3",IF(C23>=C$12,"Q2","Q1")))`,
- `SUM(D44:H44)*IM_A_DEFINED_NAME`,
- `IM_A_DEFINED_NAME+SUM(D44:H44)*IM_A_DEFINED_NAME_ALSO`,
- `SUM(D44:H44)*IM_A_DEFINED_NAME+A1`,
- "AA1",
- "$AA1",
- "AA$1",
- "$AA$1",
- }
- expected := []string{
- "B2",
- "$A2",
- "B$1",
- "$A$1",
- "B2+C2",
- "$A2+C2",
- "$A$1+C2",
- "B2+$B2",
- "B2+C$1",
- "B2+$B$1",
- "$A$1+$B$1",
- `IF(D24>=F$12,"Q4",IF(D24>=$D$12,"Q3",IF(D24>=D$12,"Q2","Q1")))`,
- `SUM(E45:I45)*IM_A_DEFINED_NAME`,
- `IM_A_DEFINED_NAME+SUM(E45:I45)*IM_A_DEFINED_NAME_ALSO`,
- `SUM(E45:I45)*IM_A_DEFINED_NAME+B2`,
- "AB2",
- "$AA2",
- "AB$1",
- "$AA$1",
- }
- anchorCell := "C4"
- sharedFormulas := map[int]sharedFormula{}
- x, y, _ := GetCoordsFromCellIDString(anchorCell)
- for i, formula := range formulas {
- res := formula
- sharedFormulas[i] = sharedFormula{x, y, res}
- }
- for i, formula := range formulas {
- testCell := xlsxC{
- R: "D5",
- F: &xlsxF{
- Content: formula,
- T: "shared",
- Si: i,
- },
- }
- c.Assert(formulaForCell(testCell, sharedFormulas), Equals, expected[i])
- }
- }
- // Avoid panic when cell.F.T is "e" (for error)
- func (l *LibSuite) TestFormulaForCellPanic(c *C) {
- cell := xlsxC{R: "A1"}
- // This line would panic before the fix.
- sharedFormulas := make(map[int]sharedFormula)
- // Not really an important test; getting here without a
- // panic is the real win.
- c.Assert(formulaForCell(cell, sharedFormulas), Equals, "")
- }
- func (l *LibSuite) TestRowNotOverwrittenWhenFollowedByEmptyRow(c *C) {
- sheetXML := bytes.NewBufferString(`
- <?xml version="1.0" encoding="UTF-8"?>
- <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">
- <sheetViews>
- <sheetView workbookViewId="0" />
- </sheetViews>
- <sheetFormatPr customHeight="1" defaultColWidth="14.43" defaultRowHeight="15.75" />
- <sheetData>
- <row r="2">
- <c r="A2" t="str">
- <f t="shared" ref="A2" si="1">RANDBETWEEN(1,100)</f>
- <v>66</v>
- </c>
- </row>
- <row r="3">
- <c r="A3" t="str">
- <f t="shared" ref="A3" si="2">RANDBETWEEN(1,100)</f>
- <v>30</v>
- </c>
- </row>
- <row r="4">
- <c r="A4" t="str">
- <f t="shared" ref="A4" si="3">RANDBETWEEN(1,100)</f>
- <v>75</v>
- </c>
- </row>
- <row r="7">
- <c r="A7" s="1" t="str">
- <f t="shared" ref="A7" si="4">A4/A2</f>
- <v>1.14</v>
- </c>
- </row>
- </sheetData>
- <drawing r:id="rId1" />
- </worksheet>
- `)
- sharedstringsXML := bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"/>`)
- worksheet := new(xlsxWorksheet)
- xml.NewDecoder(sheetXML).Decode(worksheet)
- sst := new(xlsxSST)
- xml.NewDecoder(sharedstringsXML).Decode(sst)
- file := new(File)
- file.referenceTable = MakeSharedStringRefTable(sst)
- sheet := new(Sheet)
- rows, _, _, _ := readRowsFromSheet(worksheet, file, sheet)
- cells := rows[3].Cells
- c.Assert(cells, HasLen, 1)
- c.Assert(cells[0].Value, Equals, "75")
- }
- // This was a specific issue raised by a user.
- func (l *LibSuite) TestRoundTripFileWithNoSheetCols(c *C) {
- originalXlFile, err := OpenFile("testdocs/original.xlsx")
- c.Assert(err, IsNil)
- originalXlFile.Save("testdocs/after_write.xlsx")
- _, err = OpenFile("testdocs/after_write.xlsx")
- c.Assert(err, IsNil)
- os.Remove("testdocs/after_write.xlsx")
- }
|