首页 > 解决方案 > 具有纯色填充颜色的 C# EPPlus 数据栏条件格式

问题描述

我正在生成包含几个百分比数据列的 Excel 报告。由于报告用于演示目的,我希望通过使用实心填充的数据栏格式化百分比数据来使它们看起来不错。不知何故,这被证明是非常困难的,因为在 EPPlus 中没有直接设置数据栏的实体填充,但尽管如此,我已经得出了这篇文章中的答案:

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

但是,无论我多么努力地尝试为我的应用程序编辑代码,我只有一列最终以实心填充而其余为渐变。即使我将问题中的节点更改为节点列表,如下所示:

        var cfNodes = xdoc.SelectNodes("/default:worksheet/default:conditionalFormatting/default:cfRule", nsm);
        foreach(XmlNode cfNode in cfNodes)
        {
            cfNode.AppendChild(extLstCf);
        }

以及工作表元素:

        var wsNodes = xdoc.SelectNodes("/default:worksheet", nsm);
        foreach(XmlElement wsNode in wsNodes)
        {
            wsNode.AppendChild(extLstWs);
        }

我还尝试使用 xml 更改<sqref>参数,但这仍然没有涵盖我所有的数据栏列。我认为必须有一些我可以在 xml 中更改以完成我想要的东西,但我不知道要寻找什么......

标签: c#excelxmlepplusconditional-formatting

解决方案


好的,我花了几天时间,但我终于弄明白了。可能有一种更简单的方法可以做到这一点,但到目前为止,这就是我让它为我工作的方式:

工作表 xml 扩展列表节点需要附加到工作表级别节点,其中包括工作表包含的数字数据栏元素,并且每个元素都需要gradient = 0用于实心填充 I。例如,我的工作表包含两个数据栏,所以我的看起来像这样:

        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>100</xm:f>
                                        </x14:cfvo>
                                        <x14:negativeFillColor rgb=""FFFF0000""/><x14:axisColor rgb=""FF000000""/>
                                        </x14:dataBar>
                                    </x14:cfRule>
                                    <xm:sqref>A1:A20</xm:sqref>
                                    </x14:conditionalFormatting>
                                    <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>200</xm:f>
                                            </x14:cfvo><x14:negativeFillColor rgb=""FFFF0000""/>
                                            <x14:axisColor rgb=""FF000000""/>
                                        </x14:dataBar>
                                        </x14:cfRule>
                                        <xm:sqref>B1:B20</xm:sqref>
                                    </x14:conditionalFormatting>
                                    </x14:conditionalFormattings>
                                </ext>";
        var wsNode = xdoc.SelectSingleNode("/default:worksheet", nsm);
        wsNode.AppendChild(extLstWs);

请注意我是如何在其中获得两个子节点的<x14:conditionalFormattings>,每个数据栏一个。

其次,需要在节点下附加另一个条件格式规则节点的扩展列表,<cfRule>每个数据栏也需要一个扩展列表。我能够使用 foreach 循环在我的工作表中查找所有数据栏,并将相同的 xml 附加到每个数据栏,如下所示:

        var cfNodes = xdoc.SelectNodes("/default:worksheet/default:conditionalFormatting/default:cfRule", nsm);
        foreach (XmlNode cfnode in cfNodes)
        {
            var extLstCfNormal = xdoc.CreateNode(XmlNodeType.Element, "extLst", xdoc.DocumentElement.NamespaceURI);
            extLstCfNormal.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>";

            cfnode.AppendChild(extLstCfNormal);
        }

完成上述操作后,我终于能够用实心填充显示我的所有数据栏。


推荐阅读