我正在使用Microsoft Excel 15.0对象库并以这种方式打开.xlsx文件:
static void readDirection(String path)
{
Application excel = new Application();
Workbook wb = excel.Workbooks.Open(path);
foreach (Worksheet temp in wb.Worksheets)
{
Console.WriteLine(temp.Name + " | index:" + temp.Index);
}
Console.WriteLine(wb.Worksheets.Count);
}
由于只有一个标签,所以写了:
TabName | index:1
1
但是为什么索引1中唯一的标签而不是0?当我尝试Console.WriteLine("name"+wb.Worksheets[0].Name);
时
我得到了例外:
System.Runtime.InteropServices.COMException
答案 0 :(得分:0)
因为并非每种语言中的每个序列都从0开始。在Excel集合中从1开始(可能有例外)。
答案 1 :(得分:0)
我同意Cetin,
这是一个展示索引表的示例。第二类是对第一个代码块的支持
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelHelper
{
public class ExcelInfo
{
public Exception LastException { get; set; }
private List<ExcelReferenceTable> mReferenceTables;
/// <summary>
/// List of reference tables
/// </summary>
/// <value></value>
/// <returns></returns>
/// <remarks></remarks>
public List<ExcelReferenceTable> ReferenceTables
{
get
{
return mReferenceTables;
}
}
private string[] Extensions = { ".xls", ".xlsx" };
private string mFileName;
/// <summary>
/// Valid/existing Excel file name to work with.
/// </summary>
/// <value></value>
/// <returns></returns>
/// <remarks></remarks>
public string FileName
{
get
{
return mFileName;
}
set
{
if (!(Extensions.Contains(System.IO.Path.GetExtension(value.ToLower()))))
{
throw new Exception("Invalid file name");
}
mFileName = value;
}
}
private List<string> mNameRanges = new List<string>();
/// <summary>
/// List of named ranges in current file
/// </summary>
/// <value></value>
/// <returns></returns>
/// <remarks></remarks>
public List<string> NameRanges
{
get
{
return mNameRanges;
}
}
private List<string> mSheets = new List<string>();
/// <summary>
/// List of work sheets in current file
/// </summary>
/// <value></value>
/// <returns></returns>
/// <remarks></remarks>
public List<string> Sheets
{
get
{
return mSheets;
}
}
private Dictionary<Int32, string> mSheetsData = new Dictionary<Int32, string>();
public Dictionary<Int32, string> SheetsData
{
get
{
return mSheetsData;
}
}
public ExcelInfo()
{
}
/// <summary>
/// File to get information from
/// </summary>
/// <param name="FileName"></param>
/// <remarks>
/// The caller is responsible to ensure the file exists.
/// </remarks>
public ExcelInfo(string FileName)
{
this.FileName = FileName;
}
/// <summary>
/// Retrieve worksheet and name range names.
/// </summary>
/// <returns></returns>
/// <remarks></remarks>
public bool GetInformation()
{
bool Success = true;
if (!(System.IO.File.Exists(FileName)))
{
Exception ex = new Exception("Failed to locate '" + FileName + "'");
this.LastException = ex;
throw ex;
}
mSheets.Clear();
mNameRanges.Clear();
mSheetsData.Clear();
if (mReferenceTables != null)
{
mReferenceTables.Clear();
}
Excel.Application xlApp = null;
Excel.Workbooks xlWorkBooks = null;
Excel.Workbook xlWorkBook = null;
Excel.Workbook xlActiveRanges = null;
Excel.Names xlNames = null;
Excel.Sheets xlWorkSheets = null;
try
{
xlApp = new Excel.Application();
xlApp.DisplayAlerts = false;
xlWorkBooks = xlApp.Workbooks;
xlWorkBook = xlWorkBooks.Open(FileName);
xlActiveRanges = xlApp.ActiveWorkbook;
xlNames = xlActiveRanges.Names;
for (int x = 1; x <= xlNames.Count; x++)
{
Excel.Name xlName = xlNames.Item(x);
mNameRanges.Add(xlName.Name);
Marshal.FinalReleaseComObject(xlName);
xlName = null;
}
xlWorkSheets = xlWorkBook.Sheets;
for (int x = 1; x <= xlWorkSheets.Count; x++)
{
Excel.Worksheet Sheet1 = (Excel.Worksheet)xlWorkSheets[x];
mSheets.Add(Sheet1.Name);
mSheetsData.Add(x, Sheet1.Name);
Marshal.FinalReleaseComObject(Sheet1);
Sheet1 = null;
}
GetReferenceTables(xlWorkSheets);
ReleaseComObject(xlWorkSheets);
xlWorkBook.Close();
xlApp.UserControl = true;
xlApp.Quit();
}
catch (Exception ex)
{
this.LastException = ex;
Success = false;
}
finally
{
if (xlWorkSheets != null)
{
Marshal.FinalReleaseComObject(xlWorkSheets);
xlWorkSheets = null;
}
if (xlNames != null)
{
Marshal.FinalReleaseComObject(xlNames);
xlNames = null;
}
if (xlActiveRanges != null)
{
Marshal.FinalReleaseComObject(xlActiveRanges);
xlActiveRanges = null;
}
if (xlActiveRanges != null)
{
Marshal.FinalReleaseComObject(xlActiveRanges);
xlActiveRanges = null;
}
if (xlWorkBook != null)
{
Marshal.FinalReleaseComObject(xlWorkBook);
xlWorkBook = null;
}
if (xlWorkBooks != null)
{
Marshal.FinalReleaseComObject(xlWorkBooks);
xlWorkBooks = null;
}
if (xlApp != null)
{
Marshal.FinalReleaseComObject(xlApp);
xlApp = null;
}
}
return Success;
}
private List<ExcelReferenceTable> GetReferenceTables(Excel.Sheets xlWorkSheets)
{
List<ExcelReferenceTable> Result = new List<ExcelReferenceTable>();
string Temp = "";
Excel.Worksheet xlWorkSheet = null;
Excel.ListObjects xlListObjects = null;
Excel.ListObject ThisItem = null;
for (int x = 1; x <= xlWorkSheets.Count; x++)
{
ExcelReferenceTable Item = new ExcelReferenceTable();
xlWorkSheet = (Excel.Worksheet)xlWorkSheets[x];
xlListObjects = xlWorkSheet.ListObjects;
Int32 TotalCount = xlListObjects.Count - 1;
for (int y = 0; y <= TotalCount; y++)
{
ThisItem = xlListObjects.Item[y + 1];
Item.Name = ThisItem.Name;
Item.SheetName = xlWorkSheet.Name;
// TODO: Need to tinker with this.
try
{
Excel.QueryTable QT = ThisItem.QueryTable;
Item.SourceDataFile = QT.SourceDataFile;
ReleaseComObject(QT);
}
catch (Exception)
{
Item.SourceDataFile = "";
}
Excel.Range ThisRange = ThisItem.Range;
Temp = ThisRange.Address;
Item.Address = Temp.Replace("$", "");
Result.Add(Item);
Marshal.FinalReleaseComObject(ThisRange);
ThisRange = null;
Marshal.FinalReleaseComObject(ThisItem);
ThisItem = null;
Marshal.FinalReleaseComObject(xlListObjects);
xlListObjects = null;
}
}
ReleaseComObject(xlWorkSheet);
mReferenceTables = Result;
return Result;
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <remarks>
/// Generally speaking we should not have to call
/// GC.Collect() but about one percent of the time
/// Excel will refuse to release an object dependency
/// thus no choice but to call GC.Collect(). Please
/// make every effort to use ReleaseComObjectClean
/// rather than this procedure unless a object refuses
/// to release.
/// </remarks>
private void ReleaseComObject(object obj)
{
try
{
Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception)
{
obj = null;
}
finally
{
GC.Collect();
}
}
public void ReleaseComObjectClean(object obj)
{
try
{
Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception)
{
obj = null;
}
}
}
}
支持班级
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ExcelHelper
{
public class ExcelReferenceTable
{
public string Name { get; set; }
public string SheetName { get; set; }
public string Address { get; set; }
public string SelectString
{
get
{
return "SELECT * FROM [" + SheetName + "$" + Address + "]";
}
}
public string SourceDataFile { get; set; }
[System.Diagnostics.DebuggerStepThrough()]
public ExcelReferenceTable()
{
}
public override string ToString()
{
return Name;
}
}
}
使用示例
using ExcelHelper;
using System;
using System.Data;
using System.Data.OleDb;
using System.Linq;
namespace ExcelHelperTest
{
internal class Program
{
private static void Main(string[] args)
{
demo1();
ExcelInfo Helper = new ExcelInfo();
Helper.FileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "File1.xlsx");
Console.WriteLine(Helper.FileName);
if (Helper.GetInformation())
{
var SheetNames = Helper.Sheets;
Console.WriteLine("Sheet names");
foreach (var Sheet in SheetNames)
{
Console.WriteLine(Sheet);
}
Console.WriteLine();
var ReferenceTables = Helper.ReferenceTables;
if (ReferenceTables !=null)
{
Console.WriteLine("Reference tables");
foreach (var item in ReferenceTables)
{
Console.WriteLine(item);
}
}
else
{
Console.WriteLine("No reference tables found");
}
}
Console.ReadLine();
}
}
}
答案 2 :(得分:0)
当您在C#中使用Excel时,您必须采用与您作为程序员正常做法不同的方式进行思考。
在Excel中,每个索引都以1而不是0开头。