C#OpenXML – 仅用于Excel导出的特定单元格样式

我相对较新的C#。 下面是我目前的代码。 它适用于将DataTable转换为Excel格式可导出的Byte数组。 我首先在填充的DataSet上调用Create(),将其存储在Byte []中,然后由DataSet中的数据填充。 请注意,下面的所有代码完美工作,我正在寻找添加一些样式到导出的Excel文件根据特定的条件。 我想知道这样的if(?)语句可以去哪里,因为在哪里我可以附加这个样式信息,给定我的具体约束(我应该识别特定行中的数据并突出显示它们)。在网上尝试了很多资源,几乎每个人都有一个问题,因为我正在使用这个实现。 我也不允许使用标准OpenXML以外的任何库。

public static Byte[] Create(DataSet ds) { Dictionary<String, List<OpenXmlElement>> sets = ToSheets(ds); Byte[] _data = new Byte[] { }; using (MemoryStream _ms = new MemoryStream()) { using (SpreadsheetDocument package = SpreadsheetDocument.Create(_ms, SpreadsheetDocumentType.Workbook)) { WorkbookPart workbookpart = package.AddWorkbookPart(); workbookpart.Workbook = new Workbook(); Sheets sheets = workbookpart.Workbook.AppendChild(new Sheets()); foreach (KeyValuePair<String, List<OpenXmlElement>> set in sets) { WorksheetPart worksheetpart = workbookpart.AddNewPart<WorksheetPart>(); worksheetpart.Worksheet = new Worksheet(new SheetData(set.Value)); worksheetpart.Worksheet.Save(); Sheet sheet = new Sheet() { Id = workbookpart.GetIdOfPart(worksheetpart), SheetId = Convert.ToUInt32(sheets.Count() + 1), Name = set.Key }; sheets.AppendChild(sheet); } workbookpart.Workbook.Save(); } _data = _ms.ToArray(); } return _data; } 

上面是主要的Create()函数,下面是ToSheets()函数。 这应该是不言自明的。

  public static Dictionary<String, List<OpenXmlElement>> ToSheets(DataSet ds) { return (from dt in ds.Tables.OfType<DataTable>() select new { Key = dt.TableName, Value = ( new List<OpenXmlElement>( new OpenXmlElement[] { new Row( from d in dt.Columns.OfType<DataColumn>() select (OpenXmlElement)new Cell() { CellValue = new CellValue(d.ColumnName), DataType = CellValues.String }) })).Union ((from dr in dt.Rows.OfType<DataRow>() select ((OpenXmlElement)new Row(from dc in dr.ItemArray select (OpenXmlElement)new Cell() { CellValue = new CellValue(dc.ToString()), DataType = CellValues.String })))).ToList() }).ToDictionary(p => p.Key, p => p.Value); } 

我会很感激,如果任何人都可以指出我在正确的方向,我可以追加风格的信息,我怎么可以这样做(记住我必须根据行中的数据样式行,即与某些单元格的行值应该有一个特定的方式行样式)。具体来说,我正在寻找样式单元格的行中,蓝色背景,没有边界,当所述行中的第一个单元格包含数据,说“X”。

感谢您的时间!

我自己设法解决了这个问题。 我添加了详细的样式信息在这个页面 。

然后我修改了我自己的代码来反映select性的变化。

  public Dictionary<String, List<OpenXmlElement>> ToSheets(DataSet ds) { return (from dt in ds.Tables.OfType<DataTable>() select new { Key = dt.TableName, Value = ( new List<OpenXmlElement>( new OpenXmlElement[] { new Row( from d in dt.Columns.OfType<DataColumn>() select (OpenXmlElement)new Cell() { CellValue = new CellValue(d.ColumnName), StyleIndex = 1, DataType = CellValues.String }) })).Union ((from dr in dt.Rows.OfType<DataRow>() select ((OpenXmlElement)new Row(from dc in dr.ItemArray select (OpenXmlElement)new Cell() { CellValue = new CellValue(dc.ToString()), DataType = CellValues.String, StyleIndex = styleIdentifier(dc.ToString()) })))).ToList() }).ToDictionary(p => p.Key, p => p.Value); } 

显而易见,我通过使用上面的链接指南将多个子元素附加到stylesPart.Stylesheet.CellFormats中来定义多个StyleIndex值。 有效! 然后,我简单地使用下面的函数来dynamic地识别我想为每个特定行添加的样式信息。

  public UInt32Value styleIdentifier(String str) { int temp; xCount.Value = (Convert.ToInt32(this.xCount.Value) + 1).ToString(); if (int.TryParse(str, out temp)) { xCount.Value = "0"; } if (Convert.ToInt32(this.xCount.Value) < 4) { return 2; } return 3; } 

在代码前端,我简单地使用“xCount”作为初始值大于5的HiddenField值。 这样,对于从列1中的数据识别的每一行作为要突出显示的行,每个单元格被突出显示(最多4个,因为我有4列)。 然后,xCount的值被重置,直到遇到另一个这样的单元并重复该过程,直到遇到下一个要被高亮显示的行。

再次感谢在StackOverflow聊天的好人们,特别是@juanvan引导我在正确的方向!