Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/EPPlus/Style/Dxf/DxfStyleHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ private static void UpdateConditionalFormatting(ExcelWorksheet ws, ExcelStyleCol
{
foreach (var cf in ws.ConditionalFormatting)
{
if (cf.Style.HasValue)
//If at least one border exists then a dxf style for the border must be added even if the value for that border is empty
//(Thus meaning HasValue is false)
if (cf.Style.HasValue || cf.Style.Border != null && cf.Style.Border.AtLeastOneBorderExists())
{
var standardDxfStyle = cf.Style.ToDxfStyle();

Expand All @@ -228,11 +230,9 @@ private static void UpdateConditionalFormatting(ExcelWorksheet ws, ExcelStyleCol
{
((ExcelConditionalFormattingRule)cf).DxfId = ix;
cf.Style.DxfId = ix;
//cf.Style.DxfId = ix;
}
}
}
//var num = dxfs._list[129];
}
internal static void CopyDxfStylesTable(ExcelTable tblFrom, ExcelTable tblTo)
{
Expand Down
31 changes: 27 additions & 4 deletions src/EPPlus/Style/Dxf/ExcelDxfBorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,36 @@ internal override DxfStyleBase Clone()
Horizontal = (ExcelDxfBorderItem)Horizontal.Clone(),
};
}

private bool BorderItemExists(ExcelDxfBorderItem bi)
{
if (bi.Style != null)
{
return true;
}
return false;
}

internal bool AtLeastOneBorderExists()
{
if (BorderItemExists(Left)) return true;
if (BorderItemExists(Right)) return true;
if (BorderItemExists(Bottom)) return true;
if (BorderItemExists(Top)) return true;
if (BorderItemExists(Vertical)) return true;
if (BorderItemExists(Horizontal)) return true;

return false;
}

internal override void SetValuesFromXml(XmlHelper helper)
{
if (helper.ExistsNode("d:border"))
{
Left = GetBorderItem(helper, "d:border/d:left", eStyleClass.BorderLeft);
Right = GetBorderItem(helper, "d:border/d:right", eStyleClass.BorderLeft);
Bottom = GetBorderItem(helper, "d:border/d:bottom", eStyleClass.BorderLeft);
Top = GetBorderItem(helper, "d:border/d:top", eStyleClass.BorderLeft);
Right = GetBorderItem(helper, "d:border/d:right", eStyleClass.BorderRight);
Bottom = GetBorderItem(helper, "d:border/d:bottom", eStyleClass.BorderBottom);
Top = GetBorderItem(helper, "d:border/d:top", eStyleClass.BorderTop);
Vertical = GetBorderItem(helper, "d:border/d:vertical", eStyleClass.Border);
Horizontal = GetBorderItem(helper, "d:border/d:horizontal", eStyleClass.Border);
}
Expand All @@ -224,7 +246,8 @@ private ExcelDxfBorderItem GetBorderItem(XmlHelper helper, string path, eStyleCl
if (exists)
{
var style = helper.GetXmlNodeString(path + "/@style");
bi.Style = GetBorderStyleEnum(style);
//When exists and border has no style the CT_BorderPr\ST_BorderStyle node defaults to BorderNone if the node exists even when empty
bi.Style = GetBorderStyleEnum(style) ?? ExcelBorderStyle.None;
bi.Color = GetColor(helper, path + "/d:color", styleClass);
}
return bi;
Expand Down
2 changes: 1 addition & 1 deletion src/EPPlus/Style/Dxf/ExcelDxfStyleLimitedFont.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ internal override void CreateNodes(XmlHelper helper, string path)
{
if (Font.HasValue) Font.CreateNodes(helper, "d:font");
if (Fill.HasValue) Fill.CreateNodes(helper, "d:fill");
if (Border.HasValue) Border.CreateNodes(helper, "d:border");
if (Border.HasValue || Border.AtLeastOneBorderExists()) Border.CreateNodes(helper, "d:border");
}
/// <summary>
/// If the object has any properties set
Expand Down
123 changes: 123 additions & 0 deletions src/EPPlusTest/Issues/ConditionalFormattingIssues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

namespace EPPlusTest.Issues
Expand Down Expand Up @@ -262,6 +264,127 @@ public void RoundTrip_ExtIconSetWithNumericFormulaCfvo_DoesNotThrow()
}
}


[TestMethod]
public void ReadEppGeneratedCFBorderStylesCorrectly()
{
using (var p = OpenPackage("i2488_EppGen.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("readBorderNone");

var notEqual = ws.Cells["C1:C5"].ConditionalFormatting.AddNotEqual();

notEqual.Formula = "1";

ws.Cells["D5"].Style.Border.Left.Style = ExcelBorderStyle.None;

//Set a borderstyle to thick so that Conditional Formatting can then Set it to None
ws.Cells["C2"].Style.Border.Left.Style = ExcelBorderStyle.Thick;
ws.Cells["C2"].Style.Border.Top.Style = ExcelBorderStyle.Thick;
ws.Cells["C2"].Style.Border.Right.Style = ExcelBorderStyle.Thick;
ws.Cells["C2"].Style.Border.Bottom.Style = ExcelBorderStyle.Thick;

notEqual.Style.Border.Left.Style = ExcelBorderStyle.None;
notEqual.Style.Border.Top.Style = ExcelBorderStyle.None;
notEqual.Style.Border.Right.Style = ExcelBorderStyle.None;
notEqual.Style.Border.Bottom.Style = ExcelBorderStyle.None;

SaveAndCleanup(p);
}
using (var p = OpenPackage("i2488_EppGen.xlsx", false))
{
var ws = p.Workbook.Worksheets[0];
var cfs = ws.Cells["C1:C5"].ConditionalFormatting.GetConditionalFormattings();

var rightStyle = cfs[0].Style.Border.Right.Style;
Assert.AreEqual(ExcelBorderStyle.None, ws.Cells["D5"].Style.Border.Left.Style);
//Assert that we can read borderStyle None. This is different from NoNode and the same as an Empty border node
Assert.AreEqual(ExcelBorderStyle.None, cfs[0].Style.Border.Right.Style);
Assert.AreEqual(ExcelBorderStyle.None, cfs[0].Style.Border.Left.Style);
Assert.AreEqual(ExcelBorderStyle.None, cfs[0].Style.Border.Top.Style);
Assert.AreEqual(ExcelBorderStyle.None, cfs[0].Style.Border.Bottom.Style);
}
}

/// <summary>
/// Epplus did not write out ExcelBorderStyle.None correctly into DXF styles
/// Causing Cell-Styling to be applied instead of the conditionallyFormatted "None" style
/// </summary>
[TestMethod]
public void CopyingIssue2488_ActualCase()
{
string expectedId = "";
var fi = GetOutputFile("", "i2488_out.xlsx");
var copiedName = "";

using (var p = OpenTemplatePackage("i2488.xlsx"))
{
var wkbook = p.Workbook;
var wkSheet = wkbook.Worksheets[0];

var conditionalFormatting = wkSheet.Cells["S15"].ConditionalFormatting.GetConditionalFormattings().First(cf => cf.Address.Address == "S7:Y22");
var dxfId = conditionalFormatting.DxfId;
expectedId = conditionalFormatting.Style.ToDxfStyle().Id;
Assert.AreEqual(expectedId, wkbook.Styles.Dxfs[dxfId].Id);
var sheetName = wkSheet.Name;
var copyCount = 1;

copiedName = $"{sheetName}_{1}";

for (int i = 1; i <= copyCount; i++)
{
p.Workbook.Worksheets.Copy(
wkSheet.Name, $"{sheetName}_{i}");
}

wkSheet = wkbook.Worksheets[1];
sheetName = wkbook.Worksheets[1].Name;

for (int i = 1; i <= copyCount; i++)
{
p.Workbook.Worksheets.Copy(
wkSheet.Name, $"{sheetName}_{i}");
}
p.SaveAs(fi);
}
using (var p = OpenPackage(fi.Name, false))
{
var wkbook = p.Workbook;
var wkSheet = wkbook.Worksheets[copiedName];

var conditionalFormatting = wkSheet.Cells["S15"].ConditionalFormatting.GetConditionalFormattings().First(cf => cf.Address.Address == "S7:Y22");
Assert.AreEqual(expectedId, conditionalFormatting.Style.ToDxfStyle().Id);
}
}

[TestMethod]
public void CopyingIssue2488_StyleRead()
{
string expectedId = "";
var fi = GetOutputFile("", "i2488_Read_out.xlsx");

using (var p = OpenTemplatePackage("i2488.xlsx"))
{
var wkbook = p.Workbook;
var wkSheet = wkbook.Worksheets[0];

var conditionalFormatting = wkSheet.Cells["S15"].ConditionalFormatting.GetConditionalFormattings().First(cf=> cf.Address.Address == "S7:Y22");
var dxfId = conditionalFormatting.DxfId;
expectedId = conditionalFormatting.Style.ToDxfStyle().Id;
Assert.AreEqual(expectedId, wkbook.Styles.Dxfs[dxfId].Id);
p.SaveAs(fi);
}

using (var p = OpenPackage(fi.Name, false))
{
var wkbook = p.Workbook;
var wkSheet = wkbook.Worksheets[0];

var conditionalFormatting = wkSheet.Cells["S15"].ConditionalFormatting.GetConditionalFormattings().First(cf => cf.Address.Address == "S7:Y22");
Assert.AreEqual(expectedId, conditionalFormatting.Style.ToDxfStyle().Id);
}
}

[TestMethod]
public void RoundTrip_RegularIconSetWithNumericFormulaCfvo_DoesNotThrow()
{
Expand Down
Loading