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

Open XML SDK获取Excel工作表名及设置负数括号显示格式问题

问题1:获取用户友好的工作表名称

原因

Worksheet.LocalName 返回的是Open XML元素的固定标识名(固定值为worksheet),并非用户在Excel界面自定义的工作表显示名称。

解决方法

通过WorkbookPart的Sheets集合,匹配WorksheetPart对应的关系ID获取工作表显示名称,修改遍历工作表部分的代码:

foreach (WorksheetPart worksheetPart in workbookPart.WorksheetParts)
{
    // 新增代码:获取当前工作表的用户自定义名称
    string relId = workbookPart.GetIdOfPart(worksheetPart);
    Sheet sheetInfo = workbookPart.Workbook.Sheets.Elements<Sheet>().First(s => s.Id == relId);
    string sheetFriendlyName = sheetInfo.Name;

    Worksheet sheet = worksheetPart.Worksheet;
    // 后续遍历行和单元格的逻辑不变
    // ...
    // 替换原cellAddress赋值逻辑
    var cellAddress = $"{sheetFriendlyName}-{c.CellReference.InnerText}";
    // ...
}

问题2:负数自动显示为带括号格式

原因

你仅设置了单元格的值和数据类型,未指定单元格的数字渲染格式,Excel会使用默认数值格式渲染,因此需要手动配置符合要求的数字格式规则并绑定到单元格。

解决方法

  1. 打开文档后先为工作簿添加负数带括号的数字格式样式,生成对应的样式ID
  2. 赋值数值时给对应单元格绑定该样式ID

首先在打开文档、获取WorkbookPart后新增样式初始化逻辑:

// 新增:初始化负数带括号的数字格式样式
WorkbookStylesPart stylesPart = workbookPart.WorkbookStylesPart ?? workbookPart.AddNewPart<WorkbookStylesPart>();
if (stylesPart.Stylesheet == null)
{
    stylesPart.Stylesheet = new Stylesheet();
}
Stylesheet styles = stylesPart.Stylesheet;

// 目标数字格式:正数正常显示,负数用括号包裹,可按需修改格式字符串,比如加[Red]可显示红色负数
const string targetFormatCode = "#,##0_);(#,##0)";

// 避免重复添加相同格式
NumberingFormat existingFormat = styles.NumberingFormats?.Elements<NumberingFormat>()
    .FirstOrDefault(f => f.FormatCode == targetFormatCode);
uint numberFormatId;
if (existingFormat == null)
{
    // 自定义数字格式ID从164开始,0-163为Excel内置格式ID
    numberFormatId = styles.NumberingFormats == null ? 164u : (uint)(styles.NumberingFormats.Count + 164);
    styles.NumberingFormats ??= new NumberingFormats();
    styles.NumberingFormats.Append(new NumberingFormat
    {
        NumberFormatId = numberFormatId,
        FormatCode = targetFormatCode
    });
}
else
{
    numberFormatId = existingFormat.NumberFormatId;
}

// 生成对应的单元格格式
CellFormat existingCellFormat = styles.CellFormats?.Elements<CellFormat>()
    .FirstOrDefault(cf => cf.NumberFormatId == numberFormatId && cf.ApplyNumberFormat == true);
uint cellStyleId;
if (existingCellFormat == null)
{
    cellStyleId = styles.CellFormats == null ? 1u : (uint)styles.CellFormats.Count;
    styles.CellFormats ??= new CellFormats();
    styles.CellFormats.Append(new CellFormat
    {
        NumberFormatId = numberFormatId,
        ApplyNumberFormat = true,
        FontId = 0,
        FillId = 0,
        BorderId = 0
    });
}
else
{
    cellStyleId = existingCellFormat.CellFormatId;
}
styles.Save();

然后修改SetCellValue方法,新增样式ID参数,为数值类型单元格绑定样式:

private void SetCellValue(Cell c, (object Value, Domain.Entities.CellType? Type) cellValueResult, uint numberStyleId)
{
    c.CellValue.Text = cellValueResult.Value.ToString();
    
    if (cellValueResult.Type == Domain.Entities.CellType.Text)
    {
        c.DataType = new EnumValue<CellValues>(CellValues.InlineString);
        c.StyleIndex = null;
    }
    else
    {
        c.DataType = new EnumValue<CellValues>(CellValues.Number);
        // 绑定负数带括号的样式
        c.StyleIndex = new UInt32Value(numberStyleId);
    }
}

调用SetCellValue时传入前面生成的cellStyleId即可。

内容的提问来源于stack exchange,提问作者Mohsen Saleh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:27:01