使用C#.NET+OpenXML创建表格时无法切换至第二种字体的问题
解决OpenXML无法切换第二种字体的问题
你遇到的问题核心是对OpenXML样式系统的理解有误:单元格的StyleIndex对应的是单元格样式(CellStyle)的索引,而非字体的索引。你仅添加了字体,但未创建关联字体的单元格样式,也未完善样式表的必要结构,导致样式无法生效。
修正步骤及代码:
- 完善样式表结构:OpenXML的
Stylesheet必须包含Fonts、Fills、Borders、CellStyleFormats、CellStyles这些核心节点,缺失任何一个都会导致样式失效。 - 创建关联字体的单元格样式:为每种字体创建对应的
CellStyle,通过FontId绑定字体(字体索引从0开始计数)。 - 正确设置单元格的StyleIndex:使用单元格样式的索引(默认样式为0,自定义样式从1开始)。
修改后的完整代码:
private Cell CreateCell(string text, uint styleIndex) { Cell cell = new Cell(); cell.StyleIndex = styleIndex; cell.DataType = ResolveCellDataTypeOnValue(text); cell.CellValue = new CellValue(text); return cell; } using (SpreadsheetDocument document = SpreadsheetDocument.Create("somefile.xlsx", SpreadsheetDocumentType.Workbook)) { WorkbookPart workbookPart = document.AddWorkbookPart(); workbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook(); WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>(); // 初始化样式表 WorkbookStylesPart sp = workbookPart.AddNewPart<WorkbookStylesPart>(); Stylesheet stylesheet = new Stylesheet(); // 1. 添加字体集合 Fonts fonts = new Fonts(); // 字体0:蓝色加粗11号 Font font1 = new Font( new FontSize { Val = 11 }, new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = HexBinaryValue.FromString("4b53cb") }, new Bold() ); // 字体1:红色斜体15号 Font font2 = new Font( new FontSize { Val = 15 }, new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = HexBinaryValue.FromString("c93653") }, new Italic() ); fonts.Append(font1); fonts.Append(font2); fonts.Count = (uint)fonts.ChildElements.Count; // 必须设置Count属性 stylesheet.Append(fonts); // 2. 添加填充集合(默认空填充) Fills fills = new Fills(); fills.Append(new Fill(new PatternFill { PatternType = PatternValues.None })); fills.Append(new Fill(new PatternFill { PatternType = PatternValues.Gray125 })); fills.Count = (uint)fills.ChildElements.Count; stylesheet.Append(fills); // 3. 添加边框集合(默认无边框) Borders borders = new Borders(); borders.Append(new Border()); borders.Count = (uint)borders.ChildElements.Count; stylesheet.Append(borders); // 4. 创建单元格格式,关联字体、填充、边框 CellStyleFormats cellStyleFormats = new CellStyleFormats(); // 默认格式(索引0) cellStyleFormats.Append(new CellFormat { FontId = 0, FillId = 0, BorderId = 0 }); // 自定义格式1:使用字体0 cellStyleFormats.Append(new CellFormat { FontId = 0, FillId = 0, BorderId = 0, ApplyFont = true }); // 自定义格式2:使用字体1 cellStyleFormats.Append(new CellFormat { FontId = 1, FillId = 0, BorderId = 0, ApplyFont = true }); cellStyleFormats.Count = (uint)cellStyleFormats.ChildElements.Count; stylesheet.Append(cellStyleFormats); // 5. 创建单元格样式 CellStyles cellStyles = new CellStyles(); cellStyles.Append(new CellStyle { Name = "Normal", FormatId = 0, BuiltinId = 0 }); cellStyles.Append(new CellStyle { Name = "CustomStyle1", FormatId = 1 }); cellStyles.Append(new CellStyle { Name = "CustomStyle2", FormatId = 2 }); cellStyles.Count = (uint)cellStyles.ChildElements.Count; stylesheet.Append(cellStyles); // 保存样式表 sp.Stylesheet = stylesheet; sp.Stylesheet.Save(); // 创建工作表数据 SheetData sheetData = new SheetData(); // 创建行和单元格(使用自定义样式2,对应字体1) Row workRow = new Row(); workRow.Append(CreateCell("Some text", 2U)); // 这里的2是自定义样式的索引 sheetData.Append(workRow); // 保存工作表 worksheetPart.Worksheet = new Worksheet(sheetData); worksheetPart.Worksheet.Save(); // 关联工作表到工作簿 Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets()); Sheet sheet = new Sheet { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Trial" }; sheets.Append(sheet); workbookPart.Workbook.Save(); }
关键说明:
- 字体索引从0开始,
font1是索引0,font2是索引1。 - 单元格格式(
CellFormat)通过FontId绑定字体,ApplyFont = true表示应用该字体设置。 - 单元格的
StyleIndex对应CellStyles中的索引,这里自定义样式2的索引是2,对应使用字体1的格式。 - 必须为
Fonts、Fills、Borders等集合设置Count属性,否则OpenXML解析器无法识别样式数量。
内容的提问来源于stack exchange,提问作者Manoj AP
相关产品推荐
相关产品推荐

