cell.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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 integer
  80. func (c *Cell) SetInt(n int) {
  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 integer
  87. func (c *Cell) Int() (int, error) {
  88. f, err := strconv.ParseFloat(c.Value, 64)
  89. if err != nil {
  90. return -1, err
  91. }
  92. return int(f), nil
  93. }
  94. // Set boolean
  95. func (c *Cell) SetBool(b bool) {
  96. if b {
  97. c.Value = "1"
  98. } else {
  99. c.Value = "0"
  100. }
  101. c.cellType = CellTypeBool
  102. }
  103. // Get boolean
  104. func (c *Cell) Bool() bool {
  105. return c.Value == "1"
  106. }
  107. // Set formula
  108. func (c *Cell) SetFormula(formula string) {
  109. c.formula = formula
  110. c.cellType = CellTypeFormula
  111. }
  112. // Returns formula
  113. func (c *Cell) Formula() string {
  114. return c.formula
  115. }
  116. // GetStyle returns the Style associated with a Cell
  117. func (c *Cell) GetStyle() *Style {
  118. return c.style
  119. }
  120. // SetStyle sets the style of a cell.
  121. func (c *Cell) SetStyle(style *Style) {
  122. c.style = style
  123. }
  124. // The number format string is returnable from a cell.
  125. func (c *Cell) GetNumberFormat() string {
  126. return c.numFmt
  127. }
  128. func (c *Cell) formatToTime(format string) string {
  129. f, err := strconv.ParseFloat(c.Value, 64)
  130. if err != nil {
  131. return err.Error()
  132. }
  133. return TimeFromExcelTime(f, c.date1904).Format(format)
  134. }
  135. func (c *Cell) formatToFloat(format string) string {
  136. f, err := strconv.ParseFloat(c.Value, 64)
  137. if err != nil {
  138. return err.Error()
  139. }
  140. return fmt.Sprintf(format, f)
  141. }
  142. func (c *Cell) formatToInt(format string) string {
  143. f, err := strconv.ParseFloat(c.Value, 64)
  144. if err != nil {
  145. return err.Error()
  146. }
  147. return fmt.Sprintf(format, int(f))
  148. }
  149. // Return the formatted version of the value.
  150. func (c *Cell) FormattedValue() string {
  151. var numberFormat string = c.GetNumberFormat()
  152. switch numberFormat {
  153. case "general":
  154. return c.Value
  155. case "0", "#,##0":
  156. return c.formatToInt("%d")
  157. case "0.00", "#,##0.00", "@":
  158. return c.formatToFloat("%.2f")
  159. case "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)":
  160. f, err := strconv.ParseFloat(c.Value, 64)
  161. if err != nil {
  162. return err.Error()
  163. }
  164. if f < 0 {
  165. i := int(math.Abs(f))
  166. return fmt.Sprintf("(%d)", i)
  167. }
  168. i := int(f)
  169. return fmt.Sprintf("%d", i)
  170. case "#,##0.00;(#,##0.00)", "#,##0.00;[red](#,##0.00)":
  171. f, err := strconv.ParseFloat(c.Value, 64)
  172. if err != nil {
  173. return err.Error()
  174. }
  175. if f < 0 {
  176. return fmt.Sprintf("(%.2f)", f)
  177. }
  178. return fmt.Sprintf("%.2f", f)
  179. case "0%":
  180. f, err := strconv.ParseFloat(c.Value, 64)
  181. if err != nil {
  182. return err.Error()
  183. }
  184. f = f * 100
  185. return fmt.Sprintf("%d%%", int(f))
  186. case "0.00%":
  187. f, err := strconv.ParseFloat(c.Value, 64)
  188. if err != nil {
  189. return err.Error()
  190. }
  191. f = f * 100
  192. return fmt.Sprintf("%.2f%%", f)
  193. case "0.00e+00", "##0.0e+0":
  194. return c.formatToFloat("%e")
  195. case "mm-dd-yy":
  196. return c.formatToTime("01-02-06")
  197. case "d-mmm-yy":
  198. return c.formatToTime("2-Jan-06")
  199. case "d-mmm":
  200. return c.formatToTime("2-Jan")
  201. case "mmm-yy":
  202. return c.formatToTime("Jan-06")
  203. case "h:mm am/pm":
  204. return c.formatToTime("3:04 pm")
  205. case "h:mm:ss am/pm":
  206. return c.formatToTime("3:04:05 pm")
  207. case "h:mm":
  208. return c.formatToTime("15:04")
  209. case "h:mm:ss":
  210. return c.formatToTime("15:04:05")
  211. case "m/d/yy h:mm":
  212. return c.formatToTime("1/2/06 15:04")
  213. case "mm:ss":
  214. return c.formatToTime("04:05")
  215. case "[h]:mm:ss":
  216. f, err := strconv.ParseFloat(c.Value, 64)
  217. if err != nil {
  218. return err.Error()
  219. }
  220. t := TimeFromExcelTime(f, c.date1904)
  221. if t.Hour() > 0 {
  222. return t.Format("15:04:05")
  223. }
  224. return t.Format("04:05")
  225. case "mmss.0":
  226. f, err := strconv.ParseFloat(c.Value, 64)
  227. if err != nil {
  228. return err.Error()
  229. }
  230. t := TimeFromExcelTime(f, c.date1904)
  231. return fmt.Sprintf("%0d%0d.%d", t.Minute(), t.Second(), t.Nanosecond()/1000)
  232. case "yyyy\\-mm\\-dd":
  233. return c.formatToTime("2006\\-01\\-02")
  234. case "dd/mm/yy":
  235. return c.formatToTime("02/01/06")
  236. case "hh:mm:ss":
  237. return c.formatToTime("15:04:05")
  238. case "dd/mm/yy\\ hh:mm":
  239. return c.formatToTime("02/01/06\\ 15:04")
  240. case "dd/mm/yyyy hh:mm:ss":
  241. return c.formatToTime("02/01/2006 15:04:05")
  242. case "yy-mm-dd":
  243. return c.formatToTime("06-01-02")
  244. case "d-mmm-yyyy":
  245. return c.formatToTime("2-Jan-2006")
  246. case "m/d/yy":
  247. return c.formatToTime("1/2/06")
  248. case "m/d/yyyy":
  249. return c.formatToTime("1/2/2006")
  250. case "dd-mmm-yyyy":
  251. return c.formatToTime("02-Jan-2006")
  252. case "dd/mm/yyyy":
  253. return c.formatToTime("02/01/2006")
  254. case "mm/dd/yy hh:mm am/pm":
  255. return c.formatToTime("01/02/06 03:04 pm")
  256. case "mm/dd/yyyy hh:mm:ss":
  257. return c.formatToTime("01/02/2006 15:04:05")
  258. case "yyyy-mm-dd hh:mm:ss":
  259. return c.formatToTime("2006-01-02 15:04:05")
  260. }
  261. return c.Value
  262. }