我正在尝试从一堆Excel文件中删除命名范围。
在代码运行时获取以下异常:
“无效的索引。(来自HRESULT的异常:0x8002000B(DISP_E_BADINDEX))”
尝试了所有我能想到的东西,但是excel实例不会退出!
请参见下面粘贴的代码。 Interop就像一场可怕的噩梦! :(
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace excel_delete_nr
{
class Program
{
static void Main(string[] args)
{
String tp_folder = @"C:\tp";
String[] tps = Directory.GetFiles(tp_folder);
foreach (String m in tps)
{
var xlApp = new Excel.Application();
var xlWorkbooks = xlApp.Workbooks;
var xlWorkbook = xlWorkbooks.Open(m);
var ranges = xlWorkbook.Names;
int leftoveritems = ranges.Count;
while (leftoveritems > 0)
{
int i = 1;
try
{
while (i <= leftoveritems)
{
xlWorkbook.Names.Item(i).Delete();
//System.Windows.Forms.MessageBox.Show(i + " deleted.");
i++;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
ranges = xlWorkbook.Names;
leftoveritems = ranges.Count;
}
xlWorkbook.Save();
xlWorkbook.Close();
xlWorkbooks.Close();
xlApp.Quit();
Marshal.ReleaseComObject(ranges);
Marshal.ReleaseComObject(xlWorkbook);
Marshal.ReleaseComObject(xlWorkbooks);
Marshal.ReleaseComObject(xlApp);
}
}
}
}
答案 0 :(得分:1)
我使用下面的代码。使用Interop时必须非常小心。
但是,如果您的任务如此简单,并且您知道所有文件都是新格式(理解Open XML),那么我会在不需要的地方使用OpenXML解决方案完全使用Excel,而且速度明显更快。在下面检查
using System;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;
using System.Runtime.InteropServices;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Which solution to use?\n1 - for running Excel or \n2 - for using OpenXML");
var result = Console.ReadLine();
if (string.IsNullOrWhiteSpace(result)) return;
String tp_folder = @"c:\tp\";
String[] tps = Directory.GetFiles(tp_folder);
if (result == "1")
{
DeleteNamesWithExcelApp(tps);
}
else if (result == "2")
{
var cls = new OpenXmlSolution();
foreach (String m in tps)
{
cls.RemoveNames(m);
}
}
Console.WriteLine("Done");
Console.ReadLine();
}
public static void DeleteNamesWithExcelApp(String[] tps)
{
Excel.Workbooks xlWorkbooks = null;
Excel.Workbook xlWorkbook = null;
Excel.Names ranges = null;
var xlApp = new Excel.Application();
try
{
foreach (String m in tps)
{
xlWorkbooks = xlApp.Workbooks;
xlWorkbook = xlWorkbooks.Open(m);
ranges = xlWorkbook.Names;
int leftoveritems = ranges.Count;
Excel.Name name = null;
try
{
for (int i = leftoveritems; i >= 1; i--)
{
name = xlWorkbook.Names.Item(i);
name.Delete();
if (name != null) Marshal.ReleaseComObject(name);
name = null;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (name != null) Marshal.ReleaseComObject(name);
}
if (xlWorkbook != null)
{
xlWorkbook.Close(true);
Marshal.ReleaseComObject(xlWorkbook);
xlWorkbook = null;
}
if (xlWorkbooks != null) Marshal.ReleaseComObject(xlWorkbooks);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (ranges != null) Marshal.ReleaseComObject(ranges);
if (xlWorkbook != null) Marshal.ReleaseComObject(xlWorkbook);
if (xlWorkbooks != null) Marshal.ReleaseComObject(xlWorkbooks);
if (xlApp != null)
{
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
xlApp = null;
}
}
}
}
}
这是我更喜欢的OpenXML解决方案。我真的不知道它在旧的xls文件中的表现如何。
using DocumentFormat.OpenXml.Packaging;
using System.Linq;
namespace ConsoleApp3
{
public class OpenXmlSolution
{
public void RemoveNames(string fullPathToFile)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fullPathToFile, true))
{
WorkbookPart wbPart = document.WorkbookPart;
var numOfNames = wbPart.Workbook.DefinedNames.Count();
if (numOfNames == 0) return;
for (int i = numOfNames -1 ; i >= 0; i--)
{
wbPart.Workbook.DefinedNames.ChildElements[i].Remove();
}
wbPart.Workbook.Save();
}
}
}
}