Browse Source

Merge pull request #198 from tealeg/skm_191_FormattedValue_return_error

Fix for 191 formatted value return error.
Geoffrey J. Teale 9 years ago
parent
commit
10bcf5f9fa
7 changed files with 295 additions and 141 deletions
  1. 3 14
      cell.go
  2. 103 77
      cell_test.go
  3. 30 13
      compatibility_test.go
  4. 5 1
      file.go
  5. 50 11
      file_test.go
  6. 70 14
      lib_test.go
  7. 34 11
      write_test.go

+ 3 - 14
cell.go

@@ -68,7 +68,7 @@ func (c *Cell) SetString(s string) {
 }
 }
 
 
 // String returns the value of a Cell as a string.
 // String returns the value of a Cell as a string.
-func (c *Cell) String() string {
+func (c *Cell) String() (string, error) {
 	return c.FormattedValue()
 	return c.FormattedValue()
 }
 }
 
 
@@ -291,11 +291,11 @@ func (c *Cell) formatToInt(format string) (string, error) {
 	return fmt.Sprintf(format, int(f)), nil
 	return fmt.Sprintf(format, int(f)), nil
 }
 }
 
 
-// SafeFormattedValue returns a value, and possibly an error condition
+// FormattedValue returns a value, and possibly an error condition
 // from a Cell.  If it is possible to apply a format to the cell
 // from a Cell.  If it is possible to apply a format to the cell
 // value, it will do so, if not then an error will be returned, along
 // value, it will do so, if not then an error will be returned, along
 // with the raw value of the Cell.
 // with the raw value of the Cell.
-func (c *Cell) SafeFormattedValue() (string, error) {
+func (c *Cell) FormattedValue() (string, error) {
 	var numberFormat = c.GetNumberFormat()
 	var numberFormat = c.GetNumberFormat()
 	if isTimeFormat(numberFormat) {
 	if isTimeFormat(numberFormat) {
 		return parseTime(c)
 		return parseTime(c)
@@ -348,17 +348,6 @@ func (c *Cell) SafeFormattedValue() (string, error) {
 
 
 }
 }
 
 
-// FormattedValue returns the formatted version of the value.
-// If it's a string type, c.Value will just be returned. Otherwise,
-// it will attempt to apply Excel formatting to the value.
-func (c *Cell) FormattedValue() string {
-	value, err := c.SafeFormattedValue()
-	if err != nil {
-		return err.Error()
-	}
-	return value
-}
-
 // parseTime returns a string parsed using time.Time
 // parseTime returns a string parsed using time.Time
 func parseTime(c *Cell) (string, error) {
 func parseTime(c *Cell) (string, error) {
 	f, err := strconv.ParseFloat(c.Value, 64)
 	f, err := strconv.ParseFloat(c.Value, 64)

+ 103 - 77
cell_test.go

@@ -114,11 +114,11 @@ func (l *CellSuite) TestSetFloat(c *C) {
 	c.Assert(cell.Value, Equals, "37947.75334343")
 	c.Assert(cell.Value, Equals, "37947.75334343")
 }
 }
 
 
-// SafeFormattedValue returns an error for formatting errors
-func (l *CellSuite) TestSafeFormattedValueErrorsOnBadFormat(c *C) {
+// FormattedValue returns an error for formatting errors
+func (l *CellSuite) TestFormattedValueErrorsOnBadFormat(c *C) {
 	cell := Cell{Value: "Fudge Cake"}
 	cell := Cell{Value: "Fudge Cake"}
 	cell.NumFmt = "#,##0 ;(#,##0)"
 	cell.NumFmt = "#,##0 ;(#,##0)"
-	value, err := cell.SafeFormattedValue()
+	value, err := cell.FormattedValue()
 	c.Assert(value, Equals, "Fudge Cake")
 	c.Assert(value, Equals, "Fudge Cake")
 	c.Assert(err, NotNil)
 	c.Assert(err, NotNil)
 	c.Assert(err.Error(), Equals, "strconv.ParseFloat: parsing \"Fudge Cake\": invalid syntax")
 	c.Assert(err.Error(), Equals, "strconv.ParseFloat: parsing \"Fudge Cake\": invalid syntax")
@@ -128,8 +128,24 @@ func (l *CellSuite) TestSafeFormattedValueErrorsOnBadFormat(c *C) {
 func (l *CellSuite) TestFormattedValueReturnsErrorAsValueForBadFormat(c *C) {
 func (l *CellSuite) TestFormattedValueReturnsErrorAsValueForBadFormat(c *C) {
 	cell := Cell{Value: "Fudge Cake"}
 	cell := Cell{Value: "Fudge Cake"}
 	cell.NumFmt = "#,##0 ;(#,##0)"
 	cell.NumFmt = "#,##0 ;(#,##0)"
-	value := cell.FormattedValue()
-	c.Assert(value, Equals, "strconv.ParseFloat: parsing \"Fudge Cake\": invalid syntax")
+	_, err := cell.FormattedValue()
+	c.Assert(err.Error(), Equals, "strconv.ParseFloat: parsing \"Fudge Cake\": invalid syntax")
+}
+
+// formattedValueChecker removes all the boilerplate for testing Cell.FormattedValue
+// after its change from returning one value (a string) to two values (string, error)
+// This allows all the old one-line asserts in the test to continue to be one
+// line, instead of multi-line with error checking.
+type formattedValueChecker struct {
+	c *C
+}
+
+func (fvc *formattedValueChecker) Equals(cell Cell, expected string) {
+	val, err := cell.FormattedValue()
+	if err != nil {
+		fvc.c.Error(err)
+	}
+	fvc.c.Assert(val, Equals, expected)
 }
 }
 
 
 // We can return a string representation of the formatted data
 // We can return a string representation of the formatted data
@@ -142,193 +158,195 @@ func (l *CellSuite) TestFormattedValue(c *C) {
 	smallCell := Cell{Value: "0.007"}
 	smallCell := Cell{Value: "0.007"}
 	earlyCell := Cell{Value: "2.1"}
 	earlyCell := Cell{Value: "2.1"}
 
 
+	fvc := formattedValueChecker{c: c}
+
 	cell.NumFmt = "general"
 	cell.NumFmt = "general"
-	c.Assert(cell.FormattedValue(), Equals, "37947.7500001")
+	fvc.Equals(cell, "37947.7500001")
 	negativeCell.NumFmt = "general"
 	negativeCell.NumFmt = "general"
-	c.Assert(negativeCell.FormattedValue(), Equals, "-37947.7500001")
+	fvc.Equals(negativeCell, "-37947.7500001")
 
 
 	// TODO: This test is currently broken.  For a string type cell, I
 	// TODO: This test is currently broken.  For a string type cell, I
 	// don't think FormattedValue() should be doing a numeric conversion on the value
 	// don't think FormattedValue() should be doing a numeric conversion on the value
 	// before returning the string.
 	// before returning the string.
 	cell.NumFmt = "0"
 	cell.NumFmt = "0"
-	c.Assert(cell.FormattedValue(), Equals, "37947")
+	fvc.Equals(cell, "37947")
 
 
 	cell.NumFmt = "#,##0" // For the time being we're not doing
 	cell.NumFmt = "#,##0" // For the time being we're not doing
 	// this comma formatting, so it'll fall back to the related
 	// this comma formatting, so it'll fall back to the related
 	// non-comma form.
 	// non-comma form.
-	c.Assert(cell.FormattedValue(), Equals, "37947")
+	fvc.Equals(cell, "37947")
 
 
 	cell.NumFmt = "#,##0.00;(#,##0.00)"
 	cell.NumFmt = "#,##0.00;(#,##0.00)"
-	c.Assert(cell.FormattedValue(), Equals, "37947.75")
+	fvc.Equals(cell, "37947.75")
 
 
 	cell.NumFmt = "0.00"
 	cell.NumFmt = "0.00"
-	c.Assert(cell.FormattedValue(), Equals, "37947.75")
+	fvc.Equals(cell, "37947.75")
 
 
 	cell.NumFmt = "#,##0.00" // For the time being we're not doing
 	cell.NumFmt = "#,##0.00" // For the time being we're not doing
 	// this comma formatting, so it'll fall back to the related
 	// this comma formatting, so it'll fall back to the related
 	// non-comma form.
 	// non-comma form.
-	c.Assert(cell.FormattedValue(), Equals, "37947.75")
+	fvc.Equals(cell, "37947.75")
 
 
 	cell.NumFmt = "#,##0 ;(#,##0)"
 	cell.NumFmt = "#,##0 ;(#,##0)"
-	c.Assert(cell.FormattedValue(), Equals, "37947")
+	fvc.Equals(cell, "37947")
 	negativeCell.NumFmt = "#,##0 ;(#,##0)"
 	negativeCell.NumFmt = "#,##0 ;(#,##0)"
-	c.Assert(negativeCell.FormattedValue(), Equals, "(37947)")
+	fvc.Equals(negativeCell, "(37947)")
 
 
 	cell.NumFmt = "#,##0 ;[red](#,##0)"
 	cell.NumFmt = "#,##0 ;[red](#,##0)"
-	c.Assert(cell.FormattedValue(), Equals, "37947")
+	fvc.Equals(cell, "37947")
 	negativeCell.NumFmt = "#,##0 ;[red](#,##0)"
 	negativeCell.NumFmt = "#,##0 ;[red](#,##0)"
-	c.Assert(negativeCell.FormattedValue(), Equals, "(37947)")
+	fvc.Equals(negativeCell, "(37947)")
 
 
 	negativeCell.NumFmt = "#,##0.00;(#,##0.00)"
 	negativeCell.NumFmt = "#,##0.00;(#,##0.00)"
-	c.Assert(negativeCell.FormattedValue(), Equals, "(-37947.75)")
+	fvc.Equals(negativeCell, "(-37947.75)")
 
 
 	cell.NumFmt = "0%"
 	cell.NumFmt = "0%"
-	c.Assert(cell.FormattedValue(), Equals, "3794775%")
+	fvc.Equals(cell, "3794775%")
 
 
 	cell.NumFmt = "0.00%"
 	cell.NumFmt = "0.00%"
-	c.Assert(cell.FormattedValue(), Equals, "3794775.00%")
+	fvc.Equals(cell, "3794775.00%")
 
 
 	cell.NumFmt = "0.00e+00"
 	cell.NumFmt = "0.00e+00"
-	c.Assert(cell.FormattedValue(), Equals, "3.794775e+04")
+	fvc.Equals(cell, "3.794775e+04")
 
 
 	cell.NumFmt = "##0.0e+0" // This is wrong, but we'll use it for now.
 	cell.NumFmt = "##0.0e+0" // This is wrong, but we'll use it for now.
-	c.Assert(cell.FormattedValue(), Equals, "3.794775e+04")
+	fvc.Equals(cell, "3.794775e+04")
 
 
 	cell.NumFmt = "mm-dd-yy"
 	cell.NumFmt = "mm-dd-yy"
-	c.Assert(cell.FormattedValue(), Equals, "11-22-03")
+	fvc.Equals(cell, "11-22-03")
 
 
 	cell.NumFmt = "d-mmm-yy"
 	cell.NumFmt = "d-mmm-yy"
-	c.Assert(cell.FormattedValue(), Equals, "22-Nov-03")
+	fvc.Equals(cell, "22-Nov-03")
 	earlyCell.NumFmt = "d-mmm-yy"
 	earlyCell.NumFmt = "d-mmm-yy"
-	c.Assert(earlyCell.FormattedValue(), Equals, "1-Jan-00")
+	fvc.Equals(earlyCell, "1-Jan-00")
 
 
 	cell.NumFmt = "d-mmm"
 	cell.NumFmt = "d-mmm"
-	c.Assert(cell.FormattedValue(), Equals, "22-Nov")
+	fvc.Equals(cell, "22-Nov")
 	earlyCell.NumFmt = "d-mmm"
 	earlyCell.NumFmt = "d-mmm"
-	c.Assert(earlyCell.FormattedValue(), Equals, "1-Jan")
+	fvc.Equals(earlyCell, "1-Jan")
 
 
 	cell.NumFmt = "mmm-yy"
 	cell.NumFmt = "mmm-yy"
-	c.Assert(cell.FormattedValue(), Equals, "Nov-03")
+	fvc.Equals(cell, "Nov-03")
 
 
 	cell.NumFmt = "h:mm am/pm"
 	cell.NumFmt = "h:mm am/pm"
-	c.Assert(cell.FormattedValue(), Equals, "6:00 pm")
+	fvc.Equals(cell, "6:00 pm")
 	smallCell.NumFmt = "h:mm am/pm"
 	smallCell.NumFmt = "h:mm am/pm"
-	c.Assert(smallCell.FormattedValue(), Equals, "12:14 am")
+	fvc.Equals(smallCell, "12:14 am")
 
 
 	cell.NumFmt = "h:mm:ss am/pm"
 	cell.NumFmt = "h:mm:ss am/pm"
-	c.Assert(cell.FormattedValue(), Equals, "6:00:00 pm")
+	fvc.Equals(cell, "6:00:00 pm")
 	cell.NumFmt = "hh:mm:ss"
 	cell.NumFmt = "hh:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "18:00:00")
+	fvc.Equals(cell, "18:00:00")
 	smallCell.NumFmt = "h:mm:ss am/pm"
 	smallCell.NumFmt = "h:mm:ss am/pm"
-	c.Assert(smallCell.FormattedValue(), Equals, "12:14:47 am")
+	fvc.Equals(smallCell, "12:14:47 am")
 
 
 	cell.NumFmt = "h:mm"
 	cell.NumFmt = "h:mm"
-	c.Assert(cell.FormattedValue(), Equals, "6:00")
+	fvc.Equals(cell, "6:00")
 	smallCell.NumFmt = "h:mm"
 	smallCell.NumFmt = "h:mm"
-	c.Assert(smallCell.FormattedValue(), Equals, "12:14")
+	fvc.Equals(smallCell, "12:14")
 	smallCell.NumFmt = "hh:mm"
 	smallCell.NumFmt = "hh:mm"
-	c.Assert(smallCell.FormattedValue(), Equals, "00:14")
+	fvc.Equals(smallCell, "00:14")
 
 
 	cell.NumFmt = "h:mm:ss"
 	cell.NumFmt = "h:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "6:00:00")
+	fvc.Equals(cell, "6:00:00")
 	cell.NumFmt = "hh:mm:ss"
 	cell.NumFmt = "hh:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "18:00:00")
+	fvc.Equals(cell, "18:00:00")
 
 
 	smallCell.NumFmt = "hh:mm:ss"
 	smallCell.NumFmt = "hh:mm:ss"
-	c.Assert(smallCell.FormattedValue(), Equals, "00:14:47")
+	fvc.Equals(smallCell, "00:14:47")
 	smallCell.NumFmt = "h:mm:ss"
 	smallCell.NumFmt = "h:mm:ss"
-	c.Assert(smallCell.FormattedValue(), Equals, "12:14:47")
+	fvc.Equals(smallCell, "12:14:47")
 
 
 	cell.NumFmt = "m/d/yy h:mm"
 	cell.NumFmt = "m/d/yy h:mm"
-	c.Assert(cell.FormattedValue(), Equals, "11/22/03 6:00")
+	fvc.Equals(cell, "11/22/03 6:00")
 	cell.NumFmt = "m/d/yy hh:mm"
 	cell.NumFmt = "m/d/yy hh:mm"
-	c.Assert(cell.FormattedValue(), Equals, "11/22/03 18:00")
+	fvc.Equals(cell, "11/22/03 18:00")
 	smallCell.NumFmt = "m/d/yy h:mm"
 	smallCell.NumFmt = "m/d/yy h:mm"
-	c.Assert(smallCell.FormattedValue(), Equals, "12/30/99 12:14") // Note, that's 1899
+	fvc.Equals(smallCell, "12/30/99 12:14")
 	smallCell.NumFmt = "m/d/yy hh:mm"
 	smallCell.NumFmt = "m/d/yy hh:mm"
-	c.Assert(smallCell.FormattedValue(), Equals, "12/30/99 00:14") // Note, that's 1899
+	fvc.Equals(smallCell, "12/30/99 00:14")
 	earlyCell.NumFmt = "m/d/yy hh:mm"
 	earlyCell.NumFmt = "m/d/yy hh:mm"
-	c.Assert(earlyCell.FormattedValue(), Equals, "1/1/00 02:24") // and 1900
+	fvc.Equals(earlyCell, "1/1/00 02:24")
 	earlyCell.NumFmt = "m/d/yy h:mm"
 	earlyCell.NumFmt = "m/d/yy h:mm"
-	c.Assert(earlyCell.FormattedValue(), Equals, "1/1/00 2:24") // and 1900
+	fvc.Equals(earlyCell, "1/1/00 2:24")
 
 
 	cell.NumFmt = "mm:ss"
 	cell.NumFmt = "mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "00:00")
+	fvc.Equals(cell, "00:00")
 	smallCell.NumFmt = "mm:ss"
 	smallCell.NumFmt = "mm:ss"
-	c.Assert(smallCell.FormattedValue(), Equals, "14:47")
+	fvc.Equals(smallCell, "14:47")
 
 
 	cell.NumFmt = "[hh]:mm:ss"
 	cell.NumFmt = "[hh]:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "18:00:00")
+	fvc.Equals(cell, "18:00:00")
 	cell.NumFmt = "[h]:mm:ss"
 	cell.NumFmt = "[h]:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "6:00:00")
+	fvc.Equals(cell, "6:00:00")
 	smallCell.NumFmt = "[h]:mm:ss"
 	smallCell.NumFmt = "[h]:mm:ss"
-	c.Assert(smallCell.FormattedValue(), Equals, "14:47")
+	fvc.Equals(smallCell, "14:47")
 
 
 	cell.NumFmt = "mmss.0" // I'm not sure about these.
 	cell.NumFmt = "mmss.0" // I'm not sure about these.
-	c.Assert(cell.FormattedValue(), Equals, "0000.0086")
+	fvc.Equals(cell, "0000.0086")
 	smallCell.NumFmt = "mmss.0"
 	smallCell.NumFmt = "mmss.0"
-	c.Assert(smallCell.FormattedValue(), Equals, "1447.9999")
+	fvc.Equals(smallCell, "1447.9999")
 
 
 	cell.NumFmt = "yyyy\\-mm\\-dd"
 	cell.NumFmt = "yyyy\\-mm\\-dd"
-	c.Assert(cell.FormattedValue(), Equals, "2003\\-11\\-22")
+	fvc.Equals(cell, "2003\\-11\\-22")
 
 
 	cell.NumFmt = "dd/mm/yyyy hh:mm:ss"
 	cell.NumFmt = "dd/mm/yyyy hh:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "22/11/2003 18:00:00")
+	fvc.Equals(cell, "22/11/2003 18:00:00")
 
 
 	cell.NumFmt = "dd/mm/yy"
 	cell.NumFmt = "dd/mm/yy"
-	c.Assert(cell.FormattedValue(), Equals, "22/11/03")
+	fvc.Equals(cell, "22/11/03")
 	earlyCell.NumFmt = "dd/mm/yy"
 	earlyCell.NumFmt = "dd/mm/yy"
-	c.Assert(earlyCell.FormattedValue(), Equals, "01/01/00")
+	fvc.Equals(earlyCell, "01/01/00")
 
 
 	cell.NumFmt = "hh:mm:ss"
 	cell.NumFmt = "hh:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "18:00:00")
+	fvc.Equals(cell, "18:00:00")
 	smallCell.NumFmt = "hh:mm:ss"
 	smallCell.NumFmt = "hh:mm:ss"
-	c.Assert(smallCell.FormattedValue(), Equals, "00:14:47")
+	fvc.Equals(smallCell, "00:14:47")
 
 
 	cell.NumFmt = "dd/mm/yy\\ hh:mm"
 	cell.NumFmt = "dd/mm/yy\\ hh:mm"
-	c.Assert(cell.FormattedValue(), Equals, "22/11/03\\ 18:00")
+	fvc.Equals(cell, "22/11/03\\ 18:00")
 
 
 	cell.NumFmt = "yyyy/mm/dd"
 	cell.NumFmt = "yyyy/mm/dd"
-	c.Assert(cell.FormattedValue(), Equals, "2003/11/22")
+	fvc.Equals(cell, "2003/11/22")
 
 
 	cell.NumFmt = "yy-mm-dd"
 	cell.NumFmt = "yy-mm-dd"
-	c.Assert(cell.FormattedValue(), Equals, "03-11-22")
+	fvc.Equals(cell, "03-11-22")
 
 
 	cell.NumFmt = "d-mmm-yyyy"
 	cell.NumFmt = "d-mmm-yyyy"
-	c.Assert(cell.FormattedValue(), Equals, "22-Nov-2003")
+	fvc.Equals(cell, "22-Nov-2003")
 	earlyCell.NumFmt = "d-mmm-yyyy"
 	earlyCell.NumFmt = "d-mmm-yyyy"
-	c.Assert(earlyCell.FormattedValue(), Equals, "1-Jan-1900")
+	fvc.Equals(earlyCell, "1-Jan-1900")
 
 
 	cell.NumFmt = "m/d/yy"
 	cell.NumFmt = "m/d/yy"
-	c.Assert(cell.FormattedValue(), Equals, "11/22/03")
+	fvc.Equals(cell, "11/22/03")
 	earlyCell.NumFmt = "m/d/yy"
 	earlyCell.NumFmt = "m/d/yy"
-	c.Assert(earlyCell.FormattedValue(), Equals, "1/1/00")
+	fvc.Equals(earlyCell, "1/1/00")
 
 
 	cell.NumFmt = "m/d/yyyy"
 	cell.NumFmt = "m/d/yyyy"
-	c.Assert(cell.FormattedValue(), Equals, "11/22/2003")
+	fvc.Equals(cell, "11/22/2003")
 	earlyCell.NumFmt = "m/d/yyyy"
 	earlyCell.NumFmt = "m/d/yyyy"
-	c.Assert(earlyCell.FormattedValue(), Equals, "1/1/1900")
+	fvc.Equals(earlyCell, "1/1/1900")
 
 
 	cell.NumFmt = "dd-mmm-yyyy"
 	cell.NumFmt = "dd-mmm-yyyy"
-	c.Assert(cell.FormattedValue(), Equals, "22-Nov-2003")
+	fvc.Equals(cell, "22-Nov-2003")
 
 
 	cell.NumFmt = "dd/mm/yyyy"
 	cell.NumFmt = "dd/mm/yyyy"
-	c.Assert(cell.FormattedValue(), Equals, "22/11/2003")
+	fvc.Equals(cell, "22/11/2003")
 
 
 	cell.NumFmt = "mm/dd/yy hh:mm am/pm"
 	cell.NumFmt = "mm/dd/yy hh:mm am/pm"
-	c.Assert(cell.FormattedValue(), Equals, "11/22/03 18:00 pm")
+	fvc.Equals(cell, "11/22/03 18:00 pm")
 	cell.NumFmt = "mm/dd/yy h:mm am/pm"
 	cell.NumFmt = "mm/dd/yy h:mm am/pm"
-	c.Assert(cell.FormattedValue(), Equals, "11/22/03 6:00 pm")
+	fvc.Equals(cell, "11/22/03 6:00 pm")
 
 
 	cell.NumFmt = "mm/dd/yyyy hh:mm:ss"
 	cell.NumFmt = "mm/dd/yyyy hh:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "11/22/2003 18:00:00")
+	fvc.Equals(cell, "11/22/2003 18:00:00")
 	smallCell.NumFmt = "mm/dd/yyyy hh:mm:ss"
 	smallCell.NumFmt = "mm/dd/yyyy hh:mm:ss"
-	c.Assert(smallCell.FormattedValue(), Equals, "12/30/1899 00:14:47")
+	fvc.Equals(smallCell, "12/30/1899 00:14:47")
 
 
 	cell.NumFmt = "yyyy-mm-dd hh:mm:ss"
 	cell.NumFmt = "yyyy-mm-dd hh:mm:ss"
-	c.Assert(cell.FormattedValue(), Equals, "2003-11-22 18:00:00")
+	fvc.Equals(cell, "2003-11-22 18:00:00")
 	smallCell.NumFmt = "yyyy-mm-dd hh:mm:ss"
 	smallCell.NumFmt = "yyyy-mm-dd hh:mm:ss"
-	c.Assert(smallCell.FormattedValue(), Equals, "1899-12-30 00:14:47")
+	fvc.Equals(smallCell, "1899-12-30 00:14:47")
 }
 }
 
 
 // test setters and getters
 // test setters and getters
@@ -336,7 +354,11 @@ func (s *CellSuite) TestSetterGetters(c *C) {
 	cell := Cell{}
 	cell := Cell{}
 
 
 	cell.SetString("hello world")
 	cell.SetString("hello world")
-	c.Assert(cell.String(), Equals, "hello world")
+	if val, err := cell.String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "hello world")
+	}
 	c.Assert(cell.Type(), Equals, CellTypeString)
 	c.Assert(cell.Type(), Equals, CellTypeString)
 
 
 	cell.SetInt(1024)
 	cell.SetInt(1024)
@@ -370,7 +392,11 @@ func (s *CellSuite) TestOddInput(c *C) {
 	odd := `[1],[12,"DATE NOT NULL DEFAULT '0000-00-00'"]`
 	odd := `[1],[12,"DATE NOT NULL DEFAULT '0000-00-00'"]`
 	cell.Value = odd
 	cell.Value = odd
 	cell.NumFmt = "@"
 	cell.NumFmt = "@"
-	c.Assert(cell.String(), Equals, odd)
+	if val, err := cell.String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, odd)
+	}
 }
 }
 
 
 // TestBool tests basic Bool getting and setting booleans.
 // TestBool tests basic Bool getting and setting booleans.

+ 30 - 13
compatibility_test.go

@@ -26,8 +26,11 @@ func (m *MacExcelSuite) TestMacExcel(c *C) {
 	xlsxFile, err := OpenFile("./testdocs/macExcelTest.xlsx")
 	xlsxFile, err := OpenFile("./testdocs/macExcelTest.xlsx")
 	c.Assert(err, IsNil)
 	c.Assert(err, IsNil)
 	c.Assert(xlsxFile, NotNil)
 	c.Assert(xlsxFile, NotNil)
-	s := xlsxFile.Sheet["普通技能"].Cell(0, 0).String()
-	c.Assert(s, Equals, "编号")
+	if val, err := xlsxFile.Sheet["普通技能"].Cell(0, 0).String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "编号")
+	}
 }
 }
 
 
 type MacNumbersSuite struct{}
 type MacNumbersSuite struct{}
@@ -42,8 +45,11 @@ func (m *MacNumbersSuite) TestMacNumbers(c *C) {
 	c.Assert(xlsxFile, NotNil)
 	c.Assert(xlsxFile, NotNil)
 	sheet, ok := xlsxFile.Sheet["主动技能"]
 	sheet, ok := xlsxFile.Sheet["主动技能"]
 	c.Assert(ok, Equals, true)
 	c.Assert(ok, Equals, true)
-	s := sheet.Cell(0, 0).String()
-	c.Assert(s, Equals, "编号")
+	if val, err := sheet.Cell(0, 0).String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "编号")
+	}
 }
 }
 
 
 type WpsBlankLineSuite struct{}
 type WpsBlankLineSuite struct{}
@@ -59,20 +65,31 @@ func (w *WpsBlankLineSuite) TestWpsBlankLine(c *C) {
 	sheet := xlsxFile.Sheet["Sheet1"]
 	sheet := xlsxFile.Sheet["Sheet1"]
 	row := sheet.Rows[0]
 	row := sheet.Rows[0]
 	cell := row.Cells[0]
 	cell := row.Cells[0]
-	s := cell.String()
+
 	expected := "编号"
 	expected := "编号"
-	c.Assert(s, Equals, expected)
+	var val string
+
+	if val, err = cell.String(); err != nil {
+		c.Error(err)
+	}
+	c.Assert(val, Equals, expected)
 
 
 	row = sheet.Rows[2]
 	row = sheet.Rows[2]
 	cell = row.Cells[0]
 	cell = row.Cells[0]
-	s = cell.String()
-	c.Assert(s, Equals, expected)
+	if val, err = cell.String(); err != nil {
+		c.Error(err)
+	}
+	c.Assert(val, Equals, expected)
 
 
 	row = sheet.Rows[4]
 	row = sheet.Rows[4]
 	cell = row.Cells[1]
 	cell = row.Cells[1]
-	s = cell.String()
-	c.Assert(s, Equals, "")
-
-	s = sheet.Rows[4].Cells[2].String()
-	c.Assert(s, Equals, expected)
+	if val, err = cell.String(); err != nil {
+		c.Error(err)
+	}
+	c.Assert(val, Equals, "")
+
+	if val, err = sheet.Rows[4].Cells[2].String(); err != nil {
+		c.Error(err)
+	}
+	c.Assert(val, Equals, expected)
 }
 }

+ 5 - 1
file.go

@@ -312,7 +312,11 @@ func (file *File) ToSlice() (output [][][]string, err error) {
 			}
 			}
 			r := []string{}
 			r := []string{}
 			for _, cell := range row.Cells {
 			for _, cell := range row.Cells {
-				r = append(r, cell.String())
+				str, err := cell.String()
+				if err != nil {
+					return output, err
+				}
+				r = append(r, str)
 			}
 			}
 			s = append(s, r)
 			s = append(s, r)
 		}
 		}

+ 50 - 11
file_test.go

@@ -159,6 +159,7 @@ func (l *FileSuite) TestGetStyleFromZipFile(c *C) {
 	var xlsxFile *File
 	var xlsxFile *File
 	var err error
 	var err error
 	var style *Style
 	var style *Style
+	var val string
 
 
 	xlsxFile, err = OpenFile("./testdocs/testfile.xlsx")
 	xlsxFile, err = OpenFile("./testdocs/testfile.xlsx")
 	c.Assert(err, IsNil)
 	c.Assert(err, IsNil)
@@ -170,7 +171,10 @@ func (l *FileSuite) TestGetStyleFromZipFile(c *C) {
 	row0 := tabelle1.Rows[0]
 	row0 := tabelle1.Rows[0]
 	cellFoo := row0.Cells[0]
 	cellFoo := row0.Cells[0]
 	style = cellFoo.GetStyle()
 	style = cellFoo.GetStyle()
-	c.Assert(cellFoo.String(), Equals, "Foo")
+	if val, err = cellFoo.String(); err != nil {
+		c.Error(err)
+	}
+	c.Assert(val, Equals, "Foo")
 	c.Assert(style.Fill.BgColor, Equals, "FF33CCCC")
 	c.Assert(style.Fill.BgColor, Equals, "FF33CCCC")
 	c.Assert(style.ApplyFill, Equals, false)
 	c.Assert(style.ApplyFill, Equals, false)
 	c.Assert(style.ApplyFont, Equals, true)
 	c.Assert(style.ApplyFont, Equals, true)
@@ -178,12 +182,18 @@ func (l *FileSuite) TestGetStyleFromZipFile(c *C) {
 	row1 := tabelle1.Rows[1]
 	row1 := tabelle1.Rows[1]
 	cellQuuk := row1.Cells[1]
 	cellQuuk := row1.Cells[1]
 	style = cellQuuk.GetStyle()
 	style = cellQuuk.GetStyle()
-	c.Assert(cellQuuk.String(), Equals, "Quuk")
+	if val, err = cellQuuk.String(); err != nil {
+		c.Error(err)
+	}
+	c.Assert(val, Equals, "Quuk")
 	c.Assert(style.Border.Left, Equals, "thin")
 	c.Assert(style.Border.Left, Equals, "thin")
 	c.Assert(style.ApplyBorder, Equals, true)
 	c.Assert(style.ApplyBorder, Equals, true)
 
 
 	cellBar := row0.Cells[1]
 	cellBar := row0.Cells[1]
-	c.Assert(cellBar.String(), Equals, "Bar")
+	if val, err = cellBar.String(); err != nil {
+		c.Error(err)
+	}
+	c.Assert(val, Equals, "Bar")
 	c.Assert(cellBar.GetStyle().Fill.BgColor, Equals, "")
 	c.Assert(cellBar.GetStyle().Fill.BgColor, Equals, "")
 }
 }
 
 
@@ -214,8 +224,11 @@ func (l *FileSuite) TestCreateSheet(c *C) {
 	row = sheet.Rows[0]
 	row = sheet.Rows[0]
 	c.Assert(len(row.Cells), Equals, 2)
 	c.Assert(len(row.Cells), Equals, 2)
 	cell := row.Cells[0]
 	cell := row.Cells[0]
-	cellstring := cell.String()
-	c.Assert(cellstring, Equals, "Foo")
+	if val, err := cell.String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "Foo")
+	}
 }
 }
 
 
 // Test that we can add a sheet to a File
 // Test that we can add a sheet to a File
@@ -762,11 +775,19 @@ func (l *FileSuite) TestReadWorkbookWithTypes(c *C) {
 
 
 	// string 1
 	// string 1
 	c.Assert(sheet.Rows[0].Cells[0].Type(), Equals, CellTypeString)
 	c.Assert(sheet.Rows[0].Cells[0].Type(), Equals, CellTypeString)
-	c.Assert(sheet.Rows[0].Cells[0].String(), Equals, "hello world")
+	if val, err := sheet.Rows[0].Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "hello world")
+	}
 
 
 	// string 2
 	// string 2
 	c.Assert(sheet.Rows[1].Cells[0].Type(), Equals, CellTypeString)
 	c.Assert(sheet.Rows[1].Cells[0].Type(), Equals, CellTypeString)
-	c.Assert(sheet.Rows[1].Cells[0].String(), Equals, "日本語")
+	if val, err := sheet.Rows[1].Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "日本語")
+	}
 
 
 	// integer
 	// integer
 	c.Assert(sheet.Rows[2].Cells[0].Type(), Equals, CellTypeNumeric)
 	c.Assert(sheet.Rows[2].Cells[0].Type(), Equals, CellTypeNumeric)
@@ -803,8 +824,17 @@ func (s *SliceReaderSuite) TestFileWithEmptyRows(c *C) {
 	c.Assert(err, IsNil)
 	c.Assert(err, IsNil)
 	sheet, ok := f.Sheet["EmptyRows"]
 	sheet, ok := f.Sheet["EmptyRows"]
 	c.Assert(ok, Equals, true)
 	c.Assert(ok, Equals, true)
-	c.Assert(sheet.Cell(0, 0).String(), Equals, "")
-	c.Assert(sheet.Cell(2, 0).String(), Equals, "A3")
+
+	if val, err := sheet.Cell(0, 0).String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "")
+	}
+	if val, err := sheet.Cell(2, 0).String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "A3")
+	}
 }
 }
 
 
 func (s *SliceReaderSuite) TestFileWithEmptyCols(c *C) {
 func (s *SliceReaderSuite) TestFileWithEmptyCols(c *C) {
@@ -812,6 +842,15 @@ func (s *SliceReaderSuite) TestFileWithEmptyCols(c *C) {
 	c.Assert(err, IsNil)
 	c.Assert(err, IsNil)
 	sheet, ok := f.Sheet["EmptyCols"]
 	sheet, ok := f.Sheet["EmptyCols"]
 	c.Assert(ok, Equals, true)
 	c.Assert(ok, Equals, true)
-	c.Assert(sheet.Cell(0, 0).String(), Equals, "")
-	c.Assert(sheet.Cell(0, 2).String(), Equals, "C1")
+
+	if val, err := sheet.Cell(0, 0).String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "")
+	}
+	if val, err := sheet.Cell(0, 2).String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "C1")
+	}
 }
 }

+ 70 - 14
lib_test.go

@@ -39,7 +39,11 @@ func (l *LibSuite) TestReadWorkbookRelationsFromZipFileWithFunnyNames(c *C) {
 	bob := xlsxFile.Sheet["Bob"]
 	bob := xlsxFile.Sheet["Bob"]
 	row1 := bob.Rows[0]
 	row1 := bob.Rows[0]
 	cell1 := row1.Cells[0]
 	cell1 := row1.Cells[0]
-	c.Assert(cell1.String(), Equals, "I am Bob")
+	if val, err := cell1.String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "I am Bob")
+	}
 }
 }
 
 
 // We can marshal WorkBookRels to an xml file
 // We can marshal WorkBookRels to an xml file
@@ -528,9 +532,17 @@ func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyRows(c *C) {
 	c.Assert(len(rows[1].Cells), Equals, 0)
 	c.Assert(len(rows[1].Cells), Equals, 0)
 	c.Assert(len(rows[2].Cells), Equals, 0)
 	c.Assert(len(rows[2].Cells), Equals, 0)
 	c.Assert(len(rows[3].Cells), Equals, 1)
 	c.Assert(len(rows[3].Cells), Equals, 1)
-	c.Assert(rows[3].Cells[0].String(), Equals, "ABC")
+	if val, err := rows[3].Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "ABC")
+	}
 	c.Assert(len(rows[4].Cells), Equals, 1)
 	c.Assert(len(rows[4].Cells), Equals, 1)
-	c.Assert(rows[4].Cells[0].String(), Equals, "DEF")
+	if val, err := rows[4].Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "DEF")
+	}
 }
 }
 
 
 func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyCols(c *C) {
 func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyCols(c *C) {
@@ -583,15 +595,47 @@ func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyCols(c *C) {
 	c.Assert(maxCols, Equals, 4)
 	c.Assert(maxCols, Equals, 4)
 
 
 	c.Assert(len(rows[0].Cells), 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")
+	if val, err := rows[0].Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "")
+	}
+	if val, err := rows[0].Cells[1].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "")
+	}
+	if val, err := rows[0].Cells[2].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "ABC")
+	}
+	if val, err := rows[0].Cells[3].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "DEF")
+	}
 	c.Assert(len(rows[1].Cells), Equals, 4)
 	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")
+	if val, err := rows[1].Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "")
+	}
+	if val, err := rows[1].Cells[1].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "")
+	}
+	if val, err := rows[1].Cells[2].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "ABC")
+	}
+	if val, err := rows[1].Cells[3].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "DEF")
+	}
 
 
 	c.Assert(len(cols), Equals, 4)
 	c.Assert(len(cols), Equals, 4)
 	c.Assert(cols[0].Width, Equals, 0.0)
 	c.Assert(cols[0].Width, Equals, 0.0)
@@ -923,7 +967,11 @@ func (l *LibSuite) TestReadRowsFromSheetWithMultipleTypes(c *C) {
 
 
 	cell1 := row.Cells[0]
 	cell1 := row.Cells[0]
 	c.Assert(cell1.Type(), Equals, CellTypeString)
 	c.Assert(cell1.Type(), Equals, CellTypeString)
-	c.Assert(cell1.String(), Equals, "Hello World")
+	if val, err := cell1.String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "Hello World")
+	}
 
 
 	cell2 := row.Cells[1]
 	cell2 := row.Cells[1]
 	c.Assert(cell2.Type(), Equals, CellTypeNumeric)
 	c.Assert(cell2.Type(), Equals, CellTypeNumeric)
@@ -992,12 +1040,20 @@ func (l *LibSuite) TestReadRowsFromSheetWithHiddenColumn(c *C) {
 
 
 	cell1 := row.Cells[0]
 	cell1 := row.Cells[0]
 	c.Assert(cell1.Type(), Equals, CellTypeString)
 	c.Assert(cell1.Type(), Equals, CellTypeString)
-	c.Assert(cell1.String(), Equals, "This is a test.")
+	if val, err := cell1.String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "This is a test.")
+	}
 	c.Assert(cell1.Hidden, Equals, false)
 	c.Assert(cell1.Hidden, Equals, false)
 
 
 	cell2 := row.Cells[1]
 	cell2 := row.Cells[1]
 	c.Assert(cell2.Type(), Equals, CellTypeString)
 	c.Assert(cell2.Type(), Equals, CellTypeString)
-	c.Assert(cell2.String(), Equals, "This should be invisible.")
+	if val, err := cell2.String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "This should be invisible.")
+	}
 	c.Assert(cell2.Hidden, Equals, true)
 	c.Assert(cell2.Hidden, Equals, true)
 }
 }
 
 

+ 34 - 11
write_test.go

@@ -41,12 +41,20 @@ func (r *RowSuite) TestWriteStruct(c *C) {
 	row.WriteStruct(&testStruct, -1)
 	row.WriteStruct(&testStruct, -1)
 	c.Assert(row, NotNil)
 	c.Assert(row, NotNil)
 
 
-	c0 := row.Cells[0].String()
+	var c0, c4, c5 string
+	var err error
+	if c0, err = row.Cells[0].String(); err != nil {
+		c.Error(err)
+	}
 	c1, e1 := row.Cells[1].Int()
 	c1, e1 := row.Cells[1].Int()
 	c2, e2 := row.Cells[2].Float()
 	c2, e2 := row.Cells[2].Float()
 	c3 := row.Cells[3].Bool()
 	c3 := row.Cells[3].Bool()
-	c4 := row.Cells[4].String()
-	c5 := row.Cells[5].String()
+	if c4, err = row.Cells[4].String(); err != nil {
+		c.Error(err)
+	}
+	if c5, err = row.Cells[5].String(); err != nil {
+		c.Error(err)
+	}
 
 
 	c.Assert(c0, Equals, "Eric")
 	c.Assert(c0, Equals, "Eric")
 	c.Assert(c1, Equals, 20)
 	c.Assert(c1, Equals, 20)
@@ -77,8 +85,12 @@ func (r *RowSuite) TestWriteSlice(c *C) {
 	row0 := sheet.AddRow()
 	row0 := sheet.AddRow()
 	row0.WriteSlice(&s0, -1)
 	row0.WriteSlice(&s0, -1)
 	c.Assert(row0, NotNil)
 	c.Assert(row0, NotNil)
-	c0 := row0.Cells[0].String()
-	c.Assert(c0, Equals, "Eric")
+
+	if val, err := row0.Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "Eric")
+	}
 
 
 	s1 := intA{10}
 	s1 := intA{10}
 	row1 := sheet.AddRow()
 	row1 := sheet.AddRow()
@@ -107,8 +119,11 @@ func (r *RowSuite) TestWriteSlice(c *C) {
 	row4 := sheet.AddRow()
 	row4 := sheet.AddRow()
 	row4.WriteSlice(&s4, -1)
 	row4.WriteSlice(&s4, -1)
 	c.Assert(row4, NotNil)
 	c.Assert(row4, NotNil)
-	c40 := row4.Cells[0].String()
-	c.Assert(c40, Equals, "Eric")
+	if val, err := row4.Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "Eric")
+	}
 	c41, e41 := row4.Cells[1].Int()
 	c41, e41 := row4.Cells[1].Int()
 	c.Assert(e41, Equals, nil)
 	c.Assert(e41, Equals, nil)
 	c.Assert(c41, Equals, 10)
 	c.Assert(c41, Equals, 10)
@@ -122,13 +137,21 @@ func (r *RowSuite) TestWriteSlice(c *C) {
 	row5 := sheet.AddRow()
 	row5 := sheet.AddRow()
 	row5.WriteSlice(&s5, -1)
 	row5.WriteSlice(&s5, -1)
 	c.Assert(row5, NotNil)
 	c.Assert(row5, NotNil)
-	c5 := row5.Cells[0].String()
-	c.Assert(c5, Equals, "Stringer")
+
+	if val, err := row5.Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "Stringer")
+	}
 
 
 	s6 := stringerPtrA{&testStringerImpl{"Pointer to Stringer"}}
 	s6 := stringerPtrA{&testStringerImpl{"Pointer to Stringer"}}
 	row6 := sheet.AddRow()
 	row6 := sheet.AddRow()
 	row6.WriteSlice(&s6, -1)
 	row6.WriteSlice(&s6, -1)
 	c.Assert(row6, NotNil)
 	c.Assert(row6, NotNil)
-	c6 := row6.Cells[0].String()
-	c.Assert(c6, Equals, "Pointer to Stringer")
+
+	if val, err := row6.Cells[0].String(); err != nil {
+		c.Error(err)
+	} else {
+		c.Assert(val, Equals, "Pointer to Stringer")
+	}
 }
 }