From 01c9fa5d7738c3638d2f12b09fe7e0e6652b3f18 Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Tue, 28 Nov 2023 16:38:03 +0700 Subject: [PATCH 1/6] Upstream feature: Implement CT_DataValidation and DVRecord Equals() method overrides. --- OpenXmlFormats/Spreadsheet/Sheet.cs | 27 +++++++++++++++++++++++++ main/HSSF/Record/DVRecord.cs | 31 ++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/OpenXmlFormats/Spreadsheet/Sheet.cs b/OpenXmlFormats/Spreadsheet/Sheet.cs index e96aa1621..ab36b4473 100644 --- a/OpenXmlFormats/Spreadsheet/Sheet.cs +++ b/OpenXmlFormats/Spreadsheet/Sheet.cs @@ -7387,6 +7387,33 @@ public void Set(CT_DataValidation obj) promptField = obj.promptField; sqrefField = obj.sqrefField; } + + public override bool Equals(object obj) + { + CT_DataValidation o = (CT_DataValidation)obj; + + if (o is null) + { + return false; + } + + return formula1Field == o.formula1Field + && formula2Field == o.formula2Field + && typeField == o.typeField + && errorStyleField == o.errorStyleField + && imeModeField == o.imeModeField + && operatorField == o.operatorField + && allowBlankField == o.allowBlankField + && showDropDownField == o.showDropDownField + && showInputMessageField == o.showInputMessageField + && showErrorMessageField == o.showErrorMessageField + && errorTitleField == o.errorTitleField + && errorField == o.errorField + && promptTitleField == o.promptTitleField + && promptField == o.promptField + && sqrefField == o.sqrefField; + } + [XmlElement(Order = 0)] public string formula1 { diff --git a/main/HSSF/Record/DVRecord.cs b/main/HSSF/Record/DVRecord.cs index bda26c9c8..dda005113 100644 --- a/main/HSSF/Record/DVRecord.cs +++ b/main/HSSF/Record/DVRecord.cs @@ -185,7 +185,36 @@ public int DataType set { this._option_flags = this.opt_data_type.SetValue(this._option_flags, value); } } + public override bool Equals(object obj) + { + if (obj == null || !(obj is DVRecord)) + { + return false; + } + DVRecord dv = (DVRecord)obj; + return DataType == dv.DataType + && ErrorStyle == dv.ErrorStyle + && EmptyCellAllowed == dv.EmptyCellAllowed + && ShowErrorOnInvalidValue == dv.ShowErrorOnInvalidValue + && ShowPromptOnCellSelected == dv.ShowPromptOnCellSelected + && SuppressDropdownArrow == dv.SuppressDropdownArrow + && ListExplicitFormula == dv.ListExplicitFormula + && ConditionOperator == dv.ConditionOperator + && PromptTitle == dv.PromptTitle + && PromptText == dv.PromptText + && ErrorTitle == dv.ErrorTitle + && ErrorText == dv.ErrorText + && ((Formula1 == null && dv.Formula1 == null) + || Formula1 != null && dv.Formula1 != null + && Formula1.ToString() == dv.Formula1.ToString()) + && ((Formula2 == null && dv.Formula2 == null) + || Formula2 != null && dv.Formula2 != null + && Formula2.ToString() == dv.Formula2.ToString()) + && (CellRangeAddress == null && dv.CellRangeAddress == null + || CellRangeAddress != null && dv.CellRangeAddress != null + && CellRangeAddress.ToString() == dv.CellRangeAddress.ToString()); + } /** * Get the condition error style @@ -426,4 +455,4 @@ public override Object Clone() return CloneViaReserialise(); } } -} \ No newline at end of file +} From 73daa01cf1a15611e53f81413572c6149828b8f6 Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Tue, 28 Nov 2023 16:40:21 +0700 Subject: [PATCH 2/6] Upstream feature: implement DataValidityTable.RemoveDataValidation method --- main/HSSF/Record/Aggregates/DataValidityTable.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/main/HSSF/Record/Aggregates/DataValidityTable.cs b/main/HSSF/Record/Aggregates/DataValidityTable.cs index af830024f..935d6dcd3 100644 --- a/main/HSSF/Record/Aggregates/DataValidityTable.cs +++ b/main/HSSF/Record/Aggregates/DataValidityTable.cs @@ -72,5 +72,11 @@ public void AddDataValidation(DVRecord dvRecord) _validationList.Add(dvRecord); _headerRec.DVRecNo = (_validationList.Count); } + + public void RemoveDataValidation(DVRecord dvRecord) + { + _validationList.Remove(dvRecord); + _headerRec.DVRecNo = _validationList.Count; + } } -} \ No newline at end of file +} From 8e4b633c4dbc9a667a727d43385d72916d884536 Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Tue, 28 Nov 2023 16:41:54 +0700 Subject: [PATCH 3/6] Upstream feature: ass ISheet.RemoveValidationData method and implement it in HSSF, XSSF and SXSSF Sheets --- main/HSSF/UserModel/HSSFSheet.cs | 14 ++++++++++++++ main/SS/UserModel/Sheet.cs | 8 +++++++- ooxml/XSSF/Streaming/SXSSFSheet.cs | 7 ++++++- ooxml/XSSF/UserModel/XSSFSheet.cs | 24 ++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/main/HSSF/UserModel/HSSFSheet.cs b/main/HSSF/UserModel/HSSFSheet.cs index 0599f1de7..e2a72cf53 100644 --- a/main/HSSF/UserModel/HSSFSheet.cs +++ b/main/HSSF/UserModel/HSSFSheet.cs @@ -548,6 +548,20 @@ public void AddValidationData(IDataValidation dataValidation) dvt.AddDataValidation(dvRecord); } + public void RemoveValidationData(IDataValidation dataValidation) + { + if (dataValidation == null) + { + throw new ArgumentException("objValidation must not be null"); + } + + HSSFDataValidation hssfDataValidation = (HSSFDataValidation)dataValidation; + DataValidityTable dvt = _sheet.GetOrCreateDataValidityTable(); + + DVRecord dvRecord = hssfDataValidation.CreateDVRecord(this); + dvt.RemoveDataValidation(dvRecord); + } + /// /// Get the visibility state for a given column.F:\Gloria\�о�\�ļ���ʽ\NPOI\src\NPOI\HSSF\Util\HSSFDataValidation.cs /// diff --git a/main/SS/UserModel/Sheet.cs b/main/SS/UserModel/Sheet.cs index 093c33c06..94a883bea 100644 --- a/main/SS/UserModel/Sheet.cs +++ b/main/SS/UserModel/Sheet.cs @@ -840,6 +840,12 @@ bool Autobreaks /// The data validation object settings void AddValidationData(IDataValidation dataValidation); + /// + /// Removes a data validation object + /// + /// The data validation object settings + void RemoveValidationData(IDataValidation dataValidation); + /// /// Enable filtering for a range of cells /// @@ -947,4 +953,4 @@ bool Autobreaks void CopyTo(IWorkbook dest, string name, bool copyStyle, bool keepFormulas); } -} \ No newline at end of file +} diff --git a/ooxml/XSSF/Streaming/SXSSFSheet.cs b/ooxml/XSSF/Streaming/SXSSFSheet.cs index 8f80deb7d..8b5fb8b2b 100644 --- a/ooxml/XSSF/Streaming/SXSSFSheet.cs +++ b/ooxml/XSSF/Streaming/SXSSFSheet.cs @@ -495,11 +495,16 @@ public void ValidateMergedRegions() { _sh.ValidateMergedRegions(); } - public void AddValidationData(IDataValidation dataValidation) { _sh.AddValidationData(dataValidation); } + + public void RemoveValidationData(IDataValidation dataValidation) + { + _sh.RemoveValidationData(dataValidation); + } + /** * Adjusts the column width to fit the contents. * diff --git a/ooxml/XSSF/UserModel/XSSFSheet.cs b/ooxml/XSSF/UserModel/XSSFSheet.cs index 1b072bc76..b9a6d8900 100644 --- a/ooxml/XSSF/UserModel/XSSFSheet.cs +++ b/ooxml/XSSF/UserModel/XSSFSheet.cs @@ -3326,7 +3326,31 @@ public void AddValidationData(IDataValidation dataValidation) CT_DataValidation newval = dataValidations.AddNewDataValidation(); newval.Set(xssfDataValidation.GetCTDataValidation()); dataValidations.count = (uint)currentCount + 1; + } + + public void RemoveValidationData(IDataValidation dataValidation) + { + XSSFDataValidation xssfDataValidation = (XSSFDataValidation)dataValidation; + CT_DataValidations dataValidations = worksheet.dataValidations; + if (dataValidations is null) + { + return; + } + + int currentCount = dataValidations.sizeOfDataValidationArray(); + + for (int i = 0; i < currentCount; i++) + { + CT_DataValidation ctDataValidation = dataValidations.dataValidation[i]; + + if (ctDataValidation.Equals(xssfDataValidation.GetCTDataValidation())) + { + dataValidations.dataValidation.RemoveAt(i); + dataValidations.count = (uint)currentCount - 1; + return; + } + } } public IAutoFilter SetAutoFilter(CellRangeAddress range) From fefe574b9c1c3f0847c3130cd5e1d032581fc499 Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Tue, 28 Nov 2023 16:44:37 +0700 Subject: [PATCH 4/6] Upstream fix: fix CT_DataValidations.Write method. It was writing an empty dataValidations node if its dataValidation property was empty, which was breaking the resulting xlsx file --- OpenXmlFormats/Spreadsheet/Sheet.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenXmlFormats/Spreadsheet/Sheet.cs b/OpenXmlFormats/Spreadsheet/Sheet.cs index ab36b4473..85a4500cd 100644 --- a/OpenXmlFormats/Spreadsheet/Sheet.cs +++ b/OpenXmlFormats/Spreadsheet/Sheet.cs @@ -7133,6 +7133,8 @@ public static CT_DataValidations Parse(XmlNode node, XmlNamespaceManager namespa internal void Write(StreamWriter sw, string nodeName) { + if (this.countField == 0) + return; sw.Write(string.Format("<{0}", nodeName)); XmlHelper.WriteAttribute(sw, "disablePrompts", this.disablePrompts); XmlHelper.WriteAttribute(sw, "xWindow", this.xWindow); From a39833ec3cf2e35c30c7a78cda9c0b4954de4270 Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Tue, 28 Nov 2023 16:45:29 +0700 Subject: [PATCH 5/6] Upstream feature: add tests for ISheet.RemoveValidationData method --- .../main/HSSF/UserModel/TestDataValidation.cs | 26 +++++++++++++++-- .../XSSF/UserModel/TestXSSFDataValidation.cs | 28 +++++++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/testcases/main/HSSF/UserModel/TestDataValidation.cs b/testcases/main/HSSF/UserModel/TestDataValidation.cs index 428f97078..3c5aa1088 100644 --- a/testcases/main/HSSF/UserModel/TestDataValidation.cs +++ b/testcases/main/HSSF/UserModel/TestDataValidation.cs @@ -464,6 +464,28 @@ public void TestGetDataValidationsFormula() Assert.AreEqual(double.NaN, c.Value2); } - } + [Test] + public void TestRemoveValidationData() + { + + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.CreateSheet() as HSSFSheet; + List list = sheet.GetDataValidations(); + Assert.AreEqual(0, list.Count); -} \ No newline at end of file + IDataValidationHelper dataValidationHelper = sheet.GetDataValidationHelper(); + IDataValidationConstraint constraint = dataValidationHelper.CreateCustomConstraint("A2:A3"); + CellRangeAddressList AddressList = new CellRangeAddressList(0, 0, 0, 0); + IDataValidation validation = dataValidationHelper.CreateValidation(constraint, AddressList); + sheet.AddValidationData(validation); + + list = sheet.GetDataValidations(); + Assert.AreEqual(1, list.Count); + + sheet.RemoveValidationData(validation); + + list = sheet.GetDataValidations(); + Assert.AreEqual(0, list.Count); + } + } +} diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs index 4ab0d20b5..b7d112834 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs @@ -372,6 +372,32 @@ public void TestCreateMultipleRegionsValidation() } } + [Test] + public void TestRemoveValidationData() + { + XSSFWorkbook wb = new XSSFWorkbook(); + try { + XSSFSheet sheet = wb.CreateSheet() as XSSFSheet; + IDataValidationHelper dataValidationHelper = sheet.GetDataValidationHelper(); + IDataValidationConstraint constraint = dataValidationHelper.CreateExplicitListConstraint(new string[] { "A" }); + CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(); + cellRangeAddressList.AddCellRangeAddress(0, 0, 0, 0); + cellRangeAddressList.AddCellRangeAddress(0, 1, 0, 1); + cellRangeAddressList.AddCellRangeAddress(0, 2, 0, 2); + XSSFDataValidation dataValidation = dataValidationHelper.CreateValidation(constraint, cellRangeAddressList) as XSSFDataValidation; + sheet.AddValidationData(dataValidation); + + Assert.AreEqual(1, sheet.GetDataValidations().Count); + + sheet.RemoveValidationData(dataValidation); + + Assert.AreEqual(0, sheet.GetDataValidations().Count); + } + finally { + wb.Close(); + } + } + private XSSFDataValidation CreateValidation(XSSFSheet sheet) { //create the cell that will have the validation applied @@ -387,5 +413,3 @@ private XSSFDataValidation CreateValidation(XSSFSheet sheet) } } - - From 428a170a92df4c2bf4c71d5ef6dc72f39962dbe6 Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Fri, 9 Feb 2024 11:31:06 +0700 Subject: [PATCH 6/6] Upstream feature: change RemoveValidationData methods to RemoveDataValidation --- main/HSSF/UserModel/HSSFSheet.cs | 2 +- main/SS/UserModel/Sheet.cs | 2 +- ooxml/XSSF/Streaming/SXSSFSheet.cs | 4 ++-- ooxml/XSSF/UserModel/XSSFSheet.cs | 2 +- testcases/main/HSSF/UserModel/TestDataValidation.cs | 4 ++-- testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/main/HSSF/UserModel/HSSFSheet.cs b/main/HSSF/UserModel/HSSFSheet.cs index e2a72cf53..d4017a8c0 100644 --- a/main/HSSF/UserModel/HSSFSheet.cs +++ b/main/HSSF/UserModel/HSSFSheet.cs @@ -548,7 +548,7 @@ public void AddValidationData(IDataValidation dataValidation) dvt.AddDataValidation(dvRecord); } - public void RemoveValidationData(IDataValidation dataValidation) + public void RemoveDataValidation(IDataValidation dataValidation) { if (dataValidation == null) { diff --git a/main/SS/UserModel/Sheet.cs b/main/SS/UserModel/Sheet.cs index 94a883bea..3f9aba37d 100644 --- a/main/SS/UserModel/Sheet.cs +++ b/main/SS/UserModel/Sheet.cs @@ -844,7 +844,7 @@ bool Autobreaks /// Removes a data validation object /// /// The data validation object settings - void RemoveValidationData(IDataValidation dataValidation); + void RemoveDataValidation(IDataValidation dataValidation); /// /// Enable filtering for a range of cells diff --git a/ooxml/XSSF/Streaming/SXSSFSheet.cs b/ooxml/XSSF/Streaming/SXSSFSheet.cs index 8b5fb8b2b..35f1d566d 100644 --- a/ooxml/XSSF/Streaming/SXSSFSheet.cs +++ b/ooxml/XSSF/Streaming/SXSSFSheet.cs @@ -500,9 +500,9 @@ public void AddValidationData(IDataValidation dataValidation) _sh.AddValidationData(dataValidation); } - public void RemoveValidationData(IDataValidation dataValidation) + public void RemoveDataValidation(IDataValidation dataValidation) { - _sh.RemoveValidationData(dataValidation); + _sh.RemoveDataValidation(dataValidation); } /** diff --git a/ooxml/XSSF/UserModel/XSSFSheet.cs b/ooxml/XSSF/UserModel/XSSFSheet.cs index b9a6d8900..72c0f953a 100644 --- a/ooxml/XSSF/UserModel/XSSFSheet.cs +++ b/ooxml/XSSF/UserModel/XSSFSheet.cs @@ -3328,7 +3328,7 @@ public void AddValidationData(IDataValidation dataValidation) dataValidations.count = (uint)currentCount + 1; } - public void RemoveValidationData(IDataValidation dataValidation) + public void RemoveDataValidation(IDataValidation dataValidation) { XSSFDataValidation xssfDataValidation = (XSSFDataValidation)dataValidation; CT_DataValidations dataValidations = worksheet.dataValidations; diff --git a/testcases/main/HSSF/UserModel/TestDataValidation.cs b/testcases/main/HSSF/UserModel/TestDataValidation.cs index 3c5aa1088..c68078553 100644 --- a/testcases/main/HSSF/UserModel/TestDataValidation.cs +++ b/testcases/main/HSSF/UserModel/TestDataValidation.cs @@ -465,7 +465,7 @@ public void TestGetDataValidationsFormula() } [Test] - public void TestRemoveValidationData() + public void TestRemoveDataValidation() { HSSFWorkbook wb = new HSSFWorkbook(); @@ -482,7 +482,7 @@ public void TestRemoveValidationData() list = sheet.GetDataValidations(); Assert.AreEqual(1, list.Count); - sheet.RemoveValidationData(validation); + sheet.RemoveDataValidation(validation); list = sheet.GetDataValidations(); Assert.AreEqual(0, list.Count); diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs index b7d112834..c52e70f37 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFDataValidation.cs @@ -373,7 +373,7 @@ public void TestCreateMultipleRegionsValidation() } [Test] - public void TestRemoveValidationData() + public void TestRemoveDataValidation() { XSSFWorkbook wb = new XSSFWorkbook(); try { @@ -389,7 +389,7 @@ public void TestRemoveValidationData() Assert.AreEqual(1, sheet.GetDataValidations().Count); - sheet.RemoveValidationData(dataValidation); + sheet.RemoveDataValidation(dataValidation); Assert.AreEqual(0, sheet.GetDataValidations().Count); }