data_validation.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. // NewDataValidation return data validation struct
  55. func NewDataValidation(startRow, startCol, endRow, endCol int, allowBlank bool) *xlsxDataValidation {
  56. startX := ColIndexToLetters(startCol)
  57. startY := RowIndexToString(startRow)
  58. endX := ColIndexToLetters(endCol)
  59. endY := RowIndexToString(endRow)
  60. sqref := startX + startY
  61. if startX != endX || startY != endY {
  62. sqref += ":" + endX + endY
  63. }
  64. return &xlsxDataValidation{
  65. AllowBlank: allowBlank,
  66. Sqref: sqref,
  67. }
  68. }
  69. // SetError set error notice
  70. func (dd *xlsxDataValidation) SetError(style DataValidationErrorStyle, title, msg *string) {
  71. dd.ShowErrorMessage = true
  72. dd.Error = msg
  73. dd.ErrorTitle = title
  74. strStyle := styleStop
  75. switch style {
  76. case StyleStop:
  77. strStyle = styleStop
  78. case StyleWarning:
  79. strStyle = styleWarning
  80. case StyleInformation:
  81. strStyle = styleInformation
  82. }
  83. dd.ErrorStyle = &strStyle
  84. }
  85. // SetInput set prompt notice
  86. func (dd *xlsxDataValidation) SetInput(title, msg *string) {
  87. dd.ShowInputMessage = true
  88. dd.PromptTitle = title
  89. dd.Prompt = msg
  90. }
  91. // SetDropList sets a hard coded list of values that the drop down will choose from.
  92. // List validations do not work in Apple Numbers.
  93. func (dd *xlsxDataValidation) SetDropList(keys []string) error {
  94. formula := "\"" + strings.Join(keys, ",") + "\""
  95. if dataValidationFormulaStrLen < len(formula) {
  96. return fmt.Errorf(dataValidationFormulaStrLenErr)
  97. }
  98. dd.Formula1 = formula
  99. dd.Type = convDataValidationType(dataValidationTypeList)
  100. return nil
  101. }
  102. // SetInFileList is like SetDropList, excel that instead of having a hard coded list,
  103. // a reference to a part of the file is accepted and the list is automatically taken from there.
  104. // Setting y2 to -1 will select all the way to the end of the column. Selecting to the end of the
  105. // column will cause Google Sheets to spin indefinitely while trying to load the possible drop down
  106. // values (more than 5 minutes).
  107. // List validations do not work in Apple Numbers.
  108. func (dd *xlsxDataValidation) SetInFileList(sheet string, x1, y1, x2, y2 int) error {
  109. start := GetCellIDStringFromCoordsWithFixed(x1, y1, true, true)
  110. if y2 < 0 {
  111. y2 = Excel2006MaxRowIndex
  112. }
  113. end := GetCellIDStringFromCoordsWithFixed(x2, y2, true, true)
  114. // Escape single quotes in the file name.
  115. // Single quotes are escaped by replacing them with two single quotes.
  116. sheet = strings.Replace(sheet, "'", "''", -1)
  117. formula := "'" + sheet + "'" + externalSheetBangChar + start + cellRangeChar + end
  118. dd.Formula1 = formula
  119. dd.Type = convDataValidationType(dataValidationTypeList)
  120. return nil
  121. }
  122. // SetDropList data validation range
  123. func (dd *xlsxDataValidation) SetRange(f1, f2 int, t DataValidationType, o DataValidationOperator) error {
  124. formula1 := fmt.Sprintf("%d", f1)
  125. formula2 := fmt.Sprintf("%d", f2)
  126. switch o {
  127. case DataValidationOperatorBetween:
  128. if f1 > f2 {
  129. tmp := formula1
  130. formula1 = formula2
  131. formula2 = tmp
  132. }
  133. case DataValidationOperatorNotBetween:
  134. if f1 > f2 {
  135. tmp := formula1
  136. formula1 = formula2
  137. formula2 = tmp
  138. }
  139. }
  140. dd.Formula1 = formula1
  141. dd.Formula2 = formula2
  142. dd.Type = convDataValidationType(t)
  143. dd.Operator = convDataValidationOperatior(o)
  144. return nil
  145. }
  146. // convDataValidationType get excel data validation type
  147. func convDataValidationType(t DataValidationType) string {
  148. typeMap := map[DataValidationType]string{
  149. typeNone: "none",
  150. DataValidationTypeCustom: "custom",
  151. DataValidationTypeDate: "date",
  152. DataValidationTypeDecimal: "decimal",
  153. dataValidationTypeList: "list",
  154. DataValidationTypeTextLeng: "textLength",
  155. DataValidationTypeTime: "time",
  156. DataValidationTypeWhole: "whole",
  157. }
  158. return typeMap[t]
  159. }
  160. // convDataValidationOperatior get excel data validation operator
  161. func convDataValidationOperatior(o DataValidationOperator) string {
  162. typeMap := map[DataValidationOperator]string{
  163. DataValidationOperatorBetween: "between",
  164. DataValidationOperatorEqual: "equal",
  165. DataValidationOperatorGreaterThan: "greaterThan",
  166. DataValidationOperatorGreaterThanOrEqual: "greaterThanOrEqual",
  167. DataValidationOperatorLessThan: "lessThan",
  168. DataValidationOperatorLessThanOrEqual: "lessThanOrEqual",
  169. DataValidationOperatorNotBetween: "notBetween",
  170. DataValidationOperatorNotEqual: "notEqual",
  171. }
  172. return typeMap[o]
  173. }