Skip to content

Commit

Permalink
Fix for tealeg#78 : Change default behavior when reading empty cols a…
Browse files Browse the repository at this point in the history
…nd rows. Now it returns empty cells. And now it reads Col.Width.
  • Loading branch information
Yoshiki Shibukawa committed Jan 18, 2015
1 parent 9632e69 commit a5f93ed
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 9 deletions.
18 changes: 18 additions & 0 deletions file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -764,3 +764,21 @@ func (l *FileSuite) TestReadWorkbookWithTypes(c *C) {
c.Assert(sheet.Rows[7].Cells[0].Formula(), Equals, "10/0")
c.Assert(sheet.Rows[7].Cells[0].Value, Equals, "#DIV/0!")
}

func (s *SliceReaderSuite) TestFileWithEmptyRows(c *C) {
f, err := OpenFile("./testdocs/empty_rows.xlsx")
c.Assert(err, IsNil)
sheet, ok := f.Sheet["EmptyRows"]
c.Assert(ok, Equals, true)
c.Assert(sheet.Cell(0, 0).String(), Equals, "")
c.Assert(sheet.Cell(2, 0).String(), Equals, "A3")
}

func (s *SliceReaderSuite) TestFileWithEmptyCols(c *C) {
f, err := OpenFile("./testdocs/empty_rows.xlsx")
c.Assert(err, IsNil)
sheet, ok := f.Sheet["EmptyCols"]
c.Assert(ok, Equals, true)
c.Assert(sheet.Cell(0, 0).String(), Equals, "")
c.Assert(sheet.Cell(0, 2).String(), Equals, "C1")
}
26 changes: 19 additions & 7 deletions lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ func makeRowFromRaw(rawrow xlsxRow) *Row {
return row
}

func makeEmptyRow() *Row {
row := new(Row)
row.Cells = make([]*Cell, 0)
return row
}

// fillCellData attempts to extract a valid value, usable in
// CSV form from the raw cell value. Note - this is not actually
// general enough - we should support retaining tabs and newlines.
Expand Down Expand Up @@ -367,8 +373,8 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, []*Col, in
if err != nil {
panic(err.Error())
}
rowCount = (maxRow - minRow) + 1
colCount = (maxCol - minCol) + 1
rowCount = maxRow + 1
colCount = maxCol + 1
rows = make([]*Row, rowCount)
cols = make([]*Col, colCount)
insertRowIndex = minRow
Expand All @@ -389,17 +395,23 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, []*Col, in
cols[i-1] = &Col{
Min: rawcol.Min,
Max: rawcol.Max,
Hidden: rawcol.Hidden}
Hidden: rawcol.Hidden,
Width: rawcol.Width}
}
}

// insert leading empty rows that is in front of minRow
for rowIndex := 0; rowIndex < minRow; rowIndex++ {
rows[rowIndex] = makeEmptyRow()
}

for rowIndex := 0; rowIndex < len(Worksheet.SheetData.Row); rowIndex++ {
rawrow := Worksheet.SheetData.Row[rowIndex]
// Some spreadsheets will omit blank rows from the
// stored data
for rawrow.R > (insertRowIndex + 1) {
// Put an empty Row into the array
rows[insertRowIndex-minRow] = new(Row)
rows[insertRowIndex-minRow] = makeEmptyRow()
insertRowIndex++
}
// range is not empty and only one range exist
Expand All @@ -422,7 +434,7 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, []*Col, in
row.Cells[insertColIndex-minCol] = new(Cell)
insertColIndex++
}
cellX := insertColIndex - minCol
cellX := insertColIndex
cell := row.Cells[cellX]
fillCellData(rawcell, reftable, cell)
if file.styles != nil {
Expand All @@ -433,8 +445,8 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, []*Col, in
cell.Hidden = rawrow.Hidden || (len(cols) > cellX && cell.Hidden)
insertColIndex++
}
if len(rows) > insertRowIndex-minRow {
rows[insertRowIndex-minRow] = row
if len(rows) > insertRowIndex {
rows[insertRowIndex] = row
}
insertRowIndex++
}
Expand Down
78 changes: 76 additions & 2 deletions lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,83 @@ func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyRows(c *C) {

file := new(File)
file.referenceTable = MakeSharedStringRefTable(sst)
_, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
c.Assert(maxRows, Equals, 2)
rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
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)
c.Assert(rows[3].Cells[0].String(), Equals, "ABC")
c.Assert(len(rows[4].Cells), Equals, 1)
c.Assert(rows[4].Cells[0].String(), 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)
rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
c.Assert(maxRows, Equals, 2)
c.Assert(maxCols, Equals, 4)

c.Assert(len(rows[0].Cells), Equals, 4)
c.Assert(rows[0].Cells[0].String(), Equals, "")
c.Assert(rows[0].Cells[1].String(), Equals, "")
c.Assert(rows[0].Cells[2].String(), Equals, "ABC")
c.Assert(rows[0].Cells[3].String(), Equals, "DEF")
c.Assert(len(rows[1].Cells), Equals, 4)
c.Assert(rows[1].Cells[0].String(), Equals, "")
c.Assert(rows[1].Cells[1].String(), Equals, "")
c.Assert(rows[1].Cells[2].String(), Equals, "ABC")
c.Assert(rows[1].Cells[3].String(), 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) {
Expand Down
Binary file added testdocs/empty_rows.xlsx
Binary file not shown.

0 comments on commit a5f93ed

Please sign in to comment.