cell.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. package xlsx
  2. import (
  3. "fmt"
  4. "math"
  5. "strconv"
  6. )
  7. type CellType int
  8. const (
  9. CellTypeString CellType = iota
  10. CellTypeFormula
  11. CellTypeNumeric
  12. CellTypeBool
  13. CellTypeInline
  14. CellTypeError
  15. )
  16. // Cell is a high level structure intended to provide user access to
  17. // the contents of Cell within an xlsx.Row.
  18. type Cell struct {
  19. Row *Row
  20. Value string
  21. formula string
  22. style *Style
  23. numFmt string
  24. date1904 bool
  25. Hidden bool
  26. cellType CellType
  27. }
  28. // CellInterface defines the public API of the Cell.
  29. type CellInterface interface {
  30. String() string
  31. FormattedValue() string
  32. }
  33. func NewCell(r *Row) *Cell {
  34. return &Cell{style: NewStyle(), Row: r}
  35. }
  36. func (c *Cell) Type() CellType {
  37. return c.cellType
  38. }
  39. // Set string
  40. func (c *Cell) SetString(s string) {
  41. c.Value = s
  42. c.formula = ""
  43. c.cellType = CellTypeString
  44. }
  45. // String returns the value of a Cell as a string.
  46. func (c *Cell) String() string {
  47. return c.FormattedValue()
  48. }
  49. // Set float
  50. func (c *Cell) SetFloat(n float64) {
  51. c.SetFloatWithFormat(n, "0.00e+00")
  52. }
  53. /*
  54. Set float with format. The followings are samples of format samples.
  55. * "0.00e+00"
  56. * "0", "#,##0"
  57. * "0.00", "#,##0.00", "@"
  58. * "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)"
  59. * "#,##0.00;(#,##0.00)", "#,##0.00;[red](#,##0.00)"
  60. * "0%", "0.00%"
  61. * "0.00e+00", "##0.0e+0"
  62. */
  63. func (c *Cell) SetFloatWithFormat(n float64, format string) {
  64. // tmp value. final value is formatted by FormattedValue() method
  65. c.Value = fmt.Sprintf("%e", n)
  66. c.numFmt = format
  67. c.Value = c.FormattedValue()
  68. c.formula = ""
  69. c.cellType = CellTypeNumeric
  70. }
  71. // Returns the value of cell as a number
  72. func (c *Cell) Float() (float64, error) {
  73. f, err := strconv.ParseFloat(c.Value, 64)
  74. if err != nil {
  75. return math.NaN(), err
  76. }
  77. return f, nil
  78. }
  79. // Set a 64-bit integer
  80. func (c *Cell) SetInt64(n int64) {
  81. c.Value = fmt.Sprintf("%d", n)
  82. c.numFmt = "0"
  83. c.formula = ""
  84. c.cellType = CellTypeNumeric
  85. }
  86. // Returns the value of cell as 64-bit integer
  87. func (c *Cell) Int64() (int64, error) {
  88. f, err := strconv.ParseInt(c.Value, 10, 64)
  89. if err != nil {
  90. return -1, err
  91. }
  92. return f, nil
  93. }
  94. // Set integer
  95. func (c *Cell) SetInt(n int) {
  96. c.Value = fmt.Sprintf("%d", n)
  97. c.numFmt = "0"
  98. c.formula = ""
  99. c.cellType = CellTypeNumeric
  100. }
  101. // Returns the value of cell as integer
  102. // Has max 53 bits of precision
  103. // See: float64(int64(math.MaxInt))
  104. func (c *Cell) Int() (int, error) {
  105. f, err := strconv.ParseFloat(c.Value, 64)
  106. if err != nil {
  107. return -1, err
  108. }
  109. return int(f), nil
  110. }
  111. // Set boolean
  112. func (c *Cell) SetBool(b bool) {
  113. if b {
  114. c.Value = "1"
  115. } else {
  116. c.Value = "0"
  117. }
  118. c.cellType = CellTypeBool
  119. }
  120. // Get boolean
  121. func (c *Cell) Bool() bool {
  122. return c.Value == "1"
  123. }
  124. // Set formula
  125. func (c *Cell) SetFormula(formula string) {
  126. c.formula = formula
  127. c.cellType = CellTypeFormula
  128. }
  129. // Returns formula
  130. func (c *Cell) Formula() string {
  131. return c.formula
  132. }
  133. // GetStyle returns the Style associated with a Cell
  134. func (c *Cell) GetStyle() *Style {
  135. return c.style
  136. }
  137. // SetStyle sets the style of a cell.
  138. func (c *Cell) SetStyle(style *Style) {
  139. c.style = style
  140. }
  141. // The number format string is returnable from a cell.
  142. func (c *Cell) GetNumberFormat() string {
  143. return c.numFmt
  144. }
  145. func (c *Cell) formatToTime(format string) string {
  146. f, err := strconv.ParseFloat(c.Value, 64)
  147. if err != nil {
  148. return err.Error()
  149. }
  150. return TimeFromExcelTime(f, c.date1904).Format(format)
  151. }
  152. func (c *Cell) formatToFloat(format string) string {
  153. f, err := strconv.ParseFloat(c.Value, 64)
  154. if err != nil {
  155. return err.Error()
  156. }
  157. return fmt.Sprintf(format, f)
  158. }
  159. func (c *Cell) formatToInt(format string) string {
  160. f, err := strconv.ParseFloat(c.Value, 64)
  161. if err != nil {
  162. return err.Error()
  163. }
  164. return fmt.Sprintf(format, int(f))
  165. }
  166. // Return the formatted version of the value.
  167. func (c *Cell) FormattedValue() string {
  168. var numberFormat string = c.GetNumberFormat()
  169. switch numberFormat {
  170. case "general", "@":
  171. return c.Value
  172. case "0", "#,##0":
  173. return c.formatToInt("%d")
  174. case "0.00", "#,##0.00":
  175. return c.formatToFloat("%.2f")
  176. case "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)":
  177. f, err := strconv.ParseFloat(c.Value, 64)
  178. if err != nil {
  179. return err.Error()
  180. }
  181. if f < 0 {
  182. i := int(math.Abs(f))
  183. return fmt.Sprintf("(%d)", i)
  184. }
  185. i := int(f)
  186. return fmt.Sprintf("%d", i)
  187. case "#,##0.00;(#,##0.00)", "#,##0.00;[red](#,##0.00)":
  188. f, err := strconv.ParseFloat(c.Value, 64)
  189. if err != nil {
  190. return err.Error()
  191. }
  192. if f < 0 {
  193. return fmt.Sprintf("(%.2f)", f)
  194. }
  195. return fmt.Sprintf("%.2f", f)
  196. case "0%":
  197. f, err := strconv.ParseFloat(c.Value, 64)
  198. if err != nil {
  199. return err.Error()
  200. }
  201. f = f * 100
  202. return fmt.Sprintf("%d%%", int(f))
  203. case "0.00%":
  204. f, err := strconv.ParseFloat(c.Value, 64)
  205. if err != nil {
  206. return err.Error()
  207. }
  208. f = f * 100
  209. return fmt.Sprintf("%.2f%%", f)
  210. case "0.00e+00", "##0.0e+0":
  211. return c.formatToFloat("%e")
  212. case "mm-dd-yy":
  213. return c.formatToTime("01-02-06")
  214. case "d-mmm-yy":
  215. return c.formatToTime("2-Jan-06")
  216. case "d-mmm":
  217. return c.formatToTime("2-Jan")
  218. case "mmm-yy":
  219. return c.formatToTime("Jan-06")
  220. case "h:mm am/pm":
  221. return c.formatToTime("3:04 pm")
  222. case "h:mm:ss am/pm":
  223. return c.formatToTime("3:04:05 pm")
  224. case "h:mm":
  225. return c.formatToTime("15:04")
  226. case "h:mm:ss":
  227. return c.formatToTime("15:04:05")
  228. case "m/d/yy h:mm":
  229. return c.formatToTime("1/2/06 15:04")
  230. case "mm:ss":
  231. return c.formatToTime("04:05")
  232. case "[h]:mm:ss":
  233. f, err := strconv.ParseFloat(c.Value, 64)
  234. if err != nil {
  235. return err.Error()
  236. }
  237. t := TimeFromExcelTime(f, c.date1904)
  238. if t.Hour() > 0 {
  239. return t.Format("15:04:05")
  240. }
  241. return t.Format("04:05")
  242. case "mmss.0":
  243. f, err := strconv.ParseFloat(c.Value, 64)
  244. if err != nil {
  245. return err.Error()
  246. }
  247. t := TimeFromExcelTime(f, c.date1904)
  248. return fmt.Sprintf("%0d%0d.%d", t.Minute(), t.Second(), t.Nanosecond()/1000)
  249. case "yyyy\\-mm\\-dd":
  250. return c.formatToTime("2006\\-01\\-02")
  251. case "dd/mm/yy":
  252. return c.formatToTime("02/01/06")
  253. case "hh:mm:ss":
  254. return c.formatToTime("15:04:05")
  255. case "dd/mm/yy\\ hh:mm":
  256. return c.formatToTime("02/01/06\\ 15:04")
  257. case "dd/mm/yyyy hh:mm:ss":
  258. return c.formatToTime("02/01/2006 15:04:05")
  259. case "yy-mm-dd":
  260. return c.formatToTime("06-01-02")
  261. case "d-mmm-yyyy":
  262. return c.formatToTime("2-Jan-2006")
  263. case "m/d/yy":
  264. return c.formatToTime("1/2/06")
  265. case "m/d/yyyy":
  266. return c.formatToTime("1/2/2006")
  267. case "dd-mmm-yyyy":
  268. return c.formatToTime("02-Jan-2006")
  269. case "dd/mm/yyyy":
  270. return c.formatToTime("02/01/2006")
  271. case "mm/dd/yy hh:mm am/pm":
  272. return c.formatToTime("01/02/06 03:04 pm")
  273. case "mm/dd/yyyy hh:mm:ss":
  274. return c.formatToTime("01/02/2006 15:04:05")
  275. case "yyyy-mm-dd hh:mm:ss":
  276. return c.formatToTime("2006-01-02 15:04:05")
  277. }
  278. return c.Value
  279. }