diff --git a/src/EPPlus.DrawingRenderer.Tests/Shape/ShapeToSvgTests.cs b/src/EPPlus.DrawingRenderer.Tests/Shape/ShapeToSvgTests.cs index 214d831085..14ddf495fd 100644 --- a/src/EPPlus.DrawingRenderer.Tests/Shape/ShapeToSvgTests.cs +++ b/src/EPPlus.DrawingRenderer.Tests/Shape/ShapeToSvgTests.cs @@ -85,7 +85,7 @@ public void Rect() d.TextAlignment = OfficeOpenXml.Drawing.eTextAlignment.Left; d.TextAnchoring = OfficeOpenXml.Drawing.eTextAnchoringType.Bottom; var svg = d.ToSvg(); - SaveTextFileToWorkbook("svg\\rect.svg", svg); + SaveTextFileToWorkbook("svg/rect.svg", svg); SaveAndCleanup(p); } } diff --git a/src/EPPlus/Drawing/ExcelPicture.cs b/src/EPPlus/Drawing/ExcelPicture.cs index 1c8d0dfca8..ab32edea01 100644 --- a/src/EPPlus/Drawing/ExcelPicture.cs +++ b/src/EPPlus/Drawing/ExcelPicture.cs @@ -139,10 +139,15 @@ internal ExcelPicture(ExcelDrawings drawings, XmlNode node, ExcelGroupShape shap { container.RelPic = LinkedImageRel; Image = new ExcelImage(this); - //Path.Combine automatically fixes things like "\\" to linux appropriate paths if in linux - //var fixedPath = Path.Combine(new string[] { Path.GetFullPath(LinkedImageRel.TargetUri.GetComponents), "" }); - var fullPath = Path.GetFullPath(LinkedImageRel.TargetUri.LocalPath); - FileInfo ImageFile = new FileInfo(fullPath); + + var intendedPath = LinkedImageRel.TargetUri.OriginalString; + //var localPathOSAgnostic = LinkedImageRel.TargetUri.LocalPath.Replace(@"\\", @"/"); + if (intendedPath.StartsWith("file:///")) + { + intendedPath = intendedPath.Substring("file:///".Length); + } + FileInfo ImageFile = new FileInfo(intendedPath); + LoadImageLinked(ImageFile); } } diff --git a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlExporterBaseInternal.cs b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlExporterBaseInternal.cs index d80afbf29d..2bac89b0b2 100644 --- a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlExporterBaseInternal.cs +++ b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlExporterBaseInternal.cs @@ -28,6 +28,7 @@ Date Author Change using System.IO; using System.Linq; using System.Runtime; +using System.Xml; using static OfficeOpenXml.Export.HtmlExport.ColumnDataTypeManager; namespace OfficeOpenXml.Export.HtmlExport.Exporters.Internal @@ -868,5 +869,17 @@ public void AddTableDataFromCell(ExcelRangeBase cell, string dataType, HTMLEleme contentElement.Content = ValueToTextHandler.GetFormattedText(cell.Value, cell.Worksheet.Workbook, cell.StyleID, false, settings.Culture); } } + + internal string FormatHtmlCssLineEnding(string htmlDocument, string html, string css) + { + if (htmlDocument.Contains("{2}")) + { + return string.Format(htmlDocument, html, css, Environment.NewLine); + } + else + { + return string.Format(htmlDocument, html, css); + } + } } } diff --git a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlRangeExporterAsync.cs b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlRangeExporterAsync.cs index 2466eff035..7ca130a4aa 100644 --- a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlRangeExporterAsync.cs +++ b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlRangeExporterAsync.cs @@ -126,10 +126,11 @@ public async Task RenderHtmlAsync(Stream stream, int rangeIndex, Action GetSinglePageAsync(string htmlDocument = "\r\n\r\n\r\n\r\n\r\n{0}\r\n\r\n") { if (Settings.Minify) htmlDocument = htmlDocument.Replace("\r\n", ""); + if (Settings.Minify) htmlDocument = htmlDocument.Replace("{2}", ""); var html = await GetHtmlStringAsync(); var cssExporter = HtmlExporterFactory.CreateCssExporterAsync(_settings, _ranges, _exporterContext); var css = await cssExporter.GetCssStringAsync(); - return string.Format(htmlDocument, html, css); + return FormatHtmlCssLineEnding(htmlDocument, html, css); } } } diff --git a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlRangeExporterSync.cs b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlRangeExporterSync.cs index acc936d5da..db0b3e355a 100644 --- a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlRangeExporterSync.cs +++ b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlRangeExporterSync.cs @@ -144,10 +144,11 @@ public void RenderHtml(Stream stream, int rangeIndex, Action\r\n{1}\r\n\r\n{0}\r\n\r\n") { if (Settings.Minify) htmlDocument = htmlDocument.Replace("\r\n", ""); + if (Settings.Minify) htmlDocument = htmlDocument.Replace("{2}", ""); var html = GetHtmlString(); var exporter = HtmlExporterFactory.CreateCssExporterSync(_settings, _ranges, _exporterContext); var css = exporter.GetCssString(); - return string.Format(htmlDocument, html, css); + return FormatHtmlCssLineEnding(htmlDocument, html, css); } } } diff --git a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlTableExporterAsync.cs b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlTableExporterAsync.cs index 7d980425cb..87d6cb9e9e 100644 --- a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlTableExporterAsync.cs +++ b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlTableExporterAsync.cs @@ -63,10 +63,11 @@ public async Task RenderHtmlAsync(Stream stream) public async Task GetSinglePageAsync(string htmlDocument = "\r\n\r\n\r\n\r\n\r\n{0}\r\n") { if (Settings.Minify) htmlDocument = htmlDocument.Replace("\r\n", ""); + if (Settings.Minify) htmlDocument = htmlDocument.Replace("{2}", ""); var html = await GetHtmlStringAsync(); var cssExporter = HtmlExporterFactory.CreateCssExporterTableAsync(_tableExportSettings, _table, _exporterContext); var css = await cssExporter.GetCssStringAsync(); - return string.Format(htmlDocument, html, css); + return FormatHtmlCssLineEnding(htmlDocument, html, css); } } } diff --git a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlTableExporterSync.cs b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlTableExporterSync.cs index 69c14d0e33..f68f057163 100644 --- a/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlTableExporterSync.cs +++ b/src/EPPlus/Export/HtmlExport/Exporters/Internal/HtmlTableExporterSync.cs @@ -61,11 +61,11 @@ public void RenderHtml(Stream stream) public string GetSinglePage(string htmlDocument = "\r\n\r\n\r\n\r\n\r\n{0}\r\n") { if (Settings.Minify) htmlDocument = htmlDocument.Replace("\r\n", ""); + if (Settings.Minify) htmlDocument = htmlDocument.Replace("{2}", ""); var html = GetHtmlString(); var cssExporter = HtmlExporterFactory.CreateCssExporterTableSync(_tableExportSettings, _table, _exporterContext); var css = cssExporter.GetCssString(); - return string.Format(htmlDocument, html, css); - + return FormatHtmlCssLineEnding(htmlDocument, html, css); } } } diff --git a/src/EPPlus/Export/HtmlExport/Interfaces/IExcelHtmlRangeExporter.cs b/src/EPPlus/Export/HtmlExport/Interfaces/IExcelHtmlRangeExporter.cs index cdfaf56cd2..8cf85d522a 100644 --- a/src/EPPlus/Export/HtmlExport/Interfaces/IExcelHtmlRangeExporter.cs +++ b/src/EPPlus/Export/HtmlExport/Interfaces/IExcelHtmlRangeExporter.cs @@ -95,7 +95,7 @@ public interface IExcelHtmlRangeExporter /// /// The html string where to insert the html and the css. The Html will be inserted in string parameter {0} and the Css will be inserted in parameter {1}. /// The html document - string GetSinglePage(string htmlDocument = "\r\n\r\n\r\n\r\n\r\n{0}\r\n\r\n"); + string GetSinglePage(string htmlDocument = "{2}{2}{2}{2}{2}{0}{2}{2}"); /// /// Exports an to a html string @@ -163,7 +163,7 @@ public interface IExcelHtmlRangeExporter /// /// The html string where to insert the html and the css. The Html will be inserted in string parameter {0} and the Css will be inserted in parameter {1}. /// The html document - Task GetSinglePageAsync(string htmlDocument = "\r\n\r\n\r\n\r\n\r\n{0}\r\n\r\n"); + Task GetSinglePageAsync(string htmlDocument = "{2}{2}{2}{2}{2}{0}{2}{2}"); /// /// Exports the css part of an to a html string diff --git a/src/EPPlusTest/Core/LoadSaveTests.cs b/src/EPPlusTest/Core/LoadSaveTests.cs index 5733ed1e2f..fcf28198cf 100644 --- a/src/EPPlusTest/Core/LoadSaveTests.cs +++ b/src/EPPlusTest/Core/LoadSaveTests.cs @@ -181,8 +181,8 @@ public void SaveToText_VerifyWithApostrophes() } //Assert - var expectedText = "\"dog 1\"\"\"\"\"\"\",\"dog 2\"\"\"\"\"\"\",\"dog 3\"\"\"\"\"\"\"\r\n" - + "\"cat 1\",\"cat 2\",\"cat 3\"\"\"\"\"\r\n" + var expectedText = $"\"dog 1\"\"\"\"\"\"\",\"dog 2\"\"\"\"\"\"\",\"dog 3\"\"\"\"\"\"\"{Environment.NewLine}" + + $"\"cat 1\",\"cat 2\",\"cat 3\"\"\"\"\"{Environment.NewLine}" + "\"mouse 1\"\"\"\"\",\"mouse 2\"\"\"\"\",\"mouse 3\"\"\"\"\""; Assert.AreEqual(expectedText, result); diff --git a/src/EPPlusTest/Core/Range/RangeToTextTests.cs b/src/EPPlusTest/Core/Range/RangeToTextTests.cs index ddf84eecb2..0afdef1e53 100644 --- a/src/EPPlusTest/Core/Range/RangeToTextTests.cs +++ b/src/EPPlusTest/Core/Range/RangeToTextTests.cs @@ -513,7 +513,7 @@ public void ToTextHandleRichTextCells() var text = ws.Cells["A1:A2"].ToText(); //Assert - Assert.AreEqual("RichText 1\r\nRichText 2", text); + Assert.AreEqual($"RichText 1{Environment.NewLine}RichText 2", text); Assert.AreEqual(3, ws.Cells["A2"].RichText.Count); Assert.AreEqual(Color.Red.ToArgb(), ws.Cells["A2"].RichText[1].Color.ToArgb()); } diff --git a/src/EPPlusTest/Drawing/PictureTests.cs b/src/EPPlusTest/Drawing/PictureTests.cs index a8afcbdad6..8457094b24 100644 --- a/src/EPPlusTest/Drawing/PictureTests.cs +++ b/src/EPPlusTest/Drawing/PictureTests.cs @@ -187,7 +187,7 @@ public void AddPictureWithIllegalCharsShouldFail() { var sheet = package.Workbook.Worksheets.Add("emptyWS"); - var pic = sheet.Drawings.AddPicture("ImageName", "testafhkai/[/\\|stuff", PictureLocation.Link); + var pic = sheet.Drawings.AddPicture("ImageName", "testafhkai/[/\\|stuff'\0'", PictureLocation.Link); SaveAndCleanup(package); } @@ -200,7 +200,7 @@ public void AddPictureWithFaultyPathShouldFail() { var sheet = package.Workbook.Worksheets.Add("emptyWS"); - var pic = sheet.Drawings.AddPicture("ImageName", "C:\\temp\\\test???", PictureLocation.Link); + var pic = sheet.Drawings.AddPicture("ImageName", "C:\\temp\\\test???'\0'", PictureLocation.Link); SaveAndCleanup(package); } @@ -214,7 +214,7 @@ public void AddPictureWithFaultyPathShouldFail2() { var sheet = package.Workbook.Worksheets.Add("emptyWS"); - var pic = sheet.Drawings.AddPicture("ImageName", "C:\\temp\\test???", PictureLocation.Link); + var pic = sheet.Drawings.AddPicture("ImageName", "C:\\temp\\test???'\0'", PictureLocation.Link); SaveAndCleanup(package); } @@ -228,7 +228,7 @@ public void AddPictureWithIllegalCharsAndHyperlinkShouldFail() { var sheet = package.Workbook.Worksheets.Add("emptyWS"); - var pic = sheet.Drawings.AddPicture("ImageName", "testafhkai/[/\\|stuff", new ExcelHyperLink("https://www.google.com/"), PictureLocation.Link); + var pic = sheet.Drawings.AddPicture("ImageName", "testafhkai/[/\\|stuff'\0'", new ExcelHyperLink("https://www.google.com/"), PictureLocation.Link); SaveAndCleanup(package); } diff --git a/src/EPPlusTest/Export/HtmlExport/HtmlConditionalFormattingTest.cs b/src/EPPlusTest/Export/HtmlExport/HtmlConditionalFormattingTest.cs index 1df2113a14..841d6ec5ab 100644 --- a/src/EPPlusTest/Export/HtmlExport/HtmlConditionalFormattingTest.cs +++ b/src/EPPlusTest/Export/HtmlExport/HtmlConditionalFormattingTest.cs @@ -1,14 +1,17 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using OfficeOpenXml; +using OfficeOpenXml.ConditionalFormatting; +using OfficeOpenXml.Drawing; +using OfficeOpenXml.Drawing.OleObject.Structures; +using OfficeOpenXml.Export.HtmlExport; using OfficeOpenXml.Export.HtmlExport.Parsers; using OfficeOpenXml.Export.HtmlExport.Settings; -using OfficeOpenXml.Export.HtmlExport; -using OfficeOpenXml.ConditionalFormatting; +using System; +using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Linq; using System.Text; -using OfficeOpenXml.Drawing; -using System; namespace EPPlusTest.Export.HtmlExport { @@ -99,6 +102,8 @@ public void ExportingHtmlCFsWithThemeColor() sheet.Calculate(); + var firstVal = sheet.Cells["A1"].Value; + var twoColor = range.ConditionalFormatting.AddTwoColorScale(); var threeColor = range2.ConditionalFormatting.AddThreeColorScale(); var databar = range3.ConditionalFormatting.AddDatabar(Color.Aqua); @@ -137,18 +142,41 @@ public void ExportingHtmlCFsWithThemeColor() } var expected = "\r\n\r\n\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
11-9
22-8
33-7
44-6
55-5
66-4
77-3
88-2
99-1
10100
11111
12122
13133
14144
15155
16166
17177
18188
19199
202010
212111
222212
232313
242414
252515
262616
272717
282818
292919
303020
\r\n\r\n"; string finalExpected = ""; - //if ("\r\n" != Environment.NewLine) - //{ - // finalExpected = expected.Replace("\r\n", Environment.NewLine); - //} - //else - //{ - // finalExpected = expected; - //} - - - - Assert.AreEqual(expected, result); + if ("\r\n" != Environment.NewLine) + { + finalExpected = expected.Replace("\r\n", Environment.NewLine); + } + else + { + finalExpected = expected; + } + + var expectedTxt = GetOutputFile("", "exptectedText.txt"); + var resTxt = GetOutputFile("", "result.txt"); + + var rCount = finalExpected.Count(x => x == '\r'); + var rCountResult = result.Count(x => x == '\r'); + + Assert.AreEqual(rCount, rCountResult); + + var nCount = finalExpected.Count(x => x == '\n'); + var nCountResult = result.Count(x => x == '\n'); + + Assert.AreEqual(nCount, nCount); + + var expectedStrings = finalExpected.Split($"\r\n".ToCharArray()).ToList(); + var resultStrings = result.Split($"\r\n".ToCharArray()).ToList(); + + List differingStrings = new(); + + if (expectedStrings.Count() > resultStrings.Count()) + differingStrings = resultStrings.Except(expectedStrings).ToList(); + else + differingStrings = expectedStrings.Except(resultStrings).ToList(); + + + Assert.AreEqual(finalExpected, result); + Assert.AreEqual(0, differingStrings.Count); SaveAndCleanup(p); } diff --git a/src/EPPlusTest/Issues/WorksheetIssues.cs b/src/EPPlusTest/Issues/WorksheetIssues.cs index d95a6d2e4b..80a32a67be 100644 --- a/src/EPPlusTest/Issues/WorksheetIssues.cs +++ b/src/EPPlusTest/Issues/WorksheetIssues.cs @@ -853,6 +853,14 @@ public void s843() [TestMethod] public void i1951() { + var isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT && + Environment.OSVersion.Version.Major >= 6 && + Environment.OSVersion.Version.Minor >= 0; + if (isWindows == false) + { + Assert.Inconclusive("This test is only meant to be run on Windows OS"); + } + using (var p = OpenPackage("I1951.xlsx", true)) { var ws = p.Workbook.Worksheets.Add("GenericTM"); diff --git a/src/EPPlusTest/TestBase.cs b/src/EPPlusTest/TestBase.cs index 5d853f9a3e..c614431dda 100644 --- a/src/EPPlusTest/TestBase.cs +++ b/src/EPPlusTest/TestBase.cs @@ -472,6 +472,9 @@ protected static ExcelShape TryGetShape(ExcelPackage pck, string wsName) protected static FileInfo GetResourceFile(string fileName) { string path = AppContext.BaseDirectory; + //Trim start and end separators so not double-added below (extra important on linux) + path = path.TrimEnd(new char[] { Path.DirectorySeparatorChar }); + while (!Directory.Exists(path + $"{Path.DirectorySeparatorChar}Resources") && path.Length > 4) { path = new DirectoryInfo(path + $"{Path.DirectorySeparatorChar}..").FullName;