news 2026/10/12 3:18:04

ClosedXML 工作表 API 完全指南:深入解析 IXLWorksheet 的每个成员与底层实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ClosedXML 工作表 API 完全指南:深入解析 IXLWorksheet 的每个成员与底层实现
  • 后端

【免费下载链接】ClosedXML

ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API.

项目地址:https://gitcode.com/gh_mirrors/cl/ClosedXML
点击查看免费下载

导读

IXLWorksheet是 ClosedXML 中代表单个 Excel 工作表的统一入口接口,几乎所有的单元格读写、行列操作、样式设置、数据验证、透视表、自动筛选等功能都从它开始。本文以官方 API 文档 docs/api/worksheet.rst 为骨架,逐一剖析IXLWorksheet的每个属性与方法(涵盖命名、可见性、行列单元格访问、复制删除、排序、公式计算、保护等),并结合接口源码 ClosedXML/Excel/IXLWorksheet.cs 与实现类 ClosedXML/Excel/XLWorksheet.cs 验证其真实行为与底层机制。读完本文,你将能够熟练使用 ClosedXML 创建、配置、复制和操作工作表,并理解其内部的数据组织方式。

一、工作表在 ClosedXML 中的定位

在 ClosedXML 中,工作簿(XLWorkbook)与工作表(IXLWorksheet)的关系是容器与成员:一个工作簿通过Worksheets集合管理若干张工作表,而每张工作表本身是一个覆盖整个网格的"巨型范围"——从实现类XLWorksheet继承自XLRangeBase可以看出,工作表本质上也是一个范围对象,其地址覆盖从(1,1)到(MaxRowNumber, MaxColumnNumber)的整个区域(参见 XLWorksheet.cs 构造函数)。

接口定义的核心结构如下:

public interface IXLWorksheet : IXLRangeBase, IXLProtectable<IXLSheetProtection, XLSheetProtectionElements> { // 属性:Workbook / ColumnWidth / RowHeight / Name / Position / PageSetup / Outline / Hyperlinks ... // 方法:FirstRow / LastRow / Row / Column / Cell / Range / Sort / CopyTo / Delete / Evaluate ... }

IXLWorksheet同时继承IXLRangeBase(因此具备Cells()、FirstCell()、LastCell()等范围级能力)和IXLProtectable(因此具备Protect()/Unprotect()工作表保护能力)。理解了这一点,就能明白为什么工作表可以直接调用大量范围方法。

二、获取与创建工作表

2.1 从工作簿获取已有工作表

IXLWorkbook提供了三条取表路径(见 IXLWorkbook.cs 接口定义):

var wb = new XLWorkbook(); // 按名称获取(区分大小写,找不到会抛出异常) IXLWorksheet ws = wb.Worksheet("Sheet1"); // 按位置获取(从 1 开始计数) IXLWorksheet ws2 = wb.Worksheet(1); // 安全获取:找不到返回 false,不抛异常 if (wb.TryGetWorksheet("Sheet1", out IXLWorksheet sheet)) { // 使用 sheet }

2.2 添加新工作表

AddWorksheet有丰富重载(同样定义于 IXLWorkbook.cs):

// 不带名称:自动生成 "SheetN" 形式的名称 wb.AddWorksheet(); // 指定名称 wb.AddWorksheet("销售数据"); // 指定名称与插入位置 wb.AddWorksheet("销售数据", 1); // 从 DataSet / DataTable 批量导入 DataSet ds = ...; wb.AddWorksheet(ds); wb.AddWorksheet(dataTable); // 表头即列名,写入 A1 起 wb.AddWorksheet(dataTable, "SheetName"); // 同时指定工作表名 wb.AddWorksheet(dataTable, "SheetName", "TableName"); // 同时把数据建成 Excel 表

注意:当使用AddWorksheet(DataTable, sheetName)系列重载时,数据会作为一张Excel 表(Table)写入,表名自动生成为Table{数字后缀};只有在显式传入tableName的重载中表名才是确定的。

2.3 新建工作表的默认值继承

从实现源码可以看到,新建的XLWorksheet会从工作簿继承一组默认值(XLWorksheet.cs 构造函数):默认列宽workbook.ColumnWidth、默认行高workbook.RowHeight、工作簿级显示选项(ShowFormulas、ShowGridLines、ShowOutlineSymbols、ShowRowColHeaders、ShowRuler、ShowWhiteSpace、ShowZeros)、RightToLeft,以及Author。也就是说,你可以在工作簿上统一设置后,让所有新建工作表自动带上这些默认行为。

三、命名、位置与可见性

3.1 Name:工作表命名与重命名

ws.Name = "新名称";

重命名是"联动"操作。接口注释明确指出:The sheet rename also renames sheet in formulas and defined names.(重命名会同步修改公式与定义名称中对该表的引用)。实现中,Name的 setter 先调用XLHelper.ValidateSheetName(value)做合法性校验,再通过Workbook.WorksheetsInternal.Rename(_name, value)完成重命名(XLWorksheet.cs)。

3.2 工作表名称的合法性规则

名称校验逻辑位于 ClosedXML/XLHelper_ASF.cs 的 ValidateSheetName,规则如下:

规则说明
长度必须 ≥ 1 且 ≤ 31 个字符
禁用的非法字符0x0000、0x0003、冒号:、反斜杠\、星号*、问号?、正斜杠/、左方括号[、右方括号]
首尾字符不能以单引号'开头或结尾
空白不能为 null 或纯空白字符串

违反上述任何一条都会抛出ArgumentException。例如ws.Name = "A:B"会因为冒号非法而失败。该实现移植自 Apache POI 的WorkbookUtil,与 Excel 本身的命名约束保持一致。

3.3 Position:调整工作表顺序

ws.Position = 2; // 把工作表移动到第 2 个标签位置

接口注释强调:设置 Position 时,其他所有工作表的 Position 会被相应平移。实现中(XLWorksheet.cs),如果新位置小于旧位置,则介于两者之间的工作表_position各加 1;反之各减 1。若目标位置超过"工作表总数 + 1",会抛出ArgumentOutOfRangeException。

3.4 Visibility:可见性三态

public enum XLWorksheetVisibility { Visible, Hidden, VeryHidden }
  • Visible:正常显示(默认);
  • Hidden:隐藏,但用户可在 Excel 中通过"取消隐藏"恢复;
  • VeryHidden:深度隐藏,不显示在 Excel 的"取消隐藏"列表中,只能通过代码改回。
ws.Hide(); // 等价于 Visibility = XLWorksheetVisibility.Hidden ws.Unhide(); // 等价于 Visibility = XLWorksheetVisibility.Visible ws.Visibility = XLWorksheetVisibility.VeryHidden;

实现细节:当把Visibility设为非Visible时,TabSelected会被自动置为false(XLWorksheet.cs),保证隐藏的工作表不会保留"被选中"状态。

3.5 标签页外观:TabColor / TabSelected / TabActive

ws.TabColor = XLColor.Red; // 设置标签颜色 ws.SetTabColor(XLColor.Blue); // 链式写法 ws.TabSelected = true; // 标签被选中 ws.TabActive = true; // 标签处于活动状态

TabActive有一个重要的互斥语义:设置某个工作表为活动时,工作簿内其他所有工作表的TabActive都会被置为 false(见 XLWorksheet.cs)。此外注意SetTabActive()与SetTabSelected()的区别——Active 表示当前聚焦的标签页,Selected 表示被选中的标签(Excel 中可通过 Ctrl 多选)。

四、行列与单元格访问

这是IXLWorksheet使用频率最高的一组 API。

4.1 单行 / 单列 / 单格

IXLRow row = ws.Row(5); // 第 5 行 IXLColumn col = ws.Column("C"); // C 列(也支持 Column(3)) IXLCell cell = ws.Cell(2, 3); // 第 2 行第 3 列,即 C2 IXLCell cell2 = ws.Cell("B4"); // 也支持 A1 地址字符串或工作簿级命名区域

接口要求Cell(string)传入的是A1 地址或工作簿级命名区域,否则抛出ArgumentException。实现中(XLWorksheet.cs),Cell(string)会先按 A1 解析,失败后再尝试在工作簿的DefinedNames中查找命名区域并返回其首单元格。

4.2 首行 / 末行 / 首列 / 末列(含 Used 变体)

IXLRow first = ws.FirstRow(); // 第 1 行(网格边界) IXLRow last = ws.LastRow(); // 最后一行(XLHelper.MaxRowNumber) IXLColumn firstCol = ws.FirstColumn(); // A 列 IXLColumn lastCol = ws.LastColumn(); // 最后一列(XLHelper.MaxColumnNumber) // Used 变体:第一个/最后一个"非空"行或列 IXLRow? firstUsed = ws.FirstRowUsed(); // 第一个有内容的行 IXLColumn? lastUsedCol = ws.LastColumnUsed();

"非空"的判定标准默认是XLCellsUsedOptions.AllContents——即只要包含内容(值、数据类型或批注)就算"被使用",仅有格式的空单元格不计入(接口注释明确说明Formatted empty cells do not count)。这一规则与XLCellsUsedOptions枚举密切相关:

[Flags] public enum XLCellsUsedOptions { None = 0, Contents = 1 << 0, // 有值 DataType = 1 << 1, // 有数据类型 NormalFormats = 1 << 2, // 普通格式 ConditionalFormats = 1 << 3, // 条件格式 Comments = 1 << 4, // 批注 DataValidation = 1 << 5, // 数据验证 MergedRanges = 1 << 6, // 合并单元格 Sparklines = 1 << 7, // 迷你图 AllFormats = NormalFormats | ConditionalFormats, AllContents = Contents | DataType | Comments, All = Contents | DataType | NormalFormats | ConditionalFormats | Comments | DataValidation | MergedRanges | Sparklines }

(枚举定义见 ClosedXML/Excel/XLCellsUsedOptions.cs)

因此你可以精确控制"什么算被使用":

// 只要"内容或格式"都算被使用 ws.FirstRowUsed(XLCellsUsedOptions.All); // 仅当存在条件格式时才认为被使用 ws.LastColumnUsed(XLCellsUsedOptions.ConditionalFormats);

实现上(XLWorksheet.cs),FirstRowUsed等方法是把整张表当作范围,委托AsRange().FirstRowUsed(options)计算后映射回对应的行对象。

4.3 行集合与列集合

// 全部行 / 全部列 IXLRows allRows = ws.Rows(); IXLColumns allCols = ws.Columns(); // 按范围取(支持逗号分隔多段、冒号表示区间) IXLRows rows = ws.Rows("4:5"); // 第 4~5 行 IXLRows rows2 = ws.Rows("7:8,10:11"); // 第 7~8 行与第 10~11 行 IXLRows rows3 = ws.Rows(1, 10); // 数字区间 IXLColumns cols = ws.Columns("G:H"); IXLColumns cols2 = ws.Columns("P:Q,S:T"); IXLColumns cols3 = ws.Columns("V"); // 单列

实现中(XLWorksheet.cs),字符串重载会先按逗号分割,再对每段判断是否含:或-作为区间分隔符;数字形式的段(如"10:11")走整数解析,字母形式的段(如"G:H")走XLHelper.GetColumnNumberFromLetter转数字。

4.4 只取"被使用的"行/列集合

// 只返回有内容的行,支持谓词过滤 IXLRows usedRows = ws.RowsUsed(); IXLRows usedRows2 = ws.RowsUsed(options: XLCellsUsedOptions.All, predicate: r => r.RowNumber() % 2 == 0);

RowsUsed/ColumnsUsed的默认参数是XLCellsUsedOptions.AllContents和predicate = null(XLWorksheet.cs),会把行/列集合去重后逐行判断IsEmpty(options),再应用谓词过滤。

4.5 单元格区域:Range / Ranges

IXLRange rng = ws.Range("A1:C10"); // 区域地址字符串 IXLRange rng2 = ws.Range("A1", "C10"); // 两个端点地址 IXLRange rng3 = ws.Range(1, 1, 10, 3); // 行列号 (首行, 首列, 末行, 末列) IXLRanges multi = ws.Ranges("A1:B2,D1:D4"); // 逗号分隔的多区域 IXLRange? used = ws.RangeUsed(); // 整个工作表的使用区域(含内容+格式) IXLRange? used2 = ws.RangeUsed(XLCellsUsedOptions.All);

实现要点(XLWorksheet.cs):

  • Range(string)优先按 A1 地址解析;若包含[则按表引用语法(如Table1[Column])解析为表格列区域;否则依次尝试工作表级与工作簿级定义名称;
  • Ranges(string)会跳过#REF!无效引用片段(XLWorksheet.cs),并对每个片段尝试"合法地址 → 工作表命名区域 → 工作簿命名区域"三级解析;
  • RangeUsed()返回包含内容或格式的最小边界矩形。

4.6 行列计数

int totalRows = ws.RowCount(); // 网格总行数(XLHelper.MaxRowNumber) int totalCols = ws.ColumnCount(); // 网格总列数(XLHelper.MaxColumnNumber)

注意这两个方法返回的是网格理论边界,不是"有数据的行数";要获得实际数据范围请使用RangeUsed()或LastRowUsed()等 Used 系列方法。

五、工作表级显示与默认尺寸配置

5.1 默认列宽与行高

ws.ColumnWidth = 20.5; // 默认列宽(字符单位) ws.RowHeight = 30; // 默认行高(磅值)

实现中,设置这两个属性时会同时置位内部标记ColumnWidthChanged/RowHeightChanged(XLWorksheet.cs),保存时据此决定是否把默认宽高写入文件。

5.2 显示选项(Show 系列属性 + Set 链式方法)

IXLWorksheet提供一组布尔显示属性,且每个属性都有配套的SetXxx()/SetXxx(bool)链式写法:

属性默认值来源含义
ShowFormulas工作簿是否显示公式而非计算结果
ShowGridLines工作簿是否显示网格线
ShowOutlineSymbols工作簿是否显示分级显示符号
ShowRowColHeaders工作簿是否显示行号列标
ShowRuler工作簿是否显示标尺(页面视图)
ShowWhiteSpace工作簿是否显示页边距空白区
ShowZeros工作簿是否显示零值

链式写法示例:

ws.SetShowGridLines(false) // 隐藏网格线 .SetShowFormulas(true) // 显示公式 .SetShowZeros(false) // 隐藏零值 .SetShowRowColHeaders(false); // 隐藏行号列标

从构造函数可以看出,这些选项在新建工作表时默认继承自工作簿(XLWorksheet.cs),这为整本工作簿统一视图风格提供了便捷途径。

5.3 从右到左布局

ws.RightToLeft = true; // 工作表按从右到左布局 ws.SetRightToLeft(true); // 链式写法

适用于阿拉伯语、希伯来语等 RTL 语言场景。

5.4 Author

ws.Author = "张三"; // 工作表作者,新建时继承 workbook.Author

六、工作表承载的功能对象一览

IXLWorksheet暴露了大量子对象属性,用于操作该表承载的特定功能。下表汇总了全部功能入口:

属性/方法类型用途
PageSetupIXLPageSetup打印设置(纸张、页边距、页眉页脚、打印区域、分页符)
OutlineIXLOutline分级显示(大纲)级别管理
SheetViewIXLSheetView工作表视图(冻结窗格、缩放、分页预览等)
HyperlinksIXLHyperlinks该表所有超链接
Tables/Table(index)/Table(name)IXLTablesExcel 表格
DefinedNames/DefinedName(name)IXLDefinedNames工作表级定义名称
NamedRanges/NamedRange(name)IXLDefinedNames已过时,请改用DefinedNames/DefinedName
DataValidationsIXLDataValidations数据验证规则
ConditionalFormatsIXLConditionalFormats条件格式
MergedRangesIXLRanges合并单元格区域集合
PivotTables/PivotTable(name)IXLPivotTables数据透视表
SparklineGroupsIXLSparklineGroups迷你图组
AutoFilterIXLAutoFilter自动筛选(通过range.SetAutoFilter()启用)
Pictures/Picture(name)/AddPicture(...)IXLPictures图片管理
SelectedRangesIXLRanges用户选中区域
ActiveCellIXLCell?活动单元格
SortRows/SortColumnsIXLSortElements预配置排序规则

6.1 图片添加

AddPicture提供了流与文件两种主流入口(IXLWorksheet.cs):

// 从文件 IXLPicture pic1 = ws.AddPicture(@"C:\img\logo.png"); IXLPicture pic2 = ws.AddPicture(@"C:\img\logo.png", "Logo"); // 指定名称 // 从流 using var fs = File.OpenRead(@"C:\img\logo.png"); IXLPicture pic3 = ws.AddPicture(fs); IXLPicture pic4 = ws.AddPicture(fs, XLPictureFormat.Png); IXLPicture pic5 = ws.AddPicture(fs, XLPictureFormat.Png, "Logo");

6.2 自动筛选

自动筛选对象本身是只读属性,真正的启用方式是配合范围:

ws.Range("A1:D100").SetAutoFilter(); // 启用后可通过 ws.AutoFilter 访问 var filter = ws.AutoFilter;

注意实现中AutoFilter = new XLAutoFilter()在构造函数里初始化(XLWorksheet.cs),但IsEnabled只有在范围上调用过SetAutoFilter()后才为真。

6.3 工作表保护

由于接口继承IXLProtectable<IXLSheetProtection, XLSheetProtectionElements>,可直接调用:

ws.Protect(); // 无密码保护(默认算法) ws.Protect("password123"); // 密码保护,允许一切元素 ws.Protect("pwd", XLSheetProtectionElements.SelectLockedCells); // 仅锁定单元格 ws.Unprotect(); ws.Unprotect("password123");

Protect支持可选算法参数(Algorithm枚举,默认DefaultProtectionAlgorithm),并可通过XLSheetProtectionElements精细控制允许用户操作的元素(排序、筛选、插入行列、编辑对象等)。实现委托给内部的XLSheetProtection(XLWorksheet.cs),具体算法与哈希细节见 ClosedXML/Excel/Protection/XLProtectionAlgorithm.cs。

七、高级操作:复制、删除、排序与公式

7.1 CopyTo:复制工作表

CopyTo有 5 个重载(IXLWorksheet.cs):

// 本工作簿内复制到末尾 / 指定位置 ws.CopyTo("副本"); // 新表名"副本" ws.CopyTo("副本", 3); // 并指定位置 // 复制到另一个工作簿 ws.CopyTo(otherWorkbook); // 保留原名,追加到末尾 ws.CopyTo(otherWorkbook, "新表名"); // 指定新名 ws.CopyTo(otherWorkbook, "新表名", 1); // 指定新名与位置

实现类 XLWorksheet.cs 的 CopyTo 揭示了完整复制深度:列宽行高、单元格值与样式、数据验证、页面设置、页眉页脚、大纲级别、视图设置、图片、表格、定义名称、透视表、条件格式、迷你图、合并区域、选中区域、自动筛选全部会被逐一复制。特别值得注意的是,源码中以注释强调Names must modify table references, so keep the order(定义名称必须放在表格之后复制,以保证表引用正确)。如果源工作表已被删除(IsDeleted为 true),复制会抛出InvalidOperationException。

7.2 Delete:删除工作表

ws.Delete();

删除是"不可撤销"操作。实现(XLWorksheet.cs)依次执行:标记IsDeleted = true→ 通知工作簿级定义名称该表被删除(OnWorksheetDeleted)→ 触发删除监听 → 从WorksheetsInternal移除。

7.3 排序

工作表级排序可以直接对整个已用区域排序:

// 按列名排序(默认升序) ws.Sort("B"); // 按 B 列升序 ws.Sort("B,C", XLSortOrder.Descending); // 按 B、C 列降序 ws.Sort(2, XLSortOrder.Ascending); // 按第 2 列升序 // 左到右排序(按行首列的值排序列) ws.SortLeftToRight(XLSortOrder.Ascending, matchCase: false, ignoreBlanks: true); // 通过 SortRows / SortColumns 预配置排序规则 ws.SortRows.Add(1, XLSortOrder.Ascending, ignoreBlanks: true, matchCase: false); ws.Sort();

排序针对的是RangeUsed()区域,且SortRows/SortColumns上预设的元素会被合并进排序规则(见 XLWorksheet.cs GetRangeForSort)。

7.4 公式求值与强制重算

// 就地求值一个公式字符串(可选提供上下文单元格地址) XLCellValue result = ws.Evaluate("SUM(1,2,3)"); XLCellValue result2 = ws.Evaluate("A1*2", "B2"); // 以 B2 为上下文求值 // 强制重算本表所有公式(不影响其他工作表) ws.RecalculateAllFormulas();
  • Evaluate的formulaAddress参数用于提供隐式交集(implicit intersection)等计算所需上下文;若某部分计算确实需要该地址却未提供,会抛出MissingContextException(见 IXLWorksheet.cs)。实现上委托给工作簿的CalcEngine.EvaluateFormula(XLWorksheet.cs)。
  • RecalculateAllFormulas先把本表全部公式标记为 dirty,再调用工作簿计算引擎只重算当前表(XLWorksheet.cs)。

7.5 分级显示:大纲折叠与展开

工作表支持按大纲级别折叠/展开行或列,级别范围为 1~8(超出会抛ArgumentOutOfRangeException):

ws.CollapseRows(); // 折叠全部大纲行(1~8 级) ws.CollapseRows(2); // 只折叠第 2 级 ws.ExpandColumns(); // 展开全部大纲列 ws.ExpandColumns(3); // 只展开第 3 级 ws.ExpandRows(); // 展开全部大纲行

无参版本实现为对 1~8 级逐一调用(XLWorksheet.cs)。大纲级别本身通过IXLOutline对象或行列的OutlineLevel属性设置。

八、源码级透视:XLWorksheet 内部如何组织数据

理解实现类 ClosedXML/Excel/XLWorksheet.cs 的内部结构,有助于写出高性能代码。

8.1 五大内部存储

构造函数中组装了完整的内部数据容器(XLWorksheet.cs):

Internals = new XLWorksheetInternals( new XLCellsCollection(this), // 单元格集合(值、样式、公式都基于切片 Slice) new XLColumnsCollection(), // 列集合 new XLRowsCollection(), // 行集合 new XLRanges()); // 范围集合(含合并区域)

即:单元格数据存于CellsCollection(内部为ValueSlice/StyleSlice/FormulaSlice等切片结构),行列样式与尺寸存于行列集合,两者相互独立。

8.2 行/列对象的惰性创建与样式固定

Row(n)/Column(n)采用惰性创建:已存在则直接返回,不存在则通过RangeFactory创建并加入集合(XLWorksheet.cs)。其中有个重要细节:新建一列时,会遍历现有所有行对交点单元格执行PingStyle(),新建一行时同理遍历所有列——源码注释解释这是为了"保留这些单元格的既有格式"(to preserve their formatting)。这意味着先创建行列再写值,会保留整行/整列的样式上下文。

8.3 样式继承链:工作表 → 行/列 → 单元格

GetStyleValue展示了 ClosedXML 的样式解析顺序(XLWorksheet.cs):单元格样式切面没有值时,按工作表样式 → 行样式 → 列样式依次组合,最终通过XLStyleValue.Combine(sheetStyle, rowStyle, colStyle)合并。源码注释还给出一个经典场景:先设列蓝色、再设行红色,交点单元格显示红色;交换顺序则显示蓝色——因为后设置的行/列样式优先。

8.4 写入数据的自动样式适配

GetStyleForValue(XLWorksheet.cs)揭示了一个实用行为:写入数据时会自动推断并应用合适的数字格式:

  • 写入DateTime(仅日期部分):自动套用数字格式 ID 14;带时间的则用 ID 22;
  • 写入TimeSpan:自动套用数字格式 ID 46(时长格式);
  • 写入以'开头的文本:自动设置IncludeQuotePrefix(文本前导撇号);
  • 写入含换行符的文本:自动打开WrapText自动换行。

也就是说,向单元格写入日期、时间、多行文本时,即使不手动设置样式,生成的 Excel 也会正确显示。

8.5 区域移动的联动维护

当插入/删除行列导致区域位移时,WorksheetRangeShiftedColumns/WorksheetRangeShiftedRows(XLWorksheet.cs)会同步维护:定义名称、条件格式、数据验证、合并区域、分页符、迷你图、超链接以及计算引擎的依赖关系,确保这些对象随位移更新而不错位。

九、完整实战示例

下面是一个覆盖本章多数 API 的端到端示例:

using ClosedXML.Excel; using var wb = new XLWorkbook(); // 1. 创建并配置工作表 var ws = wb.AddWorksheet("订单"); ws.ColumnWidth = 18; ws.RowHeight = 22; ws.SetShowGridLines(false); // 链式显示设置 ws.TabColor = XLColor.CornflowerBlue; // 2. 写入表头与数据 ws.Cell("A1").Value = "订单号"; ws.Cell("B1").Value = "日期"; ws.Cell("C1").Value = "金额"; ws.Range("A1:C1").Style.Font.Bold = true; ws.Cell(2, 1).Value = "SO-001"; ws.Cell(2, 2).Value = new DateTime(2026, 10, 11); // 自动应用日期格式 ws.Cell(2, 3).Value = 1280.5; // 3. 区域操作 var dataRange = ws.Range("A1:C2"); dataRange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin; // 4. Used 系列方法定位数据范围 var lastUsedRow = ws.LastRowUsed(); // 第 2 行 var usedRange = ws.RangeUsed(); // A1:C2 ws.RowsUsed().ForEach(r => Console.WriteLine(r.RowNumber())); // 5. 排序与自动筛选 ws.Sort("B", XLSortOrder.Descending); ws.RangeUsed().SetAutoFilter(); // 6. 复制与可见性 var copy = ws.CopyTo("订单备份", 2); copy.Visibility = XLWorksheetVisibility.Hidden; // 7. 公式求值 var total = ws.Evaluate("SUM(C2:C10)", "D1"); Console.WriteLine($"合计: {total}"); // 8. 保护 ws.Protect("secret", XLSheetProtectionElements.SelectLockedCells); wb.SaveAs(@"orders.xlsx");

十、接口一致性提示:两个已过时成员

从接口定义(IXLWorksheet.cs)可见,NamedRanges属性与NamedRange(String)方法带有[Obsolete]标记:

[Obsolete($"Use {nameof(DefinedNames)} instead.")] IXLDefinedNames NamedRanges { get; } [Obsolete($"Use {nameof(DefinedName)} instead.")] IXLDefinedName NamedRange(String rangeName);

它们仅是兼容性别名(实现中直接转发到DefinedNames/DefinedName),新代码应一律使用DefinedNames与DefinedName(name),避免编译警告并保证面向未来版本的可迁移性。

十一、小结

IXLWorksheet是 ClosedXML 中最核心的面向对象接口之一,覆盖了从网格寻址(Row/Column/Cell/Range)到工作表生命周期(AddWorksheet/CopyTo/Delete)、从显示控制(Show*系列)到高级功能(透视表、条件格式、迷你图、自动筛选、保护、公式求值)的全部能力。通过阅读 IXLWorksheet.cs 接口注释、XLWorksheet.cs 实现以及 XLCellsUsedOptions.cs 枚举定义,开发者可以准确理解每个成员的语义与边界条件(如名称 31 字符限制、VeryHidden语义、样式继承优先级、日期格式自动推断),从而写出既正确又高效的 Excel 生成代码。更多组合用法可参考仓库中的示例工程 ClosedXML.Examples/Misc 与 ClosedXML.Examples/Ranges,测试覆盖见 ClosedXML.Tests/Excel。

  • 后端

【免费下载链接】ClosedXML

ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API.

项目地址:https://gitcode.com/gh_mirrors/cl/ClosedXML
点击查看免费下载

相关推荐

上一篇:终极指南:如何让老旧Mac重获新生,免费升级到最新macOS系统
下一篇:Monica个人关系管理工具终极指南:从零开始建立你的人际关系数据库

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 3:15:58

Open-Code-Review:一种结构化、可追溯、知识沉淀型代码评审范式

1. 项目概述&#xff1a;这不是代码检查&#xff0c;而是一场协作范式的重构“open-code-review”这个词组乍看像一个工具名&#xff0c;实则是一套正在快速落地的工程实践方法论——它把传统封闭、单向、高门槛的代码评审&#xff08;Code Review&#xff09;&#xff0c;彻底…

作者头像 李华
网站建设 2026/10/12 3:15:01

个人版AI订阅直连Devin:自主编程智能体接入与成本控制实战

1. 这件事到底意味着什么个人版 AI 编程助手订阅可以直接用在 Devin 上了。这个消息乍一看像是一条普通的产品更新&#xff0c;但如果你正在用 AI 辅助写代码&#xff0c;或者正在为团队挑选自动化编程工具&#xff0c;这件事的影响面其实比想象中大得多。先说清楚背景。Devin …

作者头像 李华
网站建设 2026/10/12 3:13:49

Autodesk插件源码防护指南:从反编译风险到分层加固方案

我做了几年 Autodesk 平台插件的开发&#xff0c;也见过不少同行在官方应用商店里卖插件赚得盆满钵满&#xff0c;但很少有人愿意聊这事&#xff1a;你辛辛苦苦写的代码&#xff0c;从打包上架那一刻起&#xff0c;就一直“裸奔”在用户的电脑上。Autodesk App Store 不像移动应…

作者头像 李华
网站建设 2026/10/12 3:13:33

读取硬盘MBR:从hexdump到Python解析器实战

简介&#xff1a;这份资源围绕硬盘MBR&#xff08;主引导记录&#xff09;的读取与解析展开&#xff0c;面向具备一定C基础、希望深入理解磁盘底层结构与系统级I/O编程的开发者。内容涵盖文件操作、低级I/O调用、512字节扇区读取、内存映射、MBR分区表结构解析以及安全备份与错…

作者头像 李华