Browse Source

Allow for manual calculation of the dimensions of a sheet if no DimensionRef is
provided in the worksheet. Issue 30 occurs because this element is missing
from Google Docs XLSX output.

Geoffrey J. Teale 11 years ago
parent
commit
9f1865bd41
2 changed files with 86 additions and 1 deletions
  1. 40 1
      lib.go
  2. 46 0
      lib_test.go

+ 40 - 1
lib.go

@@ -227,6 +227,41 @@ func getMaxMinFromDimensionRef(ref string) (minx, miny, maxx, maxy int, err erro
 	return
 }
 
+// calculateMaxMinFromWorkSheet works out the dimensions of a spreadsheet
+// that doesn't have a DimensionRef set.  The only case currently
+// known where this is true is with XLSX exported from Google Docs.
+func calculateMaxMinFromWorksheet(worksheet *xlsxWorksheet) (minx, miny, maxx, maxy int, err error) {
+	// Note, this method could be very slow for large spreadsheets.
+	var x, y int
+	minx = 0
+	miny = 0
+	maxy = 0
+	maxx = 0
+	for _, row := range worksheet.SheetData.Row {
+		for _, cell := range row.C {
+			x, y, err = getCoordsFromCellIDString(cell.R)
+			if err != nil {
+				return -1, -1, -1, -1, err
+			}
+			if x < minx {
+				minx = x
+			}
+			if x > maxx {
+				maxx = x
+			}
+			if y < miny {
+				miny = y
+			}
+			if y > maxy {
+				maxy = y
+			}
+		}
+	}
+	return
+}
+
+
+
 // makeRowFromSpan will, when given a span expressed as a string,
 // return an empty Row large enough to encompass that span and
 // populate it with empty cells.  All rows start from cell 1 -
@@ -316,7 +351,11 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, int, int)
 		return nil, 0, 0
 	}
 	reftable = file.referenceTable
-	minCol, minRow, maxCol, maxRow, err = getMaxMinFromDimensionRef(Worksheet.Dimension.Ref)
+	if len(Worksheet.Dimension.Ref) > 0 {
+		minCol, minRow, maxCol, maxRow, err = getMaxMinFromDimensionRef(Worksheet.Dimension.Ref)
+	} else {
+		minCol, minRow, maxCol, maxRow, err = calculateMaxMinFromWorksheet(Worksheet)
+	}
 	if err != nil {
 		panic(err.Error())
 	}

+ 46 - 0
lib_test.go

@@ -306,6 +306,52 @@ func (l *LibSuite) TestGetMaxMinFromDimensionRef(c *C) {
 	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