使用工作表

时间:2015-11-04 17:05:25

标签: c# excel office-interop comexception

我正在使用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

3 个答案:

答案 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开头。