cell.go 6.8 KB

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