如何使用EPPlus编程设置单元格颜色?

31

我想知道是否可以使用epplus以编程方式设置单元格颜色?

我从SQL存储过程中加载数据,它运行良好,但我的用户希望包含“年度休假”这些单词的单元格具有浅黄色的背景颜色,而不是默认的白色。有没有办法做到这一点?也许通过迭代Datatable?下面是相关代码:

public void ExportTableData(DataTable dtdata)
{
    //Using EPPLUS to export Spreadsheets
    ExcelPackage pck = new ExcelPackage();
    var ws = pck.Workbook.Worksheets.Add("Availability list");

    ws.Cells["A1"].LoadFromDataTable(dtdata, true);

    ws.Cells["A1:G1"].Style.Font.Bold = true;
    ws.Cells["A1:G1"].Style.Font.UnderLine = true;

    //change cell color depending on the text input from stored proc?
    if (dtdata.Rows[4].ToString() == "Annual Leave")
    {
        ws.Cells["E1"].Style.Fill.PatternType = ExcelFillStyle.Solid;
        ws.Cells["E1"].Style.Fill.BackgroundColor.SetColor(Color.LightYellow);
    }

    pck.SaveAs(Response.OutputStream);
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    Response.AddHeader("content-disposition", "attachment;  filename=Availability.xlsx");
    Response.End();
}

那么你这里有什么问题没有解决?抱歉,我没有看到明确的问题。 - workabyte
基本上,我有一列可以包含“年假”,“可用”,“病假”,“退休”等数据,根据这些文本,我想通过编程更改包含单元格的颜色。例如,如果它说“年假”,则为浅黄色单元格,每当包含“可用”时为绿色单元格,依此类推。目前它没有改变颜色。 - wubblyjuggly
你所拥有的东西不起作用吗?它在做什么?我完全理解你想要的结果,但是有什么阻止你实现它呢? - workabyte
我认为基本上是从DataTable获取值。当行包含“年假”值时,我希望它更改单元格颜色。它可以编译通过,但实际上并没有做任何事情。 - wubblyjuggly
3
你提供的单元格中的值是第一行的第五个单元格。你需要迭代每一行查找该值,并在找到时更改单元格地址。 - krillgar
3个回答

34

检查你的线路:

if (dtdata.Rows[4].ToString() == "Annual Leave")
如果这是一个标准的.net表格,.ToString() 会不会评估为 "System.Data.DataRow"?此外,在循环行数后,ws.Cells["E1"] 需要针对每个单元格进行调整(基本上就是 krillgar 所说的)。
类似这样:
[TestMethod]
public void Cell_Color_Background_Test()
{
    //https://dev59.com/-V4b5IYBdhLWcg3wzUUp

    //Throw in some data
    var dtdata = new DataTable("tblData");
    dtdata.Columns.Add(new DataColumn("Col1", typeof(string)));
    dtdata.Columns.Add(new DataColumn("Col2", typeof(int)));
    dtdata.Columns.Add(new DataColumn("Col3", typeof(int)));

    for (var i = 0; i < 20; i++)
    {
        var row = dtdata.NewRow();
        row["Col1"] = "Available";
        row["Col2"] = i * 10;
        row["Col3"] = i * 100;
        dtdata.Rows.Add(row);
    }
    //throw in one cell that triggers
    dtdata.Rows[10]["Col1"] = "Annual leave";

    var existingFile = new FileInfo(@"c:\temp\temp.xlsx");
    if (existingFile.Exists)
        existingFile.Delete();

    using (var pck = new ExcelPackage(existingFile))
    {
        //Using EPPLUS to export Spreadsheets
        var ws = pck.Workbook.Worksheets.Add("Availability list");

        ws.Cells["A1"].LoadFromDataTable(dtdata, true);

        ws.Cells["A1:G1"].Style.Font.Bold = true;
        ws.Cells["A1:G1"].Style.Font.UnderLine = true;

        //change cell color depending on the text input from stored proc?
        //if (dtdata.Rows[4].ToString() == "Annual Leave")
        for (var i = 0; i < dtdata.Rows.Count; i++)
        {
            if (dtdata.Rows[i]["Col1"].ToString() == "Annual leave")
            {
                ws.Cells[i + 1, 1].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                ws.Cells[i + 1, 1].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightYellow);
            }
        }

        pck.Save();
    }

1
快了!出现了“样式范围无效:E0”的错误,因为使用循环从0开始。需要将样式下移2个单元格,以考虑Excel中的标题和使用零基索引。 - wubblyjuggly
@wubblyjuggly 很好。是的,0和1索引非常容易被忘记 - 这就是上面的“+ 1”所做的。很高兴它对你有用。 - Ernie S

10

谢谢Ernie! 我稍微修改了一下,以便在Excel中包含我的标题,并确保代码不从E1开始。我使用ws.cells [i + 2, 5]来实现这一点。干杯!

   for (var i = 0; i < dtdata.Rows.Count; i++)
        {

            if (dtdata.Rows[i]["typeName"].ToString() == "Annual Leave")
            {
                ws.Cells[i + 2, 5].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                ws.Cells[i + 2, 5].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightYellow);
            }

            else if (dtdata.Rows[i]["typeName"].ToString() == "Available")
            {
                ws.Cells[i + 2, 5].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                ws.Cells[i + 2, 5].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGreen);
            }
            else
            {
                ws.Cells[i + 2, 5].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                ws.Cells[i + 2, 5].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.White);
            }
        }

0

你可以尝试在EPPlus中使用条件格式选项

这里是他们的示例

这里还有一个SO帖子,其中有其他人使用了此选项

通常使用链接作为答案不是我的风格,但没有理由重新发明轮子,如果EPP示例消失了,我猜他们也会消失,如果SO示例消失了,那么我猜这个答案也会消失。

希望能帮到你


链接的问题在于它们会停止工作,就像你的一样。 - Roger C S Wernersson
1
这就是为什么我链接到了包含代码的SO答案,但链接本身仍然有效。 - workabyte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接