C# Excel 强制只读,没有编辑权限
C# Excel forces ReadOnly with no Edit Priveledges
我有一个 Excel 工作簿 ("test.xlsx"),其中有一个名为 "gv_epxsize" 的单元格。我的目标是打开 excel 工作簿并在名称为 "gv_epxsize".
的单元格中写下字符串“101”
问题是我的代码一直将文件设置为只读,因此它不会将字符串“101”写入指定的单元格。我不断收到 windows 提示,提示我已经使用 Windows 权限打开文件,并询问我是否要打开只读副本。问题是我没有打开文件,在启动代码之前没有 EXCEL.EXE 进程 运行ning。
我已经做过的事情:
- 我已将文件以不同的名称保存在不同的文件夹中 - 仍然没有成功。
- 文件未保存在共享文件夹中。
- 我已经确保我的 TaskManager 在我 运行 我的代码之前杀死了每个 EXCEL.EXE 进程。
有人可以告诉我我做错了什么吗?
这是 C# 的片段
string filePath = "C:\Users\ussatdafa\Desktop\Work\Projects\test.xlsx";
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
MessageBox.Show("Excel has not been properly installed");
}
else
{
//string fileName = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), filePath);
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
}
我很确定您的问题出在保存文件的代码中。从您发布的代码中,有一件事实际上不起作用,可以解释您的问题。看看下面的片段:
else {
//string fileName = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), filePath);
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
}
这是 if (xlApp == null)
语句的 else
部分。首先,在此 else
部分中,您将创建一个名为 excelApp
的新 Excel 应用程序,其中:
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
您为什么要这样做是未知的,因为您之前已经创建了一个名为 xlApp
的文件。但这仍然可以;您可以打开多个 Excel 应用程序。
然后打开文件并进行更改:
Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
您使用 filePath
打开工作簿并调用工作簿 wb
。然后抓取 wb
中的第一个 sheet 并将其分配给工作 sheet 变量 ws
。请记住,您在此 else
子句中打开了工作簿。对工作簿进行更改,然后退出 else
子句。一切似乎都正常,除了……因为我们已经退出了 else
子句……excelApp
、wbs
、wb
和 ws
变量不再存在。即使您尝试在 else
子句之外保存或关闭文件,您也无法引用它,因为您在 else
子句内创建了这些变量。
因为你不能创建一个名为 wb
的新变量,如果它已经存在...那么很明显工作簿 wb
永远不会被保存或关闭。
我在您的 else
子句中添加了以下几行,并且即使使用您的程序 运行 也能够正确打开文件。很明显,您可能稍后会在代码中的某处保存和关闭该文件,但它不是您在此 else
子句中打开的文件。
else {
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
wb.Save();
wb.Close();
excelApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
}
希望这是有道理的。
老实说,我不确定发生了什么,但我有两个观察结果:
- 您打开 Excel 两次 -- 这似乎是肯定的。一个实例是
xlApp
,另一个实例是 excelApp
。如果您在 excelApp
实例化时打开任务管理器,我很确定您会发现 Excel 运行 的两个实例。我不知道这是否与您的问题有关
- 我总是发现在调试时让 Excel 可见很有帮助。您始终可以在部署之前注释该行,但在调试期间它很好,因为在调试期间公开 COM 对象不如本机 .NET 对象有用——这样您就可以看到它的本机形式
我 运行 您的代码版本进行了这些更改,更改命名 运行ge "gv_epxsize."
的单元格值没有问题
string filePath = "C:\Users\ussatdafa\Desktop\Work\Projects\test.xlsx";
Microsoft.Office.Interop.Excel.Application excelApp =
new Microsoft.Office.Interop.Excel.Application();
if (excelApp == null)
{
MessageBox.Show("Excel has not been properly installed");
}
else
{
excelApp.Visible = true;
Workbook wb = excelApp.Workbooks.Open(filePath, 0, false, 5, "", "", false,
XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = wb.Sheets[1];
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
}
这对我来说完美无缺。这是证明:
所以这让我想到了几种可能性:
(Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
不是你想的那样。或者,它可能与我使用的不一样,它是:
Worksheet ws = wb.Sheets[1];
这将 return 第一个工作表("Sheet1" 在新工作簿上)。
当然,打开两个 Excel 可能会导致问题。
我有一个 Excel 工作簿 ("test.xlsx"),其中有一个名为 "gv_epxsize" 的单元格。我的目标是打开 excel 工作簿并在名称为 "gv_epxsize".
的单元格中写下字符串“101”问题是我的代码一直将文件设置为只读,因此它不会将字符串“101”写入指定的单元格。我不断收到 windows 提示,提示我已经使用 Windows 权限打开文件,并询问我是否要打开只读副本。问题是我没有打开文件,在启动代码之前没有 EXCEL.EXE 进程 运行ning。
我已经做过的事情:
- 我已将文件以不同的名称保存在不同的文件夹中 - 仍然没有成功。
- 文件未保存在共享文件夹中。
- 我已经确保我的 TaskManager 在我 运行 我的代码之前杀死了每个 EXCEL.EXE 进程。
有人可以告诉我我做错了什么吗?
这是 C# 的片段
string filePath = "C:\Users\ussatdafa\Desktop\Work\Projects\test.xlsx";
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
MessageBox.Show("Excel has not been properly installed");
}
else
{
//string fileName = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), filePath);
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
}
我很确定您的问题出在保存文件的代码中。从您发布的代码中,有一件事实际上不起作用,可以解释您的问题。看看下面的片段:
else {
//string fileName = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), filePath);
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
}
这是 if (xlApp == null)
语句的 else
部分。首先,在此 else
部分中,您将创建一个名为 excelApp
的新 Excel 应用程序,其中:
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
您为什么要这样做是未知的,因为您之前已经创建了一个名为 xlApp
的文件。但这仍然可以;您可以打开多个 Excel 应用程序。
然后打开文件并进行更改:
Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
您使用 filePath
打开工作簿并调用工作簿 wb
。然后抓取 wb
中的第一个 sheet 并将其分配给工作 sheet 变量 ws
。请记住,您在此 else
子句中打开了工作簿。对工作簿进行更改,然后退出 else
子句。一切似乎都正常,除了……因为我们已经退出了 else
子句……excelApp
、wbs
、wb
和 ws
变量不再存在。即使您尝试在 else
子句之外保存或关闭文件,您也无法引用它,因为您在 else
子句内创建了这些变量。
因为你不能创建一个名为 wb
的新变量,如果它已经存在...那么很明显工作簿 wb
永远不会被保存或关闭。
我在您的 else
子句中添加了以下几行,并且即使使用您的程序 运行 也能够正确打开文件。很明显,您可能稍后会在代码中的某处保存和关闭该文件,但它不是您在此 else
子句中打开的文件。
else {
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks wbs = excelApp.Workbooks;
Workbook wb = wbs.Open(filePath, 0, false, 5, "", "", false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
wb.Save();
wb.Close();
excelApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
}
希望这是有道理的。
老实说,我不确定发生了什么,但我有两个观察结果:
- 您打开 Excel 两次 -- 这似乎是肯定的。一个实例是
xlApp
,另一个实例是excelApp
。如果您在excelApp
实例化时打开任务管理器,我很确定您会发现 Excel 运行 的两个实例。我不知道这是否与您的问题有关 - 我总是发现在调试时让 Excel 可见很有帮助。您始终可以在部署之前注释该行,但在调试期间它很好,因为在调试期间公开 COM 对象不如本机 .NET 对象有用——这样您就可以看到它的本机形式
我 运行 您的代码版本进行了这些更改,更改命名 运行ge "gv_epxsize."
的单元格值没有问题string filePath = "C:\Users\ussatdafa\Desktop\Work\Projects\test.xlsx";
Microsoft.Office.Interop.Excel.Application excelApp =
new Microsoft.Office.Interop.Excel.Application();
if (excelApp == null)
{
MessageBox.Show("Excel has not been properly installed");
}
else
{
excelApp.Visible = true;
Workbook wb = excelApp.Workbooks.Open(filePath, 0, false, 5, "", "", false,
XlPlatform.xlWindows, "", true, false, 0, true, false, false);
Worksheet ws = wb.Sheets[1];
wb.Names.Item("gv_epxsize").RefersToRange.Value = "101";
}
这对我来说完美无缺。这是证明:
所以这让我想到了几种可能性:
(Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);
不是你想的那样。或者,它可能与我使用的不一样,它是:
Worksheet ws = wb.Sheets[1];
这将 return 第一个工作表("Sheet1" 在新工作簿上)。
当然,打开两个 Excel 可能会导致问题。