|
@@ -5,6 +5,7 @@ import (
|
|
|
"math"
|
|
"math"
|
|
|
"strconv"
|
|
"strconv"
|
|
|
"strings"
|
|
"strings"
|
|
|
|
|
+ "time"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// CellType is an int type for storing metadata about the data type in the cell.
|
|
// CellType is an int type for storing metadata about the data type in the cell.
|
|
@@ -18,6 +19,8 @@ const (
|
|
|
CellTypeBool
|
|
CellTypeBool
|
|
|
CellTypeInline
|
|
CellTypeInline
|
|
|
CellTypeError
|
|
CellTypeError
|
|
|
|
|
+ CellTypeDate
|
|
|
|
|
+ CellTypeGeneral
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// Cell is a high level structure intended to provide user access to
|
|
// Cell is a high level structure intended to provide user access to
|
|
@@ -43,7 +46,7 @@ type CellInterface interface {
|
|
|
|
|
|
|
|
// NewCell creates a cell and adds it to a row.
|
|
// NewCell creates a cell and adds it to a row.
|
|
|
func NewCell(r *Row) *Cell {
|
|
func NewCell(r *Row) *Cell {
|
|
|
- return &Cell{style: NewStyle(), Row: r}
|
|
|
|
|
|
|
+ return &Cell{Row: r}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Merge with other cells, horizontally and/or vertically.
|
|
// Merge with other cells, horizontally and/or vertically.
|
|
@@ -71,7 +74,7 @@ func (c *Cell) String() string {
|
|
|
|
|
|
|
|
// SetFloat sets the value of a cell to a float.
|
|
// SetFloat sets the value of a cell to a float.
|
|
|
func (c *Cell) SetFloat(n float64) {
|
|
func (c *Cell) SetFloat(n float64) {
|
|
|
- c.SetFloatWithFormat(n, "general")
|
|
|
|
|
|
|
+ c.SetFloatWithFormat(n, builtInNumFmt[builtInNumFmtIndex_FLOAT])
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -100,6 +103,36 @@ func (c *Cell) SetFloatWithFormat(n float64, format string) {
|
|
|
c.cellType = CellTypeNumeric
|
|
c.cellType = CellTypeNumeric
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+var timeLocationUTC *time.Location
|
|
|
|
|
+
|
|
|
|
|
+func init() {
|
|
|
|
|
+ timeLocationUTC, _ = time.LoadLocation("UTC")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func timeToUTCTime(t time.Time) time.Time {
|
|
|
|
|
+ return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), timeLocationUTC)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func timeToExcelTime(t time.Time) float64 {
|
|
|
|
|
+ return float64(t.Unix())/86400.0 + 25569.0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// SetDate sets the value of a cell to a float.
|
|
|
|
|
+func (c *Cell) SetDate(t time.Time) {
|
|
|
|
|
+ c.SetDateTimeWithFormat(float64(int64(timeToExcelTime(timeToUTCTime(t)))), builtInNumFmt[14])
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (c *Cell) SetDateTime(t time.Time) {
|
|
|
|
|
+ c.SetDateTimeWithFormat(timeToExcelTime(timeToUTCTime(t)), builtInNumFmt[14])
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (c *Cell) SetDateTimeWithFormat(n float64, format string) {
|
|
|
|
|
+ c.Value = strconv.FormatFloat(n, 'f', -1, 64)
|
|
|
|
|
+ c.numFmt = format
|
|
|
|
|
+ c.formula = ""
|
|
|
|
|
+ c.cellType = CellTypeDate
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// Float returns the value of cell as a number.
|
|
// Float returns the value of cell as a number.
|
|
|
func (c *Cell) Float() (float64, error) {
|
|
func (c *Cell) Float() (float64, error) {
|
|
|
f, err := strconv.ParseFloat(c.Value, 64)
|
|
f, err := strconv.ParseFloat(c.Value, 64)
|
|
@@ -112,7 +145,7 @@ func (c *Cell) Float() (float64, error) {
|
|
|
// SetInt64 sets a cell's value to a 64-bit integer.
|
|
// SetInt64 sets a cell's value to a 64-bit integer.
|
|
|
func (c *Cell) SetInt64(n int64) {
|
|
func (c *Cell) SetInt64(n int64) {
|
|
|
c.Value = fmt.Sprintf("%d", n)
|
|
c.Value = fmt.Sprintf("%d", n)
|
|
|
- c.numFmt = "0"
|
|
|
|
|
|
|
+ c.numFmt = builtInNumFmt[builtInNumFmtIndex_INT]
|
|
|
c.formula = ""
|
|
c.formula = ""
|
|
|
c.cellType = CellTypeNumeric
|
|
c.cellType = CellTypeNumeric
|
|
|
}
|
|
}
|
|
@@ -129,11 +162,53 @@ func (c *Cell) Int64() (int64, error) {
|
|
|
// SetInt sets a cell's value to an integer.
|
|
// SetInt sets a cell's value to an integer.
|
|
|
func (c *Cell) SetInt(n int) {
|
|
func (c *Cell) SetInt(n int) {
|
|
|
c.Value = fmt.Sprintf("%d", n)
|
|
c.Value = fmt.Sprintf("%d", n)
|
|
|
- c.numFmt = "0"
|
|
|
|
|
|
|
+ c.numFmt = builtInNumFmt[builtInNumFmtIndex_INT]
|
|
|
c.formula = ""
|
|
c.formula = ""
|
|
|
c.cellType = CellTypeNumeric
|
|
c.cellType = CellTypeNumeric
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// SetInt sets a cell's value to an integer.
|
|
|
|
|
+func (c *Cell) SetValue(n interface{}) {
|
|
|
|
|
+ var s string
|
|
|
|
|
+ switch n.(type) {
|
|
|
|
|
+ case time.Time:
|
|
|
|
|
+ c.SetDateTime(n.(time.Time))
|
|
|
|
|
+ return
|
|
|
|
|
+ case int:
|
|
|
|
|
+ c.setGeneral(fmt.Sprintf("%v", n))
|
|
|
|
|
+ return
|
|
|
|
|
+ case int32:
|
|
|
|
|
+ c.setGeneral(fmt.Sprintf("%v", n))
|
|
|
|
|
+ return
|
|
|
|
|
+ case int64:
|
|
|
|
|
+ c.setGeneral(fmt.Sprintf("%v", n))
|
|
|
|
|
+ return
|
|
|
|
|
+ case float32:
|
|
|
|
|
+ c.setGeneral(fmt.Sprintf("%v", n))
|
|
|
|
|
+ return
|
|
|
|
|
+ case float64:
|
|
|
|
|
+ c.setGeneral(fmt.Sprintf("%v", n))
|
|
|
|
|
+ return
|
|
|
|
|
+ case string:
|
|
|
|
|
+ s = n.(string)
|
|
|
|
|
+ case []byte:
|
|
|
|
|
+ s = string(n.([]byte))
|
|
|
|
|
+ case nil:
|
|
|
|
|
+ s = ""
|
|
|
|
|
+ default:
|
|
|
|
|
+ s = fmt.Sprintf("%v", n)
|
|
|
|
|
+ }
|
|
|
|
|
+ c.SetString(s)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// SetInt sets a cell's value to an integer.
|
|
|
|
|
+func (c *Cell) setGeneral(s string) {
|
|
|
|
|
+ c.Value = s
|
|
|
|
|
+ c.numFmt = builtInNumFmt[builtInNumFmtIndex_GENERAL]
|
|
|
|
|
+ c.formula = ""
|
|
|
|
|
+ c.cellType = CellTypeGeneral
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// Int returns the value of cell as integer.
|
|
// Int returns the value of cell as integer.
|
|
|
// Has max 53 bits of precision
|
|
// Has max 53 bits of precision
|
|
|
// See: float64(int64(math.MaxInt))
|
|
// See: float64(int64(math.MaxInt))
|
|
@@ -184,6 +259,9 @@ func (c *Cell) Formula() string {
|
|
|
|
|
|
|
|
// GetStyle returns the Style associated with a Cell
|
|
// GetStyle returns the Style associated with a Cell
|
|
|
func (c *Cell) GetStyle() *Style {
|
|
func (c *Cell) GetStyle() *Style {
|
|
|
|
|
+ if c.style == nil {
|
|
|
|
|
+ c.style = NewStyle()
|
|
|
|
|
+ }
|
|
|
return c.style
|
|
return c.style
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -222,11 +300,11 @@ func (c *Cell) FormattedValue() string {
|
|
|
return parseTime(c)
|
|
return parseTime(c)
|
|
|
}
|
|
}
|
|
|
switch numberFormat {
|
|
switch numberFormat {
|
|
|
- case "general", "@":
|
|
|
|
|
|
|
+ case builtInNumFmt[builtInNumFmtIndex_GENERAL], builtInNumFmt[builtInNumFmtIndex_STRING]:
|
|
|
return c.Value
|
|
return c.Value
|
|
|
- case "0", "#,##0":
|
|
|
|
|
|
|
+ case builtInNumFmt[builtInNumFmtIndex_INT], "#,##0":
|
|
|
return c.formatToInt("%d")
|
|
return c.formatToInt("%d")
|
|
|
- case "0.00", "#,##0.00":
|
|
|
|
|
|
|
+ case builtInNumFmt[builtInNumFmtIndex_FLOAT], "#,##0.00":
|
|
|
return c.formatToFloat("%.2f")
|
|
return c.formatToFloat("%.2f")
|
|
|
case "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)":
|
|
case "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)":
|
|
|
f, err := strconv.ParseFloat(c.Value, 64)
|
|
f, err := strconv.ParseFloat(c.Value, 64)
|
|
@@ -278,9 +356,9 @@ func parseTime(c *Cell) string {
|
|
|
format := c.GetNumberFormat()
|
|
format := c.GetNumberFormat()
|
|
|
// Replace Excel placeholders with Go time placeholders.
|
|
// Replace Excel placeholders with Go time placeholders.
|
|
|
// For example, replace yyyy with 2006. These are in a specific order,
|
|
// For example, replace yyyy with 2006. These are in a specific order,
|
|
|
- // due to the fact that m is used in month, minute, and am/pm. It would
|
|
|
|
|
- // be easier to fix that with regular expressions, but if it's possible
|
|
|
|
|
- // to keep this simple it would be easier to maintain.
|
|
|
|
|
|
|
+ // due to the fact that m is used in month, minute, and am/pm. It would
|
|
|
|
|
+ // be easier to fix that with regular expressions, but if it's possible
|
|
|
|
|
+ // to keep this simple it would be easier to maintain.
|
|
|
replacements := []struct{ xltime, gotime string }{
|
|
replacements := []struct{ xltime, gotime string }{
|
|
|
{"yyyy", "2006"},
|
|
{"yyyy", "2006"},
|
|
|
{"yy", "06"},
|
|
{"yy", "06"},
|