datavalidation.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. Package excelize providing a set of functions that allow you to write to
  3. and read from XLSX files. Support reads and writes XLSX file generated by
  4. Microsoft Excel™ 2007 and later. Support save file without losing original
  5. charts of XLSX. This library needs Go version 1.8 or later.
  6. Copyright 2016 - 2018 The excelize Authors. All rights reserved. Use of
  7. this source code is governed by a BSD-style license that can be found in
  8. the LICENSE file.
  9. */
  10. package excelize
  11. import (
  12. "fmt"
  13. "strings"
  14. )
  15. // DataValidationType defined the type of data validation.
  16. type DataValidationType int
  17. // Data validation types.
  18. const (
  19. _DataValidationType = iota
  20. typeNone // inline use
  21. DataValidationTypeCustom
  22. DataValidationTypeDate
  23. DataValidationTypeDecimal
  24. typeList // inline use
  25. DataValidationTypeTextLeng
  26. DataValidationTypeTime
  27. // DataValidationTypeWhole Integer
  28. DataValidationTypeWhole
  29. )
  30. const (
  31. // dataValidationFormulaStrLen 255 characters+ 2 quotes
  32. dataValidationFormulaStrLen = 257
  33. // dataValidationFormulaStrLenErr
  34. dataValidationFormulaStrLenErr = "data validation must be 0-255 characters"
  35. )
  36. // DataValidationErrorStyle defined the style of data validation error alert.
  37. type DataValidationErrorStyle int
  38. // Data validation error styles.
  39. const (
  40. _ DataValidationErrorStyle = iota
  41. DataValidationErrorStyleStop
  42. DataValidationErrorStyleWarning
  43. DataValidationErrorStyleInformation
  44. )
  45. // Data validation error styles.
  46. const (
  47. styleStop = "stop"
  48. styleWarning = "warning"
  49. styleInformation = "information"
  50. )
  51. // DataValidationOperator operator enum.
  52. type DataValidationOperator int
  53. // Data validation operators.
  54. const (
  55. _DataValidationOperator = iota
  56. DataValidationOperatorBetween
  57. DataValidationOperatorEqual
  58. DataValidationOperatorGreaterThan
  59. DataValidationOperatorGreaterThanOrEqual
  60. DataValidationOperatorLessThan
  61. DataValidationOperatorLessThanOrEqual
  62. DataValidationOperatorNotBetween
  63. DataValidationOperatorNotEqual
  64. )
  65. // NewDataValidation return data validation struct.
  66. func NewDataValidation(allowBlank bool) *DataValidation {
  67. return &DataValidation{
  68. AllowBlank: allowBlank,
  69. ShowErrorMessage: false,
  70. ShowInputMessage: false,
  71. }
  72. }
  73. // SetError set error notice.
  74. func (dd *DataValidation) SetError(style DataValidationErrorStyle, title, msg string) {
  75. dd.Error = &msg
  76. dd.ErrorTitle = &title
  77. strStyle := styleStop
  78. switch style {
  79. case DataValidationErrorStyleStop:
  80. strStyle = styleStop
  81. case DataValidationErrorStyleWarning:
  82. strStyle = styleWarning
  83. case DataValidationErrorStyleInformation:
  84. strStyle = styleInformation
  85. }
  86. dd.ShowErrorMessage = true
  87. dd.ErrorStyle = &strStyle
  88. }
  89. // SetInput set prompt notice.
  90. func (dd *DataValidation) SetInput(title, msg string) {
  91. dd.ShowInputMessage = true
  92. dd.PromptTitle = &title
  93. dd.Prompt = &msg
  94. }
  95. // SetDropList data validation list.
  96. func (dd *DataValidation) SetDropList(keys []string) error {
  97. dd.Formula1 = "\"" + strings.Join(keys, ",") + "\""
  98. dd.Type = convDataValidationType(typeList)
  99. return nil
  100. }
  101. // SetRange provides function to set data validation range in drop list.
  102. func (dd *DataValidation) SetRange(f1, f2 int, t DataValidationType, o DataValidationOperator) error {
  103. formula1 := fmt.Sprintf("%d", f1)
  104. formula2 := fmt.Sprintf("%d", f2)
  105. if dataValidationFormulaStrLen < len(dd.Formula1) || dataValidationFormulaStrLen < len(dd.Formula2) {
  106. return fmt.Errorf(dataValidationFormulaStrLenErr)
  107. }
  108. dd.Formula1 = formula1
  109. dd.Formula2 = formula2
  110. dd.Type = convDataValidationType(t)
  111. dd.Operator = convDataValidationOperatior(o)
  112. return nil
  113. }
  114. // SetSqrefDropList provides set data validation on a range with source
  115. // reference range of the worksheet by given data validation object and
  116. // worksheet name. The data validation object can be created by
  117. // NewDataValidation function. For example, set data validation on
  118. // Sheet1!A7:B8 with validation criteria source Sheet1!E1:E3 settings, create
  119. // in-cell dropdown by allowing list source:
  120. //
  121. // dvRange := excelize.NewDataValidation(true)
  122. // dvRange.Sqref = "A7:B8"
  123. // dvRange.SetSqrefDropList("E1:E3", true)
  124. // xlsx.AddDataValidation("Sheet1", dvRange)
  125. //
  126. func (dd *DataValidation) SetSqrefDropList(sqref string, isCurrentSheet bool) error {
  127. if isCurrentSheet {
  128. dd.Formula1 = sqref
  129. dd.Type = convDataValidationType(typeList)
  130. return nil
  131. }
  132. return fmt.Errorf("cross-sheet sqref cell are not supported")
  133. }
  134. // SetSqref provides function to set data validation range in drop list.
  135. func (dd *DataValidation) SetSqref(sqref string) {
  136. if dd.Sqref == "" {
  137. dd.Sqref = sqref
  138. } else {
  139. dd.Sqref = fmt.Sprintf("%s %s", dd.Sqref, sqref)
  140. }
  141. }
  142. // convDataValidationType get excel data validation type.
  143. func convDataValidationType(t DataValidationType) string {
  144. typeMap := map[DataValidationType]string{
  145. typeNone: "none",
  146. DataValidationTypeCustom: "custom",
  147. DataValidationTypeDate: "date",
  148. DataValidationTypeDecimal: "decimal",
  149. typeList: "list",
  150. DataValidationTypeTextLeng: "textLength",
  151. DataValidationTypeTime: "time",
  152. DataValidationTypeWhole: "whole",
  153. }
  154. return typeMap[t]
  155. }
  156. // convDataValidationOperatior get excel data validation operator.
  157. func convDataValidationOperatior(o DataValidationOperator) string {
  158. typeMap := map[DataValidationOperator]string{
  159. DataValidationOperatorBetween: "between",
  160. DataValidationOperatorEqual: "equal",
  161. DataValidationOperatorGreaterThan: "greaterThan",
  162. DataValidationOperatorGreaterThanOrEqual: "greaterThanOrEqual",
  163. DataValidationOperatorLessThan: "lessThan",
  164. DataValidationOperatorLessThanOrEqual: "lessThanOrEqual",
  165. DataValidationOperatorNotBetween: "notBetween",
  166. DataValidationOperatorNotEqual: "notEqual",
  167. }
  168. return typeMap[o]
  169. }
  170. // AddDataValidation provides set data validation on a range of the worksheet
  171. // by given data validation object and worksheet name. The data validation
  172. // object can be created by NewDataValidation function.
  173. //
  174. // Example 1, set data validation on Sheet1!A1:B2 with validation criteria
  175. // settings, show error alert after invalid data is entered with "Stop" style
  176. // and custom title "error body":
  177. //
  178. // dvRange := excelize.NewDataValidation(true)
  179. // dvRange.Sqref = "A1:B2"
  180. // dvRange.SetRange(10, 20, excelize.DataValidationTypeWhole, excelize.DataValidationOperatorBetween)
  181. // dvRange.SetError(excelize.DataValidationErrorStyleStop, "error title", "error body")
  182. // xlsx.AddDataValidation("Sheet1", dvRange)
  183. //
  184. // Example 2, set data validation on Sheet1!A3:B4 with validation criteria
  185. // settings, and show input message when cell is selected:
  186. //
  187. // dvRange = excelize.NewDataValidation(true)
  188. // dvRange.Sqref = "A3:B4"
  189. // dvRange.SetRange(10, 20, excelize.DataValidationTypeWhole, excelize.DataValidationOperatorGreaterThan)
  190. // dvRange.SetInput("input title", "input body")
  191. // xlsx.AddDataValidation("Sheet1", dvRange)
  192. //
  193. // Example 3, set data validation on Sheet1!A5:B6 with validation criteria
  194. // settings, create in-cell dropdown by allowing list source:
  195. //
  196. // dvRange = excelize.NewDataValidation(true)
  197. // dvRange.Sqref = "A5:B6"
  198. // dvRange.SetDropList([]string{"1", "2", "3"})
  199. // xlsx.AddDataValidation("Sheet1", dvRange)
  200. //
  201. func (f *File) AddDataValidation(sheet string, dv *DataValidation) {
  202. xlsx := f.workSheetReader(sheet)
  203. if nil == xlsx.DataValidations {
  204. xlsx.DataValidations = new(xlsxDataValidations)
  205. }
  206. xlsx.DataValidations.DataValidation = append(xlsx.DataValidations.DataValidation, dv)
  207. xlsx.DataValidations.Count = len(xlsx.DataValidations.DataValidation)
  208. }