data_validation.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. package xlsx
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. type DataValidationType int
  7. // Data validation types
  8. const (
  9. _DataValidationType = iota
  10. typeNone //inline use
  11. DataValidationTypeCustom
  12. DataValidationTypeDate
  13. DataValidationTypeDecimal
  14. dataValidationTypeList //inline use
  15. DataValidationTypeTextLeng
  16. DataValidationTypeTime
  17. // DataValidationTypeWhole Integer
  18. DataValidationTypeWhole
  19. )
  20. const (
  21. // dataValidationFormulaStrLen 255 characters+ 2 quotes
  22. dataValidationFormulaStrLen = 257
  23. // dataValidationFormulaStrLenErr
  24. dataValidationFormulaStrLenErr = "data validation must be 0-255 characters"
  25. )
  26. type DataValidationErrorStyle int
  27. // Data validation error styles
  28. const (
  29. _ DataValidationErrorStyle = iota
  30. StyleStop
  31. StyleWarning
  32. StyleInformation
  33. )
  34. // Data validation error styles
  35. const (
  36. styleStop = "stop"
  37. styleWarning = "warning"
  38. styleInformation = "information"
  39. )
  40. // DataValidationOperator operator enum
  41. type DataValidationOperator int
  42. // Data validation operators
  43. const (
  44. _DataValidationOperator = iota
  45. DataValidationOperatorBetween
  46. DataValidationOperatorEqual
  47. DataValidationOperatorGreaterThan
  48. DataValidationOperatorGreaterThanOrEqual
  49. DataValidationOperatorLessThan
  50. DataValidationOperatorLessThanOrEqual
  51. DataValidationOperatorNotBetween
  52. DataValidationOperatorNotEqual
  53. )
  54. // NewXlsxCellDataValidation return data validation struct
  55. func NewXlsxCellDataValidation(allowBlank bool) *xlsxCellDataValidation {
  56. return &xlsxCellDataValidation{
  57. AllowBlank: allowBlank,
  58. }
  59. }
  60. // SetError set error notice
  61. func (dd *xlsxCellDataValidation) SetError(style DataValidationErrorStyle, title, msg *string) {
  62. dd.ShowErrorMessage = true
  63. dd.Error = msg
  64. dd.ErrorTitle = title
  65. strStyle := styleStop
  66. switch style {
  67. case StyleStop:
  68. strStyle = styleStop
  69. case StyleWarning:
  70. strStyle = styleWarning
  71. case StyleInformation:
  72. strStyle = styleInformation
  73. }
  74. dd.ErrorStyle = &strStyle
  75. }
  76. // SetInput set prompt notice
  77. func (dd *xlsxCellDataValidation) SetInput(title, msg *string) {
  78. dd.ShowInputMessage = true
  79. dd.PromptTitle = title
  80. dd.Prompt = msg
  81. }
  82. // SetDropList sets a hard coded list of values that the drop down will choose from.
  83. // List validations do not work in Apple Numbers.
  84. func (dd *xlsxCellDataValidation) SetDropList(keys []string) error {
  85. formula := "\"" + strings.Join(keys, ",") + "\""
  86. if dataValidationFormulaStrLen < len(formula) {
  87. return fmt.Errorf(dataValidationFormulaStrLenErr)
  88. }
  89. dd.Formula1 = formula
  90. dd.Type = convDataValidationType(dataValidationTypeList)
  91. return nil
  92. }
  93. // SetInFileList is like SetDropList, excel that instead of having a hard coded list,
  94. // a reference to a part of the file is accepted and the list is automatically taken from there.
  95. // Setting y2 to -1 will select all the way to the end of the column. Selecting to the end of the
  96. // column will cause Google Sheets to spin indefinitely while trying to load the possible drop down
  97. // values (more than 5 minutes).
  98. // List validations do not work in Apple Numbers.
  99. func (dd *xlsxCellDataValidation) SetInFileList(sheet string, x1, y1, x2, y2 int) error {
  100. start := GetCellIDStringFromCoordsWithFixed(x1, y1, true, true)
  101. if y2 < 0 {
  102. y2 = Excel2006MaxRowIndex
  103. }
  104. end := GetCellIDStringFromCoordsWithFixed(x2, y2, true, true)
  105. // Escape single quotes in the file name.
  106. // Single quotes are escaped by replacing them with two single quotes.
  107. sheet = strings.Replace(sheet, "'", "''", -1)
  108. formula := "'" + sheet + "'" + externalSheetBangChar + start + cellRangeChar + end
  109. dd.Formula1 = formula
  110. dd.Type = convDataValidationType(dataValidationTypeList)
  111. return nil
  112. }
  113. // SetDropList data validation range
  114. func (dd *xlsxCellDataValidation) SetRange(f1, f2 int, t DataValidationType, o DataValidationOperator) error {
  115. formula1 := fmt.Sprintf("%d", f1)
  116. formula2 := fmt.Sprintf("%d", f2)
  117. switch o {
  118. case DataValidationOperatorBetween:
  119. if f1 > f2 {
  120. tmp := formula1
  121. formula1 = formula2
  122. formula2 = tmp
  123. }
  124. case DataValidationOperatorNotBetween:
  125. if f1 > f2 {
  126. tmp := formula1
  127. formula1 = formula2
  128. formula2 = tmp
  129. }
  130. }
  131. dd.Formula1 = formula1
  132. dd.Formula2 = formula2
  133. dd.Type = convDataValidationType(t)
  134. dd.Operator = convDataValidationOperatior(o)
  135. return nil
  136. }
  137. // convDataValidationType get excel data validation type
  138. func convDataValidationType(t DataValidationType) string {
  139. typeMap := map[DataValidationType]string{
  140. typeNone: "none",
  141. DataValidationTypeCustom: "custom",
  142. DataValidationTypeDate: "date",
  143. DataValidationTypeDecimal: "decimal",
  144. dataValidationTypeList: "list",
  145. DataValidationTypeTextLeng: "textLength",
  146. DataValidationTypeTime: "time",
  147. DataValidationTypeWhole: "whole",
  148. }
  149. return typeMap[t]
  150. }
  151. // convDataValidationOperatior get excel data validation operator
  152. func convDataValidationOperatior(o DataValidationOperator) string {
  153. typeMap := map[DataValidationOperator]string{
  154. DataValidationOperatorBetween: "between",
  155. DataValidationOperatorEqual: "equal",
  156. DataValidationOperatorGreaterThan: "greaterThan",
  157. DataValidationOperatorGreaterThanOrEqual: "greaterThanOrEqual",
  158. DataValidationOperatorLessThan: "lessThan",
  159. DataValidationOperatorLessThanOrEqual: "lessThanOrEqual",
  160. DataValidationOperatorNotBetween: "notBetween",
  161. DataValidationOperatorNotEqual: "notEqual",
  162. }
  163. return typeMap[o]
  164. }