You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C#.NET+OpenXML创建表格时无法切换至第二种字体的问题

解决OpenXML无法切换第二种字体的问题

你遇到的问题核心是对OpenXML样式系统的理解有误:单元格的StyleIndex对应的是单元格样式(CellStyle)的索引,而非字体的索引。你仅添加了字体,但未创建关联字体的单元格样式,也未完善样式表的必要结构,导致样式无法生效。

修正步骤及代码:

  1. 完善样式表结构:OpenXML的Stylesheet必须包含Fonts、Fills、Borders、CellStyleFormats、CellStyles这些核心节点,缺失任何一个都会导致样式失效。
  2. 创建关联字体的单元格样式:为每种字体创建对应的CellStyle,通过FontId绑定字体(字体索引从0开始计数)。
  3. 正确设置单元格的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:31:04