This commit is contained in:
parent
f20bbd1f1d
commit
4ed493819a
|
@ -91,7 +91,7 @@ func TestConcurrency(t *testing.T) {
|
||||||
// Concurrency add data validation
|
// Concurrency add data validation
|
||||||
dv := NewDataValidation(true)
|
dv := NewDataValidation(true)
|
||||||
dv.Sqref = fmt.Sprintf("A%d:B%d", val, val)
|
dv.Sqref = fmt.Sprintf("A%d:B%d", val, val)
|
||||||
dv.SetRange(10, 20, DataValidationTypeWhole, DataValidationOperatorGreaterThan)
|
assert.NoError(t, dv.SetRange(10, 20, DataValidationTypeWhole, DataValidationOperatorGreaterThan))
|
||||||
dv.SetInput(fmt.Sprintf("title:%d", val), strconv.Itoa(val))
|
dv.SetInput(fmt.Sprintf("title:%d", val), strconv.Itoa(val))
|
||||||
assert.NoError(t, f.AddDataValidation("Sheet1", dv))
|
assert.NoError(t, f.AddDataValidation("Sheet1", dv))
|
||||||
// Concurrency delete data validation with reference sequence
|
// Concurrency delete data validation with reference sequence
|
||||||
|
|
|
@ -13,6 +13,7 @@ package excelize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
|
@ -293,36 +294,70 @@ func (f *File) GetDataValidations(sheet string) ([]*DataValidation, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if ws.DataValidations == nil || len(ws.DataValidations.DataValidation) == 0 {
|
var (
|
||||||
return nil, err
|
dataValidations []*DataValidation
|
||||||
|
decodeExtLst = new(decodeExtLst)
|
||||||
|
decodeDataValidations *xlsxDataValidations
|
||||||
|
ext *xlsxExt
|
||||||
|
)
|
||||||
|
if ws.DataValidations != nil {
|
||||||
|
dataValidations = append(dataValidations, getDataValidations(ws.DataValidations)...)
|
||||||
}
|
}
|
||||||
var dvs []*DataValidation
|
if ws.ExtLst != nil {
|
||||||
for _, dv := range ws.DataValidations.DataValidation {
|
if err = f.xmlNewDecoder(strings.NewReader("<extLst>" + ws.ExtLst.Ext + "</extLst>")).
|
||||||
if dv != nil {
|
Decode(decodeExtLst); err != nil && err != io.EOF {
|
||||||
dataValidation := &DataValidation{
|
return dataValidations, err
|
||||||
AllowBlank: dv.AllowBlank,
|
}
|
||||||
Error: dv.Error,
|
for _, ext = range decodeExtLst.Ext {
|
||||||
ErrorStyle: dv.ErrorStyle,
|
if ext.URI == ExtURIDataValidations {
|
||||||
ErrorTitle: dv.ErrorTitle,
|
decodeDataValidations = new(xlsxDataValidations)
|
||||||
Operator: dv.Operator,
|
_ = f.xmlNewDecoder(strings.NewReader(ext.Content)).Decode(decodeDataValidations)
|
||||||
Prompt: dv.Prompt,
|
dataValidations = append(dataValidations, getDataValidations(decodeDataValidations)...)
|
||||||
PromptTitle: dv.PromptTitle,
|
|
||||||
ShowDropDown: dv.ShowDropDown,
|
|
||||||
ShowErrorMessage: dv.ShowErrorMessage,
|
|
||||||
ShowInputMessage: dv.ShowInputMessage,
|
|
||||||
Sqref: dv.Sqref,
|
|
||||||
Type: dv.Type,
|
|
||||||
}
|
}
|
||||||
if dv.Formula1 != nil {
|
|
||||||
dataValidation.Formula1 = unescapeDataValidationFormula(dv.Formula1.Content)
|
|
||||||
}
|
|
||||||
if dv.Formula2 != nil {
|
|
||||||
dataValidation.Formula2 = unescapeDataValidationFormula(dv.Formula2.Content)
|
|
||||||
}
|
|
||||||
dvs = append(dvs, dataValidation)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dvs, err
|
return dataValidations, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDataValidations returns data validations list by given worksheet data
|
||||||
|
// validations.
|
||||||
|
func getDataValidations(dvs *xlsxDataValidations) []*DataValidation {
|
||||||
|
if dvs == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var dataValidations []*DataValidation
|
||||||
|
for _, dv := range dvs.DataValidation {
|
||||||
|
if dv == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dataValidation := &DataValidation{
|
||||||
|
AllowBlank: dv.AllowBlank,
|
||||||
|
Error: dv.Error,
|
||||||
|
ErrorStyle: dv.ErrorStyle,
|
||||||
|
ErrorTitle: dv.ErrorTitle,
|
||||||
|
Operator: dv.Operator,
|
||||||
|
Prompt: dv.Prompt,
|
||||||
|
PromptTitle: dv.PromptTitle,
|
||||||
|
ShowDropDown: dv.ShowDropDown,
|
||||||
|
ShowErrorMessage: dv.ShowErrorMessage,
|
||||||
|
ShowInputMessage: dv.ShowInputMessage,
|
||||||
|
Sqref: dv.Sqref,
|
||||||
|
Type: dv.Type,
|
||||||
|
}
|
||||||
|
if dv.Formula1 != nil {
|
||||||
|
dataValidation.Formula1 = unescapeDataValidationFormula(dv.Formula1.Content)
|
||||||
|
}
|
||||||
|
if dv.Formula2 != nil {
|
||||||
|
dataValidation.Formula2 = unescapeDataValidationFormula(dv.Formula2.Content)
|
||||||
|
}
|
||||||
|
if dv.XMSqref != "" {
|
||||||
|
dataValidation.Sqref = dv.XMSqref
|
||||||
|
dataValidation.Formula1 = strings.TrimSuffix(strings.TrimPrefix(dataValidation.Formula1, "<xm:f>"), "</xm:f>")
|
||||||
|
dataValidation.Formula2 = strings.TrimSuffix(strings.TrimPrefix(dataValidation.Formula2, "<xm:f>"), "</xm:f>")
|
||||||
|
}
|
||||||
|
dataValidations = append(dataValidations, dataValidation)
|
||||||
|
}
|
||||||
|
return dataValidations
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteDataValidation delete data validation by given worksheet name and
|
// DeleteDataValidation delete data validation by given worksheet name and
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
package excelize
|
package excelize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -104,6 +105,31 @@ func TestDataValidation(t *testing.T) {
|
||||||
dataValidations, err = f.GetDataValidations("Sheet1")
|
dataValidations, err = f.GetDataValidations("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, []*DataValidation(nil), dataValidations)
|
assert.Equal(t, []*DataValidation(nil), dataValidations)
|
||||||
|
|
||||||
|
// Test get data validations which storage in the extension lists
|
||||||
|
f = NewFile()
|
||||||
|
ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
|
||||||
|
assert.True(t, ok)
|
||||||
|
ws.(*xlsxWorksheet).ExtLst = &xlsxExtLst{Ext: fmt.Sprintf(`<ext uri="%s" xmlns:x14="%s"><x14:dataValidations><x14:dataValidation type="list" allowBlank="1"><x14:formula1><xm:f>Sheet1!$B$1:$B$5</xm:f></x14:formula1><xm:sqref>A7:B8</xm:sqref></x14:dataValidation></x14:dataValidations></ext>`, ExtURIDataValidations, NameSpaceSpreadSheetX14.Value)}
|
||||||
|
dataValidations, err = f.GetDataValidations("Sheet1")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, []*DataValidation{
|
||||||
|
{
|
||||||
|
AllowBlank: true,
|
||||||
|
Type: "list",
|
||||||
|
Formula1: "Sheet1!$B$1:$B$5",
|
||||||
|
Sqref: "A7:B8",
|
||||||
|
},
|
||||||
|
}, dataValidations)
|
||||||
|
|
||||||
|
// Test get data validations with invalid extension list characters
|
||||||
|
ws.(*xlsxWorksheet).ExtLst = &xlsxExtLst{Ext: fmt.Sprintf(`<ext uri="%s" xmlns:x14="%s"><x14:dataValidations></x14:dataValidation></x14:dataValidations></ext>`, ExtURIDataValidations, NameSpaceSpreadSheetX14.Value)}
|
||||||
|
_, err = f.GetDataValidations("Sheet1")
|
||||||
|
assert.EqualError(t, err, "XML syntax error on line 1: element <dataValidations> closed by </dataValidation>")
|
||||||
|
|
||||||
|
// Test get validations without validations
|
||||||
|
assert.Nil(t, getDataValidations(nil))
|
||||||
|
assert.Nil(t, getDataValidations(&xlsxDataValidations{DataValidation: []*xlsxDataValidation{nil}}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDataValidationError(t *testing.T) {
|
func TestDataValidationError(t *testing.T) {
|
||||||
|
|
|
@ -103,7 +103,7 @@ const (
|
||||||
ExtURIConditionalFormattingRuleID = "{B025F937-C7B1-47D3-B67F-A62EFF666E3E}"
|
ExtURIConditionalFormattingRuleID = "{B025F937-C7B1-47D3-B67F-A62EFF666E3E}"
|
||||||
ExtURIConditionalFormattings = "{78C0D931-6437-407d-A8EE-F0AAD7539E65}"
|
ExtURIConditionalFormattings = "{78C0D931-6437-407d-A8EE-F0AAD7539E65}"
|
||||||
ExtURIDataModel = "{FCE2AD5D-F65C-4FA6-A056-5C36A1767C68}"
|
ExtURIDataModel = "{FCE2AD5D-F65C-4FA6-A056-5C36A1767C68}"
|
||||||
ExtURIDataValidations = "{CCE6A557-97BC-4B89-ADB6-D9C93CAAB3DF}"
|
ExtURIDataValidations = "{CCE6A557-97BC-4b89-ADB6-D9C93CAAB3DF}"
|
||||||
ExtURIDrawingBlip = "{28A0092B-C50C-407E-A947-70E740481C1C}"
|
ExtURIDrawingBlip = "{28A0092B-C50C-407E-A947-70E740481C1C}"
|
||||||
ExtURIExternalLinkPr = "{FCE6A71B-6B00-49CD-AB44-F6B1AE7CDE65}"
|
ExtURIExternalLinkPr = "{FCE6A71B-6B00-49CD-AB44-F6B1AE7CDE65}"
|
||||||
ExtURIIgnoredErrors = "{01252117-D84E-4E92-8308-4BE1C098FCBB}"
|
ExtURIIgnoredErrors = "{01252117-D84E-4E92-8308-4BE1C098FCBB}"
|
||||||
|
|
|
@ -441,6 +441,7 @@ type xlsxDataValidation struct {
|
||||||
ShowErrorMessage bool `xml:"showErrorMessage,attr,omitempty"`
|
ShowErrorMessage bool `xml:"showErrorMessage,attr,omitempty"`
|
||||||
ShowInputMessage bool `xml:"showInputMessage,attr,omitempty"`
|
ShowInputMessage bool `xml:"showInputMessage,attr,omitempty"`
|
||||||
Sqref string `xml:"sqref,attr"`
|
Sqref string `xml:"sqref,attr"`
|
||||||
|
XMSqref string `xml:"sqref,omitempty"`
|
||||||
Type string `xml:"type,attr,omitempty"`
|
Type string `xml:"type,attr,omitempty"`
|
||||||
Formula1 *xlsxInnerXML `xml:"formula1"`
|
Formula1 *xlsxInnerXML `xml:"formula1"`
|
||||||
Formula2 *xlsxInnerXML `xml:"formula2"`
|
Formula2 *xlsxInnerXML `xml:"formula2"`
|
||||||
|
|
Loading…
Reference in New Issue