2018-09-14 00:35:47 +08:00
|
|
|
/*
|
|
|
|
Package excelize providing a set of functions that allow you to write to
|
|
|
|
and read from XLSX files. Support reads and writes XLSX file generated by
|
|
|
|
Microsoft Excel™ 2007 and later. Support save file without losing original
|
|
|
|
charts of XLSX. This library needs Go version 1.8 or later.
|
|
|
|
|
|
|
|
Copyright 2016 - 2018 The excelize Authors. All rights reserved. Use of
|
|
|
|
this source code is governed by a BSD-style license that can be found in
|
|
|
|
the LICENSE file.
|
|
|
|
*/
|
2018-07-30 22:09:41 +08:00
|
|
|
package excelize
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// DataValidationType defined the type of data validation.
|
2018-07-30 22:09:41 +08:00
|
|
|
type DataValidationType int
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// Data validation types.
|
2018-07-30 22:09:41 +08:00
|
|
|
const (
|
|
|
|
_DataValidationType = iota
|
2018-09-01 23:32:44 +08:00
|
|
|
typeNone // inline use
|
2018-07-30 22:09:41 +08:00
|
|
|
DataValidationTypeCustom
|
|
|
|
DataValidationTypeDate
|
|
|
|
DataValidationTypeDecimal
|
2018-09-01 23:32:44 +08:00
|
|
|
typeList // inline use
|
2018-07-30 22:09:41 +08:00
|
|
|
DataValidationTypeTextLeng
|
|
|
|
DataValidationTypeTime
|
|
|
|
// DataValidationTypeWhole Integer
|
|
|
|
DataValidationTypeWhole
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// dataValidationFormulaStrLen 255 characters+ 2 quotes
|
|
|
|
dataValidationFormulaStrLen = 257
|
|
|
|
// dataValidationFormulaStrLenErr
|
|
|
|
dataValidationFormulaStrLenErr = "data validation must be 0-255 characters"
|
|
|
|
)
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// DataValidationErrorStyle defined the style of data validation error alert.
|
2018-07-30 22:09:41 +08:00
|
|
|
type DataValidationErrorStyle int
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// Data validation error styles.
|
2018-07-30 22:09:41 +08:00
|
|
|
const (
|
|
|
|
_ DataValidationErrorStyle = iota
|
2018-09-01 19:38:30 +08:00
|
|
|
DataValidationErrorStyleStop
|
|
|
|
DataValidationErrorStyleWarning
|
|
|
|
DataValidationErrorStyleInformation
|
2018-07-30 22:09:41 +08:00
|
|
|
)
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// Data validation error styles.
|
2018-07-30 22:09:41 +08:00
|
|
|
const (
|
|
|
|
styleStop = "stop"
|
|
|
|
styleWarning = "warning"
|
|
|
|
styleInformation = "information"
|
|
|
|
)
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// DataValidationOperator operator enum.
|
2018-07-30 22:09:41 +08:00
|
|
|
type DataValidationOperator int
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// Data validation operators.
|
2018-07-30 22:09:41 +08:00
|
|
|
const (
|
|
|
|
_DataValidationOperator = iota
|
|
|
|
DataValidationOperatorBetween
|
|
|
|
DataValidationOperatorEqual
|
|
|
|
DataValidationOperatorGreaterThan
|
|
|
|
DataValidationOperatorGreaterThanOrEqual
|
|
|
|
DataValidationOperatorLessThan
|
|
|
|
DataValidationOperatorLessThanOrEqual
|
|
|
|
DataValidationOperatorNotBetween
|
|
|
|
DataValidationOperatorNotEqual
|
|
|
|
)
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// NewDataValidation return data validation struct.
|
2018-07-30 22:09:41 +08:00
|
|
|
func NewDataValidation(allowBlank bool) *DataValidation {
|
|
|
|
return &DataValidation{
|
2018-09-01 23:32:44 +08:00
|
|
|
AllowBlank: allowBlank,
|
|
|
|
ShowErrorMessage: false,
|
|
|
|
ShowInputMessage: false,
|
2018-07-30 22:09:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// SetError set error notice.
|
2018-09-01 19:38:30 +08:00
|
|
|
func (dd *DataValidation) SetError(style DataValidationErrorStyle, title, msg string) {
|
|
|
|
dd.Error = &msg
|
|
|
|
dd.ErrorTitle = &title
|
2018-07-30 22:09:41 +08:00
|
|
|
strStyle := styleStop
|
|
|
|
switch style {
|
2018-09-01 19:38:30 +08:00
|
|
|
case DataValidationErrorStyleStop:
|
2018-07-30 22:09:41 +08:00
|
|
|
strStyle = styleStop
|
2018-09-01 19:38:30 +08:00
|
|
|
case DataValidationErrorStyleWarning:
|
2018-07-30 22:09:41 +08:00
|
|
|
strStyle = styleWarning
|
2018-09-01 19:38:30 +08:00
|
|
|
case DataValidationErrorStyleInformation:
|
2018-07-30 22:09:41 +08:00
|
|
|
strStyle = styleInformation
|
|
|
|
|
|
|
|
}
|
2018-09-01 23:32:44 +08:00
|
|
|
dd.ShowErrorMessage = true
|
2018-07-30 22:09:41 +08:00
|
|
|
dd.ErrorStyle = &strStyle
|
|
|
|
}
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// SetInput set prompt notice.
|
2018-09-01 19:38:30 +08:00
|
|
|
func (dd *DataValidation) SetInput(title, msg string) {
|
2018-09-01 23:32:44 +08:00
|
|
|
dd.ShowInputMessage = true
|
2018-09-01 19:38:30 +08:00
|
|
|
dd.PromptTitle = &title
|
|
|
|
dd.Prompt = &msg
|
2018-07-30 22:09:41 +08:00
|
|
|
}
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// SetDropList data validation list.
|
2018-07-30 22:09:41 +08:00
|
|
|
func (dd *DataValidation) SetDropList(keys []string) error {
|
|
|
|
dd.Formula1 = "\"" + strings.Join(keys, ",") + "\""
|
|
|
|
dd.Type = convDataValidationType(typeList)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// SetRange provides function to set data validation range in drop list.
|
2018-07-30 22:09:41 +08:00
|
|
|
func (dd *DataValidation) SetRange(f1, f2 int, t DataValidationType, o DataValidationOperator) error {
|
|
|
|
formula1 := fmt.Sprintf("%d", f1)
|
|
|
|
formula2 := fmt.Sprintf("%d", f2)
|
|
|
|
if dataValidationFormulaStrLen < len(dd.Formula1) || dataValidationFormulaStrLen < len(dd.Formula2) {
|
|
|
|
return fmt.Errorf(dataValidationFormulaStrLenErr)
|
|
|
|
}
|
|
|
|
|
|
|
|
dd.Formula1 = formula1
|
|
|
|
dd.Formula2 = formula2
|
|
|
|
dd.Type = convDataValidationType(t)
|
|
|
|
dd.Operator = convDataValidationOperatior(o)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-09-13 10:38:01 +08:00
|
|
|
// SetSqrefDropList provides set data validation on a range with source
|
|
|
|
// reference range of the worksheet by given data validation object and
|
|
|
|
// worksheet name. The data validation object can be created by
|
|
|
|
// NewDataValidation function. For example, set data validation on
|
|
|
|
// Sheet1!A7:B8 with validation criteria source Sheet1!E1:E3 settings, create
|
|
|
|
// in-cell dropdown by allowing list source:
|
|
|
|
//
|
|
|
|
// dvRange := excelize.NewDataValidation(true)
|
|
|
|
// dvRange.Sqref = "A7:B8"
|
|
|
|
// dvRange.SetSqrefDropList("E1:E3", true)
|
|
|
|
// xlsx.AddDataValidation("Sheet1", dvRange)
|
|
|
|
//
|
2018-09-04 13:40:53 +08:00
|
|
|
func (dd *DataValidation) SetSqrefDropList(sqref string, isCurrentSheet bool) error {
|
|
|
|
if isCurrentSheet {
|
|
|
|
dd.Formula1 = sqref
|
|
|
|
dd.Type = convDataValidationType(typeList)
|
|
|
|
return nil
|
|
|
|
}
|
2018-09-12 15:47:56 +08:00
|
|
|
return fmt.Errorf("cross-sheet sqref cell are not supported")
|
2018-09-04 13:40:53 +08:00
|
|
|
}
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// SetSqref provides function to set data validation range in drop list.
|
2018-07-30 22:09:41 +08:00
|
|
|
func (dd *DataValidation) SetSqref(sqref string) {
|
|
|
|
if dd.Sqref == "" {
|
|
|
|
dd.Sqref = sqref
|
|
|
|
} else {
|
|
|
|
dd.Sqref = fmt.Sprintf("%s %s", dd.Sqref, sqref)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// convDataValidationType get excel data validation type.
|
2018-07-30 22:09:41 +08:00
|
|
|
func convDataValidationType(t DataValidationType) string {
|
|
|
|
typeMap := map[DataValidationType]string{
|
|
|
|
typeNone: "none",
|
|
|
|
DataValidationTypeCustom: "custom",
|
|
|
|
DataValidationTypeDate: "date",
|
|
|
|
DataValidationTypeDecimal: "decimal",
|
|
|
|
typeList: "list",
|
|
|
|
DataValidationTypeTextLeng: "textLength",
|
|
|
|
DataValidationTypeTime: "time",
|
|
|
|
DataValidationTypeWhole: "whole",
|
|
|
|
}
|
|
|
|
|
|
|
|
return typeMap[t]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// convDataValidationOperatior get excel data validation operator.
|
2018-07-30 22:09:41 +08:00
|
|
|
func convDataValidationOperatior(o DataValidationOperator) string {
|
|
|
|
typeMap := map[DataValidationOperator]string{
|
|
|
|
DataValidationOperatorBetween: "between",
|
|
|
|
DataValidationOperatorEqual: "equal",
|
|
|
|
DataValidationOperatorGreaterThan: "greaterThan",
|
|
|
|
DataValidationOperatorGreaterThanOrEqual: "greaterThanOrEqual",
|
|
|
|
DataValidationOperatorLessThan: "lessThan",
|
|
|
|
DataValidationOperatorLessThanOrEqual: "lessThanOrEqual",
|
|
|
|
DataValidationOperatorNotBetween: "notBetween",
|
|
|
|
DataValidationOperatorNotEqual: "notEqual",
|
|
|
|
}
|
|
|
|
|
|
|
|
return typeMap[o]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-09-01 23:32:44 +08:00
|
|
|
// AddDataValidation provides set data validation on a range of the worksheet
|
|
|
|
// by given data validation object and worksheet name. The data validation
|
|
|
|
// object can be created by NewDataValidation function.
|
|
|
|
//
|
|
|
|
// Example 1, set data validation on Sheet1!A1:B2 with validation criteria
|
2018-09-02 01:44:32 +08:00
|
|
|
// settings, show error alert after invalid data is entered with "Stop" style
|
2018-09-01 23:32:44 +08:00
|
|
|
// and custom title "error body":
|
|
|
|
//
|
|
|
|
// dvRange := excelize.NewDataValidation(true)
|
2018-09-02 01:44:32 +08:00
|
|
|
// dvRange.Sqref = "A1:B2"
|
2018-09-01 23:32:44 +08:00
|
|
|
// dvRange.SetRange(10, 20, excelize.DataValidationTypeWhole, excelize.DataValidationOperatorBetween)
|
|
|
|
// dvRange.SetError(excelize.DataValidationErrorStyleStop, "error title", "error body")
|
|
|
|
// xlsx.AddDataValidation("Sheet1", dvRange)
|
|
|
|
//
|
|
|
|
// Example 2, set data validation on Sheet1!A3:B4 with validation criteria
|
|
|
|
// settings, and show input message when cell is selected:
|
|
|
|
//
|
|
|
|
// dvRange = excelize.NewDataValidation(true)
|
|
|
|
// dvRange.Sqref = "A3:B4"
|
|
|
|
// dvRange.SetRange(10, 20, excelize.DataValidationTypeWhole, excelize.DataValidationOperatorGreaterThan)
|
|
|
|
// dvRange.SetInput("input title", "input body")
|
|
|
|
// xlsx.AddDataValidation("Sheet1", dvRange)
|
|
|
|
//
|
2018-09-02 01:44:32 +08:00
|
|
|
// Example 3, set data validation on Sheet1!A5:B6 with validation criteria
|
2018-09-13 10:38:01 +08:00
|
|
|
// settings, create in-cell dropdown by allowing list source:
|
2018-09-01 23:32:44 +08:00
|
|
|
//
|
|
|
|
// dvRange = excelize.NewDataValidation(true)
|
|
|
|
// dvRange.Sqref = "A5:B6"
|
|
|
|
// dvRange.SetDropList([]string{"1", "2", "3"})
|
|
|
|
// xlsx.AddDataValidation("Sheet1", dvRange)
|
|
|
|
//
|
2018-07-30 22:09:41 +08:00
|
|
|
func (f *File) AddDataValidation(sheet string, dv *DataValidation) {
|
|
|
|
xlsx := f.workSheetReader(sheet)
|
|
|
|
if nil == xlsx.DataValidations {
|
|
|
|
xlsx.DataValidations = new(xlsxDataValidations)
|
|
|
|
}
|
|
|
|
xlsx.DataValidations.DataValidation = append(xlsx.DataValidations.DataValidation, dv)
|
|
|
|
xlsx.DataValidations.Count = len(xlsx.DataValidations.DataValidation)
|
|
|
|
}
|