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会使用默认数值格式渲染,因此需要手动配置符合要求的数字格式规则并绑定到单元格。
解决方法
- 打开文档后先为工作簿添加负数带括号的数字格式样式,生成对应的样式ID
- 赋值数值时给对应单元格绑定该样式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
相关产品推荐
相关产品推荐

