diff --git a/ClosedXML/Excel/XLConstants.cs b/ClosedXML/Excel/XLConstants.cs index d1cbe58..bf4a2a8 100644 --- a/ClosedXML/Excel/XLConstants.cs +++ b/ClosedXML/Excel/XLConstants.cs @@ -4,6 +4,7 @@ public static class XLConstants { public const string PivotTableValuesSentinalLabel = "{{Values}}"; + public const int NumberOfBuiltInStyles = 163; internal static class Comment { diff --git a/ClosedXML/Excel/XLWorkbook_Save.cs b/ClosedXML/Excel/XLWorkbook_Save.cs index dc4ff47..0c40d9d 100644 --- a/ClosedXML/Excel/XLWorkbook_Save.cs +++ b/ClosedXML/Excel/XLWorkbook_Save.cs @@ -599,9 +599,9 @@ { if (XLHelper.IsNullOrWhiteSpace(xlSheet.RelId)) { - rId = String.Format("rId{0}", xlSheet.SheetId); + rId = String.Format("rId{0}", xlSheet.SheetId); context.RelIdGenerator.AddValues(new List { rId }, RelType.Workbook); - } + } else rId = xlSheet.RelId; } @@ -2604,17 +2604,12 @@ if (workbookStylesPart.Stylesheet.CellStyles == null) workbookStylesPart.Stylesheet.CellStyles = new CellStyles(); + // To determine the default workbook style, we look for the style with builtInId = 0 (I hope that is the correct approach) UInt32 defaultFormatId; - if (workbookStylesPart.Stylesheet.CellStyles.Elements().Any(c => c.Name == "Normal")) - { - defaultFormatId = - workbookStylesPart.Stylesheet.CellStyles.Elements().Single(c => c.Name == "Normal").FormatId.Value; - } + if (workbookStylesPart.Stylesheet.CellStyles.Elements().Any(c => c.BuiltinId != null && c.BuiltinId.HasValue && c.BuiltinId.Value == 0)) + defaultFormatId = workbookStylesPart.Stylesheet.CellStyles.Elements().Single(c => c.BuiltinId != null && c.BuiltinId.HasValue && c.BuiltinId.Value == 0).FormatId.Value; else if (workbookStylesPart.Stylesheet.CellStyles.Elements().Any()) - { - defaultFormatId = - workbookStylesPart.Stylesheet.CellStyles.Elements().Max(c => c.FormatId.Value) + 1; - } + defaultFormatId = workbookStylesPart.Stylesheet.CellStyles.Elements().Max(c => c.FormatId.Value) + 1; else defaultFormatId = 0; @@ -2669,7 +2664,7 @@ sharedNumberFormats.Add(numberFormat, new NumberFormatInfo { - NumberFormatId = numberFormatCount + 164, + NumberFormatId = XLConstants.NumberOfBuiltInStyles + numberFormatCount, NumberFormat = numberFormat }); numberFormatCount++; @@ -2695,7 +2690,7 @@ sharedNumberFormats.Add(xlStyle.NumberFormat, new NumberFormatInfo { - NumberFormatId = numberFormatCount + 164, + NumberFormatId = XLConstants.NumberOfBuiltInStyles + numberFormatCount, NumberFormat = xlStyle.NumberFormat }); numberFormatCount++; @@ -2735,13 +2730,9 @@ ResolveCellStyleFormats(workbookStylesPart, context); ResolveRest(workbookStylesPart, context); - if (workbookStylesPart.Stylesheet.CellStyles.Elements().All(c => c.Name != "Normal")) - { - //var defaultFormatId = context.SharedStyles.Values.Where(s => s.Style.Equals(DefaultStyle)).Single().StyleId; + if (!workbookStylesPart.Stylesheet.CellStyles.Elements().Any(c => c.BuiltinId != null && c.BuiltinId.HasValue && c.BuiltinId.Value == 0U)) + workbookStylesPart.Stylesheet.CellStyles.AppendChild(new CellStyle { Name = "Normal", FormatId = defaultFormatId, BuiltinId = 0U }); - var cellStyle1 = new CellStyle { Name = "Normal", FormatId = defaultFormatId, BuiltinId = 0U }; - workbookStylesPart.Stylesheet.CellStyles.AppendChild(cellStyle1); - } workbookStylesPart.Stylesheet.CellStyles.Count = (UInt32)workbookStylesPart.Stylesheet.CellStyles.Count(); var newSharedStyles = new Dictionary(); @@ -2817,7 +2808,7 @@ { var numberFormat = new NumberingFormat { - NumberFormatId = (UInt32)(differentialFormats.Count() + 164), + NumberFormatId = (UInt32)(XLConstants.NumberOfBuiltInStyles + differentialFormats.Count()), FormatCode = cf.Style.NumberFormat.Format }; differentialFormat.Append(numberFormat); @@ -3422,7 +3413,7 @@ var allSharedNumberFormats = new Dictionary(); foreach (var numberFormatInfo in sharedNumberFormats.Values.Where(nf => nf.NumberFormatId != defaultFormatId)) { - var numberingFormatId = 164; + var numberingFormatId = XLConstants.NumberOfBuiltInStyles + 1; var foundOne = false; foreach (NumberingFormat nf in workbookStylesPart.Stylesheet.NumberingFormats) { diff --git a/ClosedXML_Tests/ClosedXML_Tests.csproj b/ClosedXML_Tests/ClosedXML_Tests.csproj index 8a04744..5e7e48e 100644 --- a/ClosedXML_Tests/ClosedXML_Tests.csproj +++ b/ClosedXML_Tests/ClosedXML_Tests.csproj @@ -251,6 +251,7 @@ + diff --git a/ClosedXML_Tests/Excel/Loading/LoadingTests.cs b/ClosedXML_Tests/Excel/Loading/LoadingTests.cs index 3571bd2..8398a20 100644 --- a/ClosedXML_Tests/Excel/Loading/LoadingTests.cs +++ b/ClosedXML_Tests/Excel/Loading/LoadingTests.cs @@ -77,5 +77,24 @@ Assert.AreEqual("NumberOfOrders", pv.SourceName); } } + + /// + /// For non-English locales, the default style ("Normal" in English) can be + /// another piece of text (e.g. Обычный in Russian). + /// This test ensures that the default style is correctly detected and + /// no style conflicts occur on save. + /// + [Test] + public void CanSaveFileWithDefaultStyleNameNotInEnglish() + { + using (var stream = TestHelper.GetStreamFromResource(TestHelper.GetResourcePath(@"Misc\FileWithDefaultStyleNameNotInEnglish.xlsx"))) + using (var wb = new XLWorkbook(stream)) + { + using (var ms = new MemoryStream()) + { + wb.SaveAs(ms, true); + } + } + } } } diff --git a/ClosedXML_Tests/Resource/Misc/FileWithDefaultStyleNameNotInEnglish.xlsx b/ClosedXML_Tests/Resource/Misc/FileWithDefaultStyleNameNotInEnglish.xlsx new file mode 100644 index 0000000..e94bc6a --- /dev/null +++ b/ClosedXML_Tests/Resource/Misc/FileWithDefaultStyleNameNotInEnglish.xlsx Binary files differ