在制作 Excel 报价单、预算表或销售报表时,我们通常希望用户能够填写和修改数据,但不能随意更改表格中的计算公式。
例如,一份产品报价单需要允许销售人员修改商品数量和单价,而金额、小计和总计等字段应由公式自动计算。如果公式被误删或覆盖,最终的报价结果就可能出错。
通过 C#,我们可以为 Excel 单元格设置不同的编辑权限:允许修改指定的输入区域,锁定包含公式的单元格,还可以隐藏公式内容,避免用户直接查看或修改。
本文将以一份销售报价单为例,介绍如何使用 C# 实现 Excel 单元格锁定、公式隐藏以及工作表保护。
首先,在 C# 项目中安装 Excel 文档处理库。
打开 Visual Studio,依次选择“工具”→“NuGet 包管理器”→“程序包管理器控制台”,执行:
Install-Package FreeSpire.XLS也可以使用 .NET CLI 安装:
dotnet add package FreeSpire.XLS这里使用的是 Free Spire.XLS for .NET。安装后,可以直接在 C# 程序中创建、读取和修改 Excel 文件,无需安装 Microsoft Excel。
在编写代码之前,需要先了解 Excel 的单元格锁定机制。
默认情况下,Excel 单元格的“锁定”属性通常处于启用状态,但这并不意味着单元格不能编辑。只有启用工作表保护后,锁定设置才会真正生效。
因此,如果希望用户只能修改某些单元格,通常需要完成以下操作:
此外,Excel 还支持隐藏单元格中的公式。启用这一设置并保护工作表后,用户仍然能够看到公式计算出的结果,但无法通过公式栏查看公式内容。
需要注意,锁定单元格和隐藏公式是两个不同的功能。前者用于限制编辑,后者用于控制公式是否显示,可以根据实际需求单独或同时使用。
假设我们需要制作一份销售报价单,其中包含商品名称、数量、单价和金额四列。
各列的编辑权限如下:
列 | 内容 | 是否允许修改 |
|---|---|---|
A 列 | 商品名称 | 否 |
B 列 | 数量 | 是 |
C 列 | 单价 | 是 |
D 列 | 金额(公式计算) | 否 |
报价单的第 4~6 行用于记录商品信息,D7 单元格用于计算总金额。
我们的目标是让用户能够修改 B4 中的数量和单价,而 D4 中的计算公式始终受到保护。
首先,创建一个 Excel 工作簿,获取第一个工作表,并写入报价单数据。
Workbook workbook = new Workbook();
Worksheet sheet = workbook.Worksheets[0];
sheet.Name = "销售报价单";
// 添加表头
sheet.Range["A3"].Text = "商品名称";
sheet.Range["B3"].Text = "数量";
sheet.Range["C3"].Text = "单价";
sheet.Range["D3"].Text = "金额";
// 添加商品数据
sheet.Range["A4"].Text = "云服务";
sheet.Range["B4"].NumberValue = 3;
sheet.Range["C4"].NumberValue = 199;
sheet.Range["A5"].Text = "技术支持服务";
sheet.Range["B5"].NumberValue = 2;
sheet.Range["C5"].NumberValue = 149;
sheet.Range["A6"].Text = "培训服务";
sheet.Range["B6"].NumberValue = 1;
sheet.Range["C6"].NumberValue = 299;接下来,为金额列添加计算公式,并在 D7 单元格中计算总金额。
// 计算每项商品的金额
sheet.Range["D4"].Formula = "=B4*C4";
sheet.Range["D5"].Formula = "=B5*C5";
sheet.Range["D6"].Formula = "=B6*C6";
// 计算总金额
sheet.Range["A7"].Text = "总金额";
sheet.Range["D7"].Formula = "=SUM(D4:D6)";这样就完成了报价单的基本内容。用户修改数量或单价后,金额和总金额可以通过公式重新计算。
不过,此时所有单元格仍然可以正常编辑,还没有设置任何保护限制。
报价单中的数量和单价位于 B4:C6 区域。为了让用户在启用工作表保护后仍然能够修改这些数据,需要先将对应单元格解锁。
// 允许用户修改数量和单价
sheet.Range["B4:C6"].Style.Locked = false;这里使用 Style.Locked 属性控制单元格是否锁定:
false:解除锁定,允许在受保护的工作表中编辑。true:锁定单元格,在启用工作表保护后禁止编辑。由于 Excel 单元格默认处于锁定状态,因此只需要将允许填写的区域设置为 false,其他单元格保持原有设置即可。
需要注意,执行这段代码后,工作表并不会立即限制编辑。还需要在后续步骤中启用工作表保护。
报价单中的 D4 用于存放计算公式。为了避免用户意外修改这些公式,可以将该区域设置为锁定状态,并启用公式隐藏功能。
// 锁定公式单元格并隐藏公式
CellRange formulaRange = sheet.Range["D4:D7"];
formulaRange.Style.Locked = true;
formulaRange.Style.FormulaHidden = true;其中:
Style.Locked = true 用于锁定单元格,防止用户在受保护的工作表中直接修改其内容。
Style.FormulaHidden = true 用于隐藏公式。当工作表受到保护时,用户选中这些单元格,公式栏中不会显示对应的公式。
例如,D4 单元格中的公式为:
=B4*C4启用公式隐藏和工作表保护后,单元格中仍然可以显示计算结果 597,但用户无法通过公式栏查看原始公式。
这样既不会影响正常查看报价金额,也能够降低计算公式被误改的风险。
完成单元格的锁定和解锁设置后,调用 Protect() 方法启用工作表保护。
// 启用工作表保护
sheet.Protect("Quote2026");
// 保存 Excel 文件
workbook.SaveToFile(
"Protected_Quotation.xlsx",
ExcelVersion.Version2016
);
workbook.Dispose();Protect() 方法中的参数是工作表保护密码。后续如果需要修改已经锁定的单元格,可以先使用该密码取消保护。
保存文件后,用户仍然可以在 B4 区域输入数据,但不能直接修改 D4 中的公式。
下面将前面的操作整合为一个完整的 C# 示例。
程序会自动创建一份销售报价单,填写示例数据,添加计算公式,并设置不同单元格的编辑权限。
不需要提前准备 Excel 文件,直接运行即可。
using System;
using Spire.Xls;
class Program
{
static void Main()
{
// 创建工作簿
Workbook workbook = new Workbook();
Worksheet sheet = workbook.Worksheets[0];
sheet.Name = "销售报价单";
// 添加标题
sheet.Range["A1"].Text = "销售报价单";
// 添加表头
sheet.Range["A3"].Text = "商品名称";
sheet.Range["B3"].Text = "数量";
sheet.Range["C3"].Text = "单价";
sheet.Range["D3"].Text = "金额";
// 添加商品数据
sheet.Range["A4"].Text = "云服务";
sheet.Range["B4"].NumberValue = 3;
sheet.Range["C4"].NumberValue = 199;
sheet.Range["A5"].Text = "技术支持服务";
sheet.Range["B5"].NumberValue = 2;
sheet.Range["C5"].NumberValue = 149;
sheet.Range["A6"].Text = "培训服务";
sheet.Range["B6"].NumberValue = 1;
sheet.Range["C6"].NumberValue = 299;
// 添加计算公式
sheet.Range["D4"].Formula = "=B4*C4";
sheet.Range["D5"].Formula = "=B5*C5";
sheet.Range["D6"].Formula = "=B6*C6";
// 计算总金额
sheet.Range["A7"].Text = "总金额";
sheet.Range["D7"].Formula = "=SUM(D4:D6)";
// 设置基本格式
sheet.Range["A1"].Style.Font.IsBold = true;
sheet.Range["A3:D3"].Style.Font.IsBold = true;
sheet.Range["A7:D7"].Style.Font.IsBold = true;
// 调整列宽
sheet.SetColumnWidth(1, 24);
sheet.SetColumnWidth(2, 14);
sheet.SetColumnWidth(3, 16);
sheet.SetColumnWidth(4, 16);
// 解锁数量和单价输入区域
sheet.Range["B4:C6"].Style.Locked = false;
// 锁定公式单元格并隐藏公式
CellRange formulaRange = sheet.Range["D4:D7"];
formulaRange.Style.Locked = true;
formulaRange.Style.FormulaHidden = true;
// 启用工作表保护
sheet.Protect("Quote2026");
// 保存文件
workbook.SaveToFile(
"Protected_Quotation.xlsx",
ExcelVersion.Version2016
);
workbook.Dispose();
Console.WriteLine("已成功创建受保护的 Excel 报价单。");
}
}运行后,程序将生成 Protected_Quotation.xlsx 文件。
使用 Microsoft Excel 打开后,可以看到一份包含商品信息和计算结果的报价单。虽然表格外观与普通工作表没有太大区别,但不同区域的编辑权限已经发生变化:
例如,将 B4 单元格中的数量从 3 改为 5,D4 中的金额会根据公式重新计算,从 597 变为 995。
这样,用户只需要填写或修改报价数据,不必接触底层计算公式。
除了新建报价单,我们也可以对现有的 Excel 文件设置单元格保护。
例如,已经有一份制作好的 Quotation_Template.xlsx 报价模板,现在希望为其添加编辑限制。
这时不需要重新创建工作簿,只需要加载原文件,设置各区域的锁定状态,再启用工作表保护即可。
using Spire.Xls;
class Program
{
static void Main()
{
// 加载已有 Excel 文件
Workbook workbook = new Workbook();
workbook.LoadFromFile("Quotation_Template.xlsx");
Worksheet sheet = workbook.Worksheets[0];
// 锁定已使用区域中的所有单元格
sheet.Range.Style.Locked = true;
// 解锁数量和单价输入区域
sheet.Range["B4:C6"].Style.Locked = false;
// 锁定公式单元格并隐藏公式
sheet.Range["D4:D7"].Style.Locked = true;
sheet.Range["D4:D7"].Style.FormulaHidden = true;
// 启用工作表保护
sheet.Protect("Quote2026");
// 保存为新文件
workbook.SaveToFile(
"Quotation_Protected.xlsx",
ExcelVersion.Version2016
);
workbook.Dispose();
}
}与前面的示例相比,这段代码多了一步:
sheet.Range.Style.Locked = true;它会先将工作表已使用区域中的单元格统一设置为锁定状态,再单独解锁需要填写的区域。
这样做是因为已有 Excel 模板可能设置过不同的单元格权限。如果直接启用保护,部分原本未锁定的单元格仍然可以编辑。
需要注意,这个示例假设原工作表尚未启用保护,并且输入区域和公式区域与前面的报价单一致。如果实际文件使用了不同的单元格位置,应相应调整代码。
如果报价单中还有客户名称、报价日期等需要填写的字段,也可以单独解锁。
例如:
// 允许修改客户名称和报价日期
sheet.Range["B1"].Style.Locked = false;
sheet.Range["B2"].Style.Locked = false;只要在调用 Protect() 之前完成解锁设置,就可以让这些单元格在受保护的工作表中继续保持可编辑状态。
这是因为单元格锁定属性只有在工作表受到保护时才会生效。
例如:
sheet.Range["D4:D7"].Style.Locked = true;这段代码只是将 D4 设置为锁定状态,并不会立即禁止修改。
还需要执行:
sheet.Protect("Quote2026");启用工作表保护后,锁定的单元格才会受到编辑限制。
因为锁定单元格并不等于隐藏公式。
Style.Locked 只用于控制能否编辑单元格。如果还希望隐藏公式,需要额外设置 FormulaHidden 属性。
sheet.Range["D4:D7"].Style.FormulaHidden = true;然后启用工作表保护。
需要注意,隐藏公式并不会删除公式,只是在工作表受到保护时不显示公式内容。取消工作表保护后,公式仍然可以正常查看。
首先检查需要填写的单元格是否已解锁。
例如:
sheet.Range["B4:C6"].Style.Locked = false;如果这些单元格仍然处于锁定状态,启用工作表保护后,就无法正常修改其中的数据。
此外,还要检查代码中的单元格范围是否与实际 Excel 文件一致。
例如,如果数量和单价实际位于 C、D 两列,就需要调整对应的解锁区域。
不能完全做到。
Excel 工作表保护主要用于限制编辑操作,避免用户误删数据、修改公式或破坏表格结构,并不是专门用于保护机密信息的安全机制。
虽然隐藏公式后,用户无法通过正常的 Excel 公式栏查看公式内容,但这并不意味着公式已经被加密。
如果需要防止未经授权的人员访问 Excel 文件中的敏感数据,应考虑使用文件级加密等更合适的安全措施。
在需要多人填写或使用的 Excel 表格中,合理设置单元格保护,可以有效减少公式被误删、计算结果被修改等问题。
本文介绍了如何使用 C# 实现 Excel 单元格的锁定与解锁、公式隐藏和工作表保护,并通过销售报价单示例演示了如何让用户只能编辑指定区域。
无论是报价单、预算模板,还是需要自动计算数据的业务报表,都可以采用这种方式,在保留数据填写功能的同时,保护表格中的计算公式和固定内容。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。