使用工作表

本文关键字:工作 | 更新日期: 2023-09-27 18:20:42

我正在使用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开始。在Excel中,集合从1开始(可能有例外)。

我同意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();
        }
    }
}

当你在C#中使用Excel时,作为一名程序员,你必须以不同于常规的方式思考。

在Excel中,每个索引都以1开头,而不是以0开头。