如何在数据透视表 EPPlus 中应用条件格式

问题描述 投票:0回答:2

我有一个 ASP.NET Mvc 应用程序,它使用 EPPlus 生成 Excel 报告。生成的工作簿中的工作表之一包含数据透视表。我想在数据透视表中应用条件格式来为那些值等于 1 的单元格的背景颜色着色。

以下代码用于创建数据透视表。

var dataRange = _objSheet.Cells[_objSheet.Dimension.Address.ToString()];
_objSheet = outputExcel.Workbook.Worksheets.Add("Pivot");
var ptTable = _objSheet.PivotTables.Add(_objSheet.Cells["A1"], dataRange, "PivotTable");
ptTable.GridDropZones = true;
ptTable.ApplyPatternFormats = true;
ptTable.Compact = false;
ptTable.CompactData = false;
ptTable.Indent = 0;
ptTable.RowGrandTotals = false;
ptTable.ColumnGrandTotals = false;
ptTable.ShowMemberPropertyTips = false;
ptTable.DataOnRows = false;
ptTable.UseAutoFormatting = false;

如何将条件格式应用于数据透视表的范围??

c# excel pivot-table conditional-formatting epplus
2个回答
1
投票

可以完成,但需要对 XML 进行修改,因为 epplus 目前似乎不支持

Pivot
上的
ConditionalFormatting
属性:

https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.conditionalformatting.pivot?view=openxml-2.8.1

因此,如果您有数据透视表并添加格式设置,则可以设置该标志,以便 Excel 将其与工作表中的数据透视表关联起来。 例如:

[TestMethod]
public void Pivot_Table_Conditional_Format()
{
    //https://stackoverflow.com/questions/59359688/how-to-apply-conditional-formatting-in-pivot-table-epplus
    //Throw in some data
    var dt = new DataTable("tblData");
    dt.Columns.AddRange(new[]
    {
        new DataColumn("Group", typeof (string)),
        new DataColumn("MValue", typeof (int)),
        new DataColumn("Month", typeof (int)),
        new DataColumn("String", typeof (object))
    });

    var rnd = new Random();

    for (var i = 0; i < 100; i++)
    {
        var row = dt.NewRow();
        //This adds some randomness to the number of groups that will be created
        row[0] = $"Group {rnd.Next(1, 100)}";
        row[1] = i * rnd.Next(1, 100);

        //This adds randomness to the columns so not guaranteed to be all 12
        row[2] = rnd.Next(1, 12);
        row[3] = Path.GetRandomFileName();

        dt.Rows.Add(row);
    }

    //Create a test file
    var fi = new FileInfo(@"c:\temp\Pivot_Table_Conditional_Format.xlsx");
    if (fi.Exists)
        fi.Delete();

    using (var pck = new ExcelPackage(fi))
    {
        var wsData = pck.Workbook.Worksheets.Add("Data");
        wsData.Cells.LoadFromDataTable(dt, true);

        var wsPivot = pck.Workbook.Worksheets.Add("Pivot");

        var pivotTable1 = wsPivot.PivotTables.Add(
            wsPivot.Cells["A1"]
            , wsData.Cells[1, 1, wsData.Dimension.End.Row, wsData.Dimension.End.Column]
            , "DataPivot"
        );

        pivotTable1.DataFields.Add(pivotTable1.Fields["MValue"]);

        //Grouping will be by the "Group" column
        pivotTable1.RowFields.Add(pivotTable1.Fields["Group"]);

        //Columns will be months
        pivotTable1.ColumnFields.Add(pivotTable1.Fields["Month"]);

        //Set conditional formatting but have to determine the range in the pivot table
        var groups = dt
            .Rows
            .Cast<DataRow>()
            .Select(row => row["Group"])
            .Distinct()
            .ToList();

        var columns = dt
            .Rows
            .Cast<DataRow>()
            .Select(row => row["Month"])
            .Distinct()
            .ToList();

        var colOffset = pivotTable1.FirstDataCol;
        var groupOffset = pivotTable1.FirstDataRow + pivotTable1.FirstHeaderRow;

        var range = new ExcelAddress
        (
            pivotTable1.Address.Start.Row + groupOffset
            , pivotTable1.Address.Start.Column + colOffset
            , groups.Count + groupOffset
            , columns.Count + colOffset
        );

        var cond = wsPivot.ConditionalFormatting.AddGreaterThanOrEqual(range);
        cond.Formula = "100";
        cond.Style.Font.Color.Color = Color.Black;
        cond.Style.Fill.PatternType = ExcelFillStyle.Solid;
        cond.Style.Fill.BackgroundColor.Color = Color.Yellow;

        //Only way to set the pivot table as the target is with XML Hack
        var parent = cond.Node.ParentNode;
        var doc = parent.OwnerDocument;

        //Need an attribute "pivot" with a value of "1" (true)
        //https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.conditionalformatting.pivot?view=openxml-2.8.1
        var att = doc.CreateAttribute("pivot", doc.NamespaceURI);
        att.Value = "1";
        parent.Attributes.Append(att);

        pck.Save();
    }
}

给出了这个:

enter image description here


0
投票

我们升级到了 epplus 7,Node 不再可以通过条件格式化接口访问,但这些接口有一个新的布尔属性,称为数据透视表。设置为 true 时,将应用您的条件格式。

© www.soinside.com 2019 - 2024. All rights reserved.