diff --git a/src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.Impl.cs b/src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.Impl.cs index 8762adf6..953e306e 100644 --- a/src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.Impl.cs +++ b/src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.Impl.cs @@ -69,11 +69,11 @@ public XMergeCell(XmlElement mergeCell) //TODO: width,height var xy1 = refs[0]; - X1 = ColumnHelper.GetColumnIndex(StringHelper.GetLetter(refs[0])); + X1 = ColumnHelper.GetColumnIndex(StringHelper.GetLetters(refs[0])); Y1 = StringHelper.GetNumber(xy1); var xy2 = refs[1]; - X2 = ColumnHelper.GetColumnIndex(StringHelper.GetLetter(refs[1])); + X2 = ColumnHelper.GetColumnIndex(StringHelper.GetLetters(refs[1])); Y2 = StringHelper.GetNumber(xy2); Width = Math.Abs(X1 - X2) + 1; @@ -718,15 +718,13 @@ private void GenerateCellValues(string endPrefix, StreamWriter writer, ref int r // note: only first time need add diff https://user-images.githubusercontent.com/12729184/114494728-6bceda80-9c4f-11eb-9685-8b5ed054eabe.png if (!isFirst) rowIndexDiff += rowInfo.IEnumerableMercell?.Height ?? 1; //TODO:base on the merge size + if (isFirst) { // https://github.com/mini-software/MiniExcel/issues/771 Saving by template introduces unintended value replication in each row #771 cleanInnerXml = cleanNotFirstRowInnerXmlElement; - - isFirst = false; } - var mergeBaseRowIndex = newRowIndex; newRowIndex += rowInfo.IEnumerableMercell?.Height ?? 1; @@ -795,7 +793,7 @@ private static void MergeCells(List xRowInfos) return new XChildNode { InnerText = s.InnerText, - ColIndex = StringHelper.GetLetter(att), + ColIndex = StringHelper.GetLetters(att), RowIndex = StringHelper.GetNumber(att) }; }) @@ -837,7 +835,7 @@ private static void MergeCells(List xRowInfos) foreach (var childNode in childNodes) { var att = childNode.GetAttribute("r"); - var childNodeLetter = StringHelper.GetLetter(att); + var childNodeLetter = StringHelper.GetLetters(att); var childNodeNumber = StringHelper.GetNumber(att); if (!string.IsNullOrEmpty(childNode.InnerText)) @@ -952,8 +950,8 @@ private static string ConvertToDateTimeString(PropertyInfo propInfo, object cell { //TODO:c.SetAttribute("t", "d"); and custom format var format = propInfo?.GetAttributeValue((ExcelFormatAttribute x) => x.Format) - ?? propInfo?.GetAttributeValue((ExcelColumnAttribute x) => x.Format) - ?? "yyyy-MM-dd HH:mm:ss"; + ?? propInfo?.GetAttributeValue((ExcelColumnAttribute x) => x.Format) + ?? "yyyy-MM-dd HH:mm:ss"; return (cellValue as DateTime?)?.ToString(format); } @@ -962,8 +960,7 @@ private static string ConvertToDateTimeString(PropertyInfo propInfo, object cell private static string CleanXml(string xml, string endPrefix) => CleanXml(new StringBuilder(xml), endPrefix).ToString(); private static StringBuilder CleanXml(StringBuilder xml, string endPrefix) => xml .Replace("xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\"", "") - .Replace($"xmlns{endPrefix}=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"", "") - ; + .Replace($"xmlns{endPrefix}=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"", ""); private static void ReplaceSharedStringsToStr(IDictionary sharedStrings, XmlNodeList rows) { @@ -1028,7 +1025,7 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMaps if (changeRowIndex) { - c.SetAttribute("r", $"{StringHelper.GetLetter(r)}{{{{$rowindex}}}}"); + c.SetAttribute("r", $"{StringHelper.GetLetters(r)}{{{{$rowindex}}}}"); } var v = c.SelectSingleNode("x:v", _ns); @@ -1256,20 +1253,15 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMaps var refs = dimension.GetAttribute("ref").Split(':'); if (refs.Length == 2) { - //var letter = StringHelper.GetLetter(refs[1]); - //var digit = StringHelper.GetDigit(refs[1]); - var letter = new String(refs[1].Where(Char.IsLetter).ToArray()); - var digit = int.Parse(new String(refs[1].Where(Char.IsDigit).ToArray())); + var letter = StringHelper.GetLetters(refs[1]); + var digit = StringHelper.GetNumber(refs[1]); dimension.SetAttribute("ref", $"{refs[0]}:{letter}{digit + maxRowIndexDiff}"); } else { - //var letter = StringHelper.GetLetter(refs[0]); - //var digit = StringHelper.GetDigit(refs[0]); - - var letter = new String(refs[0].Where(Char.IsLetter).ToArray()); - var digit = int.Parse(new String(refs[0].Where(Char.IsDigit).ToArray())); + var letter = StringHelper.GetLetters(refs[0]); + var digit = StringHelper.GetNumber(refs[0]); dimension.SetAttribute("ref", $"A1:{letter}{digit + maxRowIndexDiff}"); } diff --git a/src/MiniExcel/Utils/StringHelper.cs b/src/MiniExcel/Utils/StringHelper.cs index 2773c2ea..e6093db4 100644 --- a/src/MiniExcel/Utils/StringHelper.cs +++ b/src/MiniExcel/Utils/StringHelper.cs @@ -9,19 +9,9 @@ namespace MiniExcelLibs.Utils internal static class StringHelper { private static readonly string[] _ns = { Config.SpreadsheetmlXmlns, Config.SpreadsheetmlXmlStrictns }; - //public static string GetLetter(string content) => content.FirstOrDefault(char.IsLetter).ToString(); - public static int GetDigit(string content) => content.FirstOrDefault(char.IsDigit) - '0'; - //public static int GetNumber(string content) => int.Parse(new string(content.Where(char.IsNumber).ToArray())); - public static string GetLetter(string content) - { - //TODO:need to chekc - return new String(content.Where(Char.IsLetter).ToArray()); - } - public static int GetNumber(string content) - { - return int.Parse(new String(content.Where(Char.IsNumber).ToArray())); - } + public static string GetLetters(string content) => new string(content.Where(char.IsLetter).ToArray()); + public static int GetNumber(string content) => int.Parse(new string(content.Where(char.IsNumber).ToArray())); /// /// Copied and modified from ExcelDataReader - @MIT License diff --git a/tests/MiniExcelTests/MiniExcelIssueTests.cs b/tests/MiniExcelTests/MiniExcelIssueTests.cs index af84ad77..88d88cca 100644 --- a/tests/MiniExcelTests/MiniExcelIssueTests.cs +++ b/tests/MiniExcelTests/MiniExcelIssueTests.cs @@ -4255,18 +4255,19 @@ public void TestIssue772() public void TestIssue773() { var templatePath = PathHelper.GetFile("xlsx/TestIssue773_Template.xlsx"); - List a = new List{ - new { Id = 1, Name = "Bill", A = "a1", B = "b1", C = "c1", D = "d1", E = "e1", F = "f1", G = "g1", H = "H1" }, - new { Id = 2, Name = "Steve", A = "a2", B = "b2", C = "c2", D = "d2", E = "e2", F = "f2", G = "g2", H = "H2" }, - new { Id = 3, Name = "Ram", A = "a3", B = "b3", C = "c3", D = "d3", E = "e3", F = "f3", G = "g3", H = "H3" }, - }; + List a = + [ + new { Id = 1, Name = "Bill", A = "a1", B = "b1", C = "c1", D = "d1", E = "e1", F = "f1", G = "g1", H = "H1" }, + new { Id = 2, Name = "Steve", A = "a2", B = "b2", C = "c2", D = "d2", E = "e2", F = "f2", G = "g2", H = "H2" }, + new { Id = 3, Name = "Ram", A = "a3", B = "b3", C = "c3", D = "d3", E = "e3", F = "f3", G = "g3", H = "H3" } + ]; var fill = new { t = a }; - var path = Path.GetTempPath() + Guid.NewGuid() + ".xlsx"; - Console.WriteLine(path); - MiniExcel.SaveAsByTemplate(path, templatePath, fill); + using var path = AutoDeletingPath.Create(); - var rows = MiniExcel.Query(path, false).ToList(); + MiniExcel.SaveAsByTemplate(path.FilePath, templatePath, fill); + var rows = MiniExcel.Query(path.FilePath).ToList(); + Assert.Equal("H1", rows[4].AF); Assert.Equal("c3", rows[6].AA); Assert.Equal("Ram", rows[6].B);