如何使用Open XML编辑Excel工作表并设置单元格背景色?
嘿,我来给你详细讲讲怎么用Open XML SDK实现读取Excel工作表并修改特定单元格背景色的操作,这事儿我熟得很!
首先你得先把Open XML SDK的包装上,直接用NuGet就行:
Install-Package DocumentFormat.OpenXml
或者在.NET项目里通过NuGet包管理器搜索DocumentFormat.OpenXml安装最新版本。
Open XML处理Excel的逻辑和直接用Excel界面操作不太一样,它是基于XML结构的,所以设置单元格背景色得走「定义样式 → 单元格引用样式」的路子,具体步骤如下:
打开Excel文档
用SpreadsheetDocument.Open方法打开文件,记得要指定可写模式(第二个参数传true),最好用using语句,这样能自动释放资源,避免文件被占用。定位目标工作表
从WorkbookPart里找到对应的工作表,你可以按工作表名称查找,也可以直接取第一个工作表,看你的需求。创建背景色填充样式
Open XML里的样式是集中管理的,不能直接给单元格硬编码颜色,得先在StylesPart里定义一个填充样式:- 先判断
WorkbookPart里有没有StylesPart,没有的话就新建一个 - 创建
PatternFill,设置填充类型为Solid(纯色填充) - 设置
ForegroundColor的ARGB值(比如红色是FFFF0000,黄色是FFFFFF00) - 把这个填充添加到
Fills集合里,同时更新Stylesheet的Fills计数
- 先判断
定位目标单元格
写个辅助方法来获取指定单元格,因为Excel里的单元格如果没被编辑过,可能不会在XML里存在,所以需要判断:如果单元格不存在,就创建一个并添加到对应的行里;如果行也不存在,还要先创建行。给单元格应用样式
找到目标单元格后,把它的StyleIndex属性设置为我们刚才创建的填充样式的索引,这样单元格就会用上这个背景色了。保存并关闭文档
最后别忘了保存StylesPart和SpreadsheetDocument,确保修改生效。
我给你写个完整的C#示例,你可以直接参考:
using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System.Linq; public class ExcelHelper { public static void SetCellBackgroundColor(string filePath, string sheetName, string cellAddress, string argbColor) { // 打开Excel文档,可写模式 using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, true)) { // 获取WorkbookPart WorkbookPart workbookPart = document.WorkbookPart; // 查找目标工作表 WorksheetPart worksheetPart = workbookPart.WorksheetParts .FirstOrDefault(wp => wp.Worksheet.Descendants<SheetName>().First().Text == sheetName); if (worksheetPart == null) { throw new System.Exception($"找不到名为{sheetName}的工作表"); } // 获取或创建StylesPart StylesPart stylesPart = workbookPart.StylesPart ?? workbookPart.AddNewPart<StylesPart>(); Stylesheet stylesheet = stylesPart.Stylesheet ?? new Stylesheet(); // 定义背景色填充样式 Fill fill = new Fill( new PatternFill() { PatternType = PatternValues.Solid, ForegroundColor = new ForegroundColor() { Rgb = new HexBinaryValue(argbColor) }, BackgroundColor = new BackgroundColor() { Indexed = 64 } }); // 添加填充到Fills集合 var fills = stylesheet.Fills ?? new Fills(); fills.Append(fill); fills.Count = (uint)fills.ChildElements.Count; stylesheet.Fills = fills; // 保存样式 stylesheet.Save(stylesPart); // 获取样式索引(新添加的填充索引是fills.Count - 1,因为索引从0开始) uint styleIndex = fills.Count - 1; // 解析单元格地址(比如A1 → 列A,行1) CellAddress cellAddr = new CellAddress(cellAddress); Cell cell = GetCell(worksheetPart.Worksheet, cellAddr.ColumnName, cellAddr.Row); // 设置单元格样式索引 cell.StyleIndex = styleIndex; // 保存工作表 worksheetPart.Worksheet.Save(); } } // 辅助方法:获取或创建单元格 private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex) { Row row = GetRow(worksheet, rowIndex); if (row == null) { row = new Row() { RowIndex = rowIndex }; worksheet.Append(row); } Cell cell = row.Elements<Cell>().FirstOrDefault(c => c.CellReference.Value == $"{columnName}{rowIndex}"); if (cell == null) { cell = new Cell() { CellReference = $"{columnName}{rowIndex}" }; row.Append(cell); } return cell; } // 辅助方法:获取或创建行 private static Row GetRow(Worksheet worksheet, uint rowIndex) { return worksheet.Elements<Row>().FirstOrDefault(r => r.RowIndex == rowIndex); } } // 辅助类:解析单元格地址 public class CellAddress { public string ColumnName { get; } public uint Row { get; } public CellAddress(string address) { // 拆分列名和行号(比如A123 → 列A,行123) int splitIndex = 0; while (splitIndex < address.Length && char.IsLetter(address[splitIndex])) { splitIndex++; } ColumnName = address.Substring(0, splitIndex); Row = uint.Parse(address.Substring(splitIndex)); } } // 使用示例 // ExcelHelper.SetCellBackgroundColor(@"C:\test.xlsx", "Sheet1", "B3", "FFFF0000");
- 确保操作Excel文件时,文件没有被其他程序(比如Excel客户端)打开,否则会抛出文件占用的异常。
- ARGB颜色值要注意格式:第一位是透明度(FF是不透明),后面三位是RGB值,比如
FF00FF00是纯绿色。 - 如果你的Excel文件已经有自定义样式,记得不要覆盖原有样式,示例代码里是在现有样式基础上添加新的填充,所以索引不会冲突。
- 处理完文档后,
using语句会自动关闭文档,不用手动调用Close方法,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Sumesh Es




