如何在ClosedXML

时间:2015-07-17 11:07:09

标签: c# openxml-sdk closedxml

我正在开发一个C#/ ASP.NET网页,并希望进行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;

但是如何做GradientFill?据我所知,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设置为单元格的填充样式?我也不介意在这里直接使用styles.xml文件中的xml - 如果我只知道放在哪里。

任何提示或有用的想法?感谢。

1 个答案:

答案 0 :(得分:2)

在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中编辑度数值或多站点渐变,但是,它是很适合生成的床单。