c# - 实体数据栏和数据栏最小值的手动版本和编码版本之间的外观不一致

标签 c# excel conditional-formatting epplus

我正在尝试在 EPPlus 4.0.4 中创建实体数据条,但遇到了两个问题。

  • 首先,我一直无法弄清楚如何创建纯色填充颜色。
  • 其次,至少对于较小的值,条形图未按我预期的方式显示。

下面的屏幕截图说明了这两个问题。在这两种情况下,期望的结果都是我在 Excel 中手动添加的数据栏:

enter image description here

这是我目前使用的代码:

var bars = doc.ConditionalFormatting.AddDatabar(range, Color.FromArgb(99,195,132));

bars.HighValue.Type = eExcelConditionalFormattingValueObjectType.Num;
bars.LowValue.Type = eExcelConditionalFormattingValueObjectType.Num;

bars.HighValue.Value = numResponses; //82
bars.LowValue.Value = 0;

对于纯色,我一直在为 bars.Style.Fill 的不同属性尝试不同的值,但无济于事。如果实现了这一点,我找不到合适的属性就很简单了。

我很难理解第二个问题。如果我在 Excel 中进入“管理规则”,高值和低值设置正确,但我没有发现我可以将它们更改为使它们的外观与手动创建的条形匹配的值。

最佳答案

这是一个扩展列表问题。当进入更复杂的导出时,这会出现很多。条件格式可能是比较难的格式之一,因为其中有很多细微差别,而且这些年来它发生了很大变化。

扩展列表(xml 中的 extLst 标记)是一种包罗万象的桶,OpenOfficeXml 标准可以使用它来添加新功能和格式。在您的情况下,Excel 会填充扩展列表部分以允许扩展的最小/最大限制。 Epplus 不支持这一点,这就是您看到差异的原因。

您最简单的选择就是通过 xml/字符串操作自己注入(inject)它 不漂亮但它完成了工作:

var bars = doc.ConditionalFormatting.AddDatabar(range, Color.FromArgb(99, 195, 132));

bars.HighValue.Type = eExcelConditionalFormattingValueObjectType.Num;
bars.LowValue.Type = eExcelConditionalFormattingValueObjectType.Num;

bars.HighValue.Value = numResponses; //82
bars.LowValue.Value = 0;

//Get reference to the worksheet xml for proper namespace
var xdoc = doc.WorksheetXml;
var nsm = new XmlNamespaceManager(xdoc.NameTable);
nsm.AddNamespace("default", xdoc.DocumentElement.NamespaceURI);

//Create the conditional format extension list entry
var extLstCf = xdoc.CreateNode(XmlNodeType.Element, "extLst", xdoc.DocumentElement.NamespaceURI);
extLstCf.InnerXml = @"<ext uri=""{B025F937-C7B1-47D3-B67F-A62EFF666E3E}"" xmlns:x14=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/main""><x14:id>{3F3F0E19-800E-4C9F-9CAF-1E3CE014ED86}</x14:id></ext>";
var cfNode = xdoc.SelectSingleNode("/default:worksheet/default:conditionalFormatting/default:cfRule", nsm);
cfNode.AppendChild(extLstCf);

//Create the extension list content for the worksheet
var extLstWs = xdoc.CreateNode(XmlNodeType.Element, "extLst", xdoc.DocumentElement.NamespaceURI);
extLstWs.InnerXml = @"<ext uri=""{78C0D931-6437-407d-A8EE-F0AAD7539E65}"" xmlns:x14=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/main""><x14:conditionalFormattings><x14:conditionalFormatting xmlns:xm=""http://schemas.microsoft.com/office/excel/2006/main""><x14:cfRule type=""dataBar"" id=""{3F3F0E19-800E-4C9F-9CAF-1E3CE014ED86}""><x14:dataBar minLength=""0"" maxLength=""100"" gradient=""0""><x14:cfvo type=""num""><xm:f>0</xm:f></x14:cfvo><x14:cfvo type=""num""><xm:f>82</xm:f></x14:cfvo><x14:negativeFillColor rgb=""FFFF0000""/><x14:axisColor rgb=""FF000000""/></x14:dataBar></x14:cfRule><xm:sqref>B2:B11</xm:sqref></x14:conditionalFormatting></x14:conditionalFormattings></ext>";
var wsNode = xdoc.SelectSingleNode("/default:worksheet", nsm);
wsNode.AppendChild(extLstWs);

pck.Save();

请注意 gradient=""0"",它将颜色条设置为纯色而不是渐变,以及最小/最大设置以获得您正在寻找的传播。

一个更“正确”的方法是逐个节点和逐个属性重新创建 xml 对象,这需要一段时间但只需执行一次。

关于c# - 实体数据栏和数据栏最小值的手动版本和编码版本之间的外观不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33541945/

相关文章:

VBA - 带有刻度线和 x 标记的条件格式

excel - 包含来自另一个单元格的值的条件格式文本的公式

c# - 双端优先队列

c# - 返回 json 数据表未收到数据

excel - Excel 表格中的用户表单操作

Excel 数字自定义格式

c# - 如何加快将 DataTable 转储到 Excel 工作表中的速度?

excel - Conditional Formatting,使用公式根据不同的单元格值范围进行格式化

c# - Splitcontainer 中面板的最大高度

c# - 使用 Xamarin Forms,如何在共享代码中创建我的 SQLite 连接?