代码之家  ›  专栏  ›  技术社区  ›  outofmind codeape

如何在ClosedXML中使用渐变填充(GradientFill)

  •  6
  • outofmind codeape  · 技术社区  · 9 年前

    我正在开发一个C#/ASP。NET web对象,并希望进行Excel导出。首先,我找到了OpenXML,迈出了一些第一步,但它确实很难使用。现在,我正在使用ClosedXML,到目前为止,这让我松了一口气。

    我想到的问题是在表格单元格上使用渐变填充……正常填充没有问题,比如

    worksheet.Cell(1,1).Style.Fill.SetBackgroundColor(XLColor.Red);
    

    或具有以下模式

    worksheet.Cell(1,1).Style.Fill.PatternType = XLFillPatternValues.LightHorizontal;
    worksheet.Cell(1,1).Style.Fill.PatternColor = XLColor.Green;
    worksheet.Cell(1,1).Style.Fill.PatternBackgroundColor = XLColor.White;
    

    但如何进行渐变填充?据我所知,ClosedXML是基于OpenXML SDK构建的,因此应该可以执行GradientFill——类似于(我还无法测试)

    GradientFill gFillEx = new GradientFill();
    GradientStop gStop1st = new GradientStop();
    gStop1st.Position = 0;
    gStop1st.Color = new Color { Rgb = HexBinaryValue.FromString("00FF00") };
    GradientStop gStop2nd = new GradientStop();
    gStop2nd.Position = 1;
    gStop2nd.Color = new Color { Rgb = HexBinaryValue.FromString("FFFFFF") };
    gFillEx.InsertAt<GradientStop>(gStop1st, 0);
    gFillEx.InsertAt<GradientStop>(gStop2nd, 1);
    

    但如何继续-如何将此gFillEx设置为单元格的填充样式?我也不介意使用样式中的xml。xml文件直接放在这里的某个地方-如果我只知道放在哪里。

    有什么提示或有用的想法吗?谢谢

    1 回复  |  直到 9 年前
        1
  •  2
  •   outofmind codeape    9 年前

    在ClosedXML不知道GradientFill之后,由于我没有找到在ClosedXML中操纵OpenXML的WorkbookStylesPart的方法,我最终采用了以下解决方法

    首先在内存流中生成.xlsx

    public ActionResult XLSX()
    {
      System.IO.Stream spreadsheetStream = new System.IO.MemoryStream();
      XLWorkbook workbook = new XLWorkbook();
      IXLWorksheet worksheet = workbook.Worksheets.Add("GradientFillExample");
      worksheet.Cell(1, 1).SetValue("example").Style.Fill.SetBackgroundColor(XLColor.FromHtml("#08F47B")); // use some unique color
      workbook.SaveAs(spreadsheetStream);
    

    我们的想法是使用一种独特的填充颜色-我们将用我们想要的渐变填充替换WorkbookStylesPart中的填充…所以我们再次使用OpenXML打开内存流(使用内存流,我们不必关心临时文件)并导航到样式表

      SpreadsheetDocument package = SpreadsheetDocument.Open(spreadsheetStream, true);
      WorkbookPart wbPart = package.GetPartsOfType<WorkbookPart>().FirstOrDefault();
      WorkbookStylesPart wbStylePart = wbPart.GetPartsOfType<WorkbookStylesPart>().FirstOrDefault();
      Stylesheet stylesheet = wbStylePart.Stylesheet; // all three are not null - check if you want
    

    由于始终有两种默认填充样式,样式表从不为空。现在,我们可以在样式表的填充中搜索我们的独特颜色,并用渐变填充替换该填充

      OpenXmlElement oldFill = stylesheet.Fills.FirstOrDefault(f => f.OuterXml.Contains("08F47B")); // find the fill that uses your unique color
      if (oldFill != null) // maybe you generate the .xlsx and the "gradient fill" is not always present
      {
        GradientFill gradientFill = new GradientFill() { Degree = 0 };
        gradientFill.Append(new GradientStop() { Position = 0D, Color = new Color() { Rgb = "FF00FF00" } });
        gradientFill.Append(new GradientStop() { Position = 1D, Color = new Color() { Rgb = "FFFFFFFF" } });
        oldFill.ReplaceChild(gradientFill, oldFill.FirstChild); // inside the fill replace the patternFill with your gradientFill
      }
      package.Close();
    

    最后,我们可以关闭内存流并将其呈现给下载。。。

      spreadsheetStream.Position = 0;
      return new FileStreamResult(spreadsheetStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = "gradfillexample.xlsx" };
    }
    

    对于测试,只需将该操作放入控制器即可。别忘了你需要一些用法:

    using DocumentFormat.OpenXml;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Spreadsheet;
    using ClosedXML.Excel;
    

    有趣的是:你还可以使用0、90、180、270以外的其他角度(会产生某种对角线渐变),甚至可以使用多停止渐变,所以类似这样的东西也是可能的

        GradientFill gradientFill = new GradientFill() { Degree = 354 };
        gradientFill.Append(new GradientStop() { Position = 0D, Color = new Color() { Rgb = "FF00FF00" } });
        gradientFill.Append(new GradientStop() { Position = 0.49D, Color = new Color() { Rgb = "FF00FF00" } });
        gradientFill.Append(new GradientStop() { Position = 0.51D, Color = new Color() { Rgb = "FFFFFFFF" } });
        gradientFill.Append(new GradientStop() { Position = 1D, Color = new Color() { Rgb = "FFFFFFFF" } });
    

    虽然Excel(和Excel Viewer)正确显示了这一点(度数值对应于一个方形单元格,因此可能会拉伸),但您不能在Excel中编辑度数值或多点渐变,不过,这对于生成的工作表来说很好。