diff --git a/samples/xlsx/TestIssue459.xlsx b/samples/xlsx/TestIssue459.xlsx new file mode 100644 index 00000000..eb9875d4 Binary files /dev/null and b/samples/xlsx/TestIssue459.xlsx differ diff --git a/src/MiniExcel/MiniExcel.cs b/src/MiniExcel/MiniExcel.cs index dd1ea4ff..d5ce287c 100644 --- a/src/MiniExcel/MiniExcel.cs +++ b/src/MiniExcel/MiniExcel.cs @@ -298,18 +298,7 @@ public static IList GetSheetDimensions(this Stream stream) { return new ExcelOpenXmlSheetReader(stream, null).GetDimensions(); } - - public static IList GetSheetsDimensions(string path) - { - using (var stream = FileHelper.OpenSharedRead(path)) - return GetSheetsDimensions(stream); - } - - public static IList GetSheetsDimensions(this Stream stream) - { - return new ExcelOpenXmlSheetReader(stream, null).GetDimensions(); - } - + public static void ConvertCsvToXlsx(string csv, string xlsx) { using (var csvStream = FileHelper.OpenSharedRead(csv)) diff --git a/src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.Impl.cs b/src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.Impl.cs index 953e306e..9695f508 100644 --- a/src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.Impl.cs +++ b/src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.Impl.cs @@ -991,30 +991,38 @@ private static void ReplaceSharedStringsToStr(IDictionary sharedStr private void UpdateDimensionAndGetRowsInfo(IDictionary inputMaps, XmlDocument doc, XmlNodeList rows, bool changeRowIndex = true) { - // note : dimension need to put on the top (https://user-images.githubusercontent.com/12729184/114507911-5dd88400-9c66-11eb-94c6-82ed7bdb5aab.png) + string[] refs; + if (doc.SelectSingleNode("/x:worksheet/x:dimension", _ns) is XmlElement dimension) + { + refs = dimension.GetAttribute("ref").Split(':'); + } + else + { + var firstRow = rows[0].SelectNodes("x:c", _ns); + var lastRow = rows[rows.Count - 1].SelectNodes("x:c", _ns); + + var dimStart = ((XmlElement)firstRow?[0])?.GetAttribute("r"); + var dimEnd = ((XmlElement)lastRow?[lastRow.Count - 1])?.GetAttribute("r"); + + refs = new[] { dimStart, dimEnd }; - var dimension = doc.SelectSingleNode("/x:worksheet/x:dimension", _ns) as XmlElement; - if (dimension == null) - throw new NotImplementedException("Excel Dimension Xml is null, please file an issue for this problem: https://github.com/mini-software/MiniExcel/issues"); + dimension = (XmlElement)doc.CreateNode(XmlNodeType.Element, "dimension", null); + var worksheet = doc.SelectSingleNode("/x:worksheet", _ns); + worksheet?.InsertBefore(dimension, worksheet.FirstChild); + } var maxRowIndexDiff = 0; foreach (XmlElement row in rows) { // ==== get ienumerable infomation & maxrowindexdiff ==== - //Type ienumerableGenricType = null; - //IDictionary props = null; - //IEnumerable ienumerable = null; - var xRowInfo = new XRowInfo - { - Row = row - }; - + var xRowInfo = new XRowInfo { Row = row }; _xRowInfos.Add(xRowInfo); + foreach (XmlElement c in row.SelectNodes("x:c", _ns)) { var r = c.GetAttribute("r"); - + // ==== mergecells ==== if (_xMergeCellInfos.TryGetValue(r, out var merCell)) { @@ -1122,7 +1130,7 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMaps } // ==== get dimension max rowindex ==== - if (!first) //avoid duplicate add first one, this row not add status ![image](https://user-images.githubusercontent.com/12729184/114851829-d2512580-9e14-11eb-8e7d-520c89a7ebee.png) + if (!first) //avoid duplicate add first one, this row not add status (https://user-images.githubusercontent.com/12729184/114851829-d2512580-9e14-11eb-8e7d-520c89a7ebee.png) maxRowIndexDiff += xRowInfo.IEnumerableMercell?.Height ?? 1; first = false; } @@ -1183,7 +1191,7 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMaps foreach (var element in xRowInfo.CellIEnumerableValues) { // ==== get demension max rowindex ==== - if (!first) //avoid duplicate add first one, this row not add status ![image](https://user-images.githubusercontent.com/12729184/114851829-d2512580-9e14-11eb-8e7d-520c89a7ebee.png) + if (!first) //avoid duplicate add first one, this row not add status (https://user-images.githubusercontent.com/12729184/114851829-d2512580-9e14-11eb-8e7d-520c89a7ebee.png) maxRowIndexDiff++; first = false; } @@ -1249,20 +1257,17 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMaps } } - // e.g only need to update B6 to BMaxRowIndex - var refs = dimension.GetAttribute("ref").Split(':'); + // e.g we only need to update B6 to BMaxRowIndex if (refs.Length == 2) { var letter = StringHelper.GetLetters(refs[1]); var digit = StringHelper.GetNumber(refs[1]); - dimension.SetAttribute("ref", $"{refs[0]}:{letter}{digit + maxRowIndexDiff}"); } else { var letter = StringHelper.GetLetters(refs[0]); var digit = StringHelper.GetNumber(refs[0]); - dimension.SetAttribute("ref", $"A1:{letter}{digit + maxRowIndexDiff}"); } } diff --git a/tests/MiniExcelTests/MiniExcelIssueTests.cs b/tests/MiniExcelTests/MiniExcelIssueTests.cs index 88d88cca..e0eea3ac 100644 --- a/tests/MiniExcelTests/MiniExcelIssueTests.cs +++ b/tests/MiniExcelTests/MiniExcelIssueTests.cs @@ -3615,6 +3615,31 @@ public void Issue422() Assert.Equal(1, enumerableWithCount.GetEnumeratorCount); } + [Fact] + public void Issue459() + { + var template = PathHelper.GetFile("xlsx/TestIssue459.xlsx"); + using var ms = new MemoryStream(); + var values = new + { + title = "FooCompany", + managers = new[] + { + new { name = "Jack", department = "HR" }, + new { name = "Loan", department = "IT" } + }, + employees = new[] + { + new { name = "Wade", department = "HR" }, + new { name = "Felix", department = "HR" }, + new { name = "Eric", department = "IT" }, + new { name = "Keaton", department = "IT" } + } + }; + + ms.SaveAsByTemplate(template, values); + } + private class Issue585VO1 { public string Col1 { get; set; } diff --git a/tests/MiniExcelTests/MiniExcelOpenXmlTests.cs b/tests/MiniExcelTests/MiniExcelOpenXmlTests.cs index 53f38215..2a10d3a5 100644 --- a/tests/MiniExcelTests/MiniExcelOpenXmlTests.cs +++ b/tests/MiniExcelTests/MiniExcelOpenXmlTests.cs @@ -1549,7 +1549,7 @@ public void DateOnlySupportTest() public void SheetDimensionsTest() { var path1 = PathHelper.GetFile("xlsx/TestTypeMapping.xlsx"); - var dim1 = MiniExcel.GetSheetsDimensions(path1); + var dim1 = MiniExcel.GetSheetDimensions(path1); Assert.Equal("A1", dim1[0].StartCell); Assert.Equal("H101", dim1[0].EndCell); Assert.Equal(101, dim1[0].Rows.Count); @@ -1560,7 +1560,7 @@ public void SheetDimensionsTest() Assert.Equal(8, dim1[0].Columns.EndIndex); var path2 = PathHelper.GetFile("xlsx/TestNoDimension.xlsx"); - var dim2 = MiniExcel.GetSheetsDimensions(path2); + var dim2 = MiniExcel.GetSheetDimensions(path2); Assert.Equal(101, dim2[0].Rows.Count); Assert.Equal(7, dim2[0].Columns.Count); Assert.Equal(1, dim2[0].Rows.StartIndex); @@ -1573,7 +1573,7 @@ public void SheetDimensionsTest() public void SheetDimensionsTest_MultiSheet() { var path = PathHelper.GetFile("xlsx/TestMultiSheet.xlsx"); - var dim = MiniExcel.GetSheetsDimensions(path); + var dim = MiniExcel.GetSheetDimensions(path); Assert.Equal("A1", dim[0].StartCell); Assert.Equal("D12", dim[0].EndCell);