Kaynağa Gözat

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 yıl önce
ebeveyn
işleme
9f1865bd41
2 değiştirilmiş dosya ile 86 ekleme ve 1 silme
  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
 	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,
 // makeRowFromSpan will, when given a span expressed as a string,
 // return an empty Row large enough to encompass that span and
 // return an empty Row large enough to encompass that span and
 // populate it with empty cells.  All rows start from cell 1 -
 // 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
 		return nil, 0, 0
 	}
 	}
 	reftable = file.referenceTable
 	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 {
 	if err != nil {
 		panic(err.Error())
 		panic(err.Error())
 	}
 	}

+ 46 - 0
lib_test.go

@@ -306,6 +306,52 @@ func (l *LibSuite) TestGetMaxMinFromDimensionRef(c *C) {
 	c.Assert(maxy, 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) {
 func (l *LibSuite) TestGetRangeFromString(c *C) {
 	var rangeString string
 	var rangeString string
 	var lower, upper int
 	var lower, upper int