C# for Excel

C# excel 文件读写

环境配置及入门

在使用c#读写excel文件时踩了不少坑,首先使用的是Microsoft.Office.Interop.Excel;
vs中没有的话,可以直接在Nuget中安装,搜索Excel找到Interop安装下载量最高的就可以,在初次运行时,一直报

QueryInterface 因以下错误而失败: 库没有注册。 (异常来自 HRESULT:0x8002801D (TYPE_E_LIBNOTREGISTERED)

这样的错误,网路上有不少人说是安装了新版本再回退到旧版本office导致的,但我只装过一个office16,在对应的注册表修改项中也没有找到对应其他版本,只有一个1.9的,我删了也没有作用(删除前最好备份注册表,以便回滚), 试了一圈,最后发现是wps的问题,需要安装wps(你没听错,是wps),再运行vs 程序就不报错了,后面再把wps删了,最好用win自带的删除功能删除,之后就一直都可以了
在之后我把excel的功能封装起来,如下

public class Excel_Control
    {

        /// <summary>
        /// 简单操作Excel文件
        /// </summary>
        /// <param name="excelPath">excel 文件路径</param>
        /// <returns></returns>
        public static List<List<string>> ExcelOp(string excelPath)
        {
            string ExcelFilePath = excelPath.Trim();
            List<List<string>> excel_list = new List<List<string>>();
            //set columns
            Excel.Application excel = new Excel.Application();
            Excel.Workbook wb = null;
            excel.Visible = false;//设置调用引用的 Excel文件是否可见
            excel.DisplayAlerts = false;
            wb = excel.Workbooks.Open(ExcelFilePath);
            Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1]; //索引从1开始 //(Excel.Worksheet)wb.Worksheets["SheetName"];
            int rowCount = 0;//有效行,索引从1开始
            try
            {
                rowCount = ws.UsedRange.Rows.Count;//赋值有效行

                for (int i = 2; i <= rowCount; i++)//从第二行开始读取,需要的可以设为1
                {
                    List<string> data = new List<string>();
                    if (ws.Rows[i] != null)
                    {
                        for (int j = 1; j <= ws.UsedRange.Columns.Count; j++)
                        {
                            data.Add(ws.Cells[i, j].Value2.ToString());//获取每一单元格的数据
                        }
                    }
                    excel_list.Add(data);
                }


            }
            catch (Exception ex) { Console.WriteLine(ex.ToString()); }
            finally
            {
                ClosePro(excelPath, excel, wb);
            }
            return excel_list;//返回读取的数据
        }


        /// <summary>
        /// 关闭Excel进程
        /// </summary>
        /// <param name="excelPath"></param>
        /// <param name="excel"></param>
        /// <param name="wb"></param>
        public static void ClosePro(string excelPath, Excel.Application excel, Excel.Workbook wb)
        {
            Process[] localByNameApp = Process.GetProcessesByName(excelPath);//获取程序名的所有进程
            if (localByNameApp.Length > 0)
            {
                foreach (var app in localByNameApp)
                {
                    if (!app.HasExited)
                    {
                        #region
                        设置禁止弹出保存和覆盖的询问提示框   
                        //excel.DisplayAlerts = false;
                        //excel.AlertBeforeOverwriting = false;

                        保存工作簿   
                        //excel.Application.Workbooks.Add(true).Save();
                        保存excel文件   
                        //excel.Save("D:" + "\\test.xls");
                        确保Excel进程关闭   
                        //excel.Quit();
                        //excel = null; 
                        #endregion
                        app.Kill();//关闭进程  
                    }
                }
            }
            if (wb != null)
                wb.Close(true, Type.Missing, Type.Missing);
            excel.Quit();
            // 安全回收进程
            System.GC.GetGeneration(excel);
        }
    }

参考
(已解决)Win10+Office2016报错:库没有注册,HRESULT:0x8002801D
C#读写Excel的几种方法
C# 使用自带Microsoft.Office.Interop.Excel简单操作Excel文件

遇到的其他问题

使用Interop.excel读写文件,在读取时间时遇到问题,表格时间数据在默认显示时是正常的,但如果切换成文本,则会变成一串整型数据,发现对于这类数据,要使用转换类进行转换,可以使用datatime.TryParse来直接转化,或者使用DateTime.FromOADate(ws.Cells[i, j].Value2),效果都是一样的。后者最好标记好要转化的数据在表格的位置,此外,在另存时要记得设置保存格式,特别是对应xls文件时,最后别忘了关闭打开的应用句柄

public class Excel_Control
    {
        private const int OLDOFFICEVESION = -4143;
        private const int NEWOFFICEVESION = 56;

        /// <summary>
        /// 读取Excel文件
        /// </summary>
        /// <param name="excelPath">excel 文件路径</param>
        /// <param name="datatime_indexs">时间格的位置</param>
        /// <returns></returns>
        public static List<List<string>> ExcelOp(string excelPath, List<int> datatime_indexs = null)
        {
            string ExcelFilePath = excelPath.Trim();
            List<List<string>> excel_list = new List<List<string>>();
            //set columns
            Excel.Application excel = new Excel.Application();
            Excel.Workbook wb = null;
            excel.Visible = false;//设置调用引用的 Excel文件是否可见
            excel.DisplayAlerts = false;
            wb = excel.Workbooks.Open(ExcelFilePath);
            Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1]; //索引从1开始 //(Excel.Worksheet)wb.Worksheets["SheetName"];
            int rowCount = 0;//有效行,索引从1开始
            try
            {
                rowCount = ws.UsedRange.Rows.Count;//赋值有效行

                for (int i = 2; i <= rowCount; i++)//从第二行开始读取,需要的可以设为1
                {
                    List<string> data = new List<string>();
                    if (ws.Rows[i] != null)
                    {
                        for (int j = 1; j <= ws.UsedRange.Columns.Count; j++)
                        {
                            if (datatime_indexs != null && datatime_indexs.Contains(j))
                            {
                                data.Add(DateTime.FromOADate(ws.Cells[i, j].Value2).ToString());//获取转换后的时间数据
                            }
                            else
                                data.Add(ws.Cells[i, j].Value2.ToString());//获取每一单元格的数据
                        }
                    }
                    excel_list.Add(data);
                }


            }
            catch (Exception ex) { Console.WriteLine(ex.ToString()); }
            finally
            {
                ClosePro(excelPath, excel, wb);
            }
            return excel_list;//返回读取的数据
        }


        /// <summary>
        /// 写入excel
        /// </summary>
        /// <param name="excelPath">excel保存文件路径,不用填写后缀</param>
        /// <returns></returns>
        public static void WriteExcel(string filePath, List<List<string>> datas)
        {
            //保存excel文件的格式
            int FormatNum;
            //excel版本号
            string Version;
            List<List<string>> excel_list = new List<List<string>>();
            //set columns
            Excel.Application excel = new Excel.Application();//启动应用
            Excel.Workbooks workbooks = excel.Workbooks;//创建文件
            Excel.Workbook workbook = workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);//添加表模板
            Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];//添加表一
            excel.Visible = false;//设置调用引用的 Excel文件是否可见
            excel.DisplayAlerts = false;

            //获取你使用的excel 的版本号
            Version = excel.Version;
            //使用Excel 97-2003
            if (Convert.ToDouble(Version) < 12)
            {
                FormatNum = OLDOFFICEVESION;
            }
            //使用 excel 2007或更新
            else
            {
                FormatNum = NEWOFFICEVESION;
            }

            int row = 1;
            foreach (var data in datas)
            {
                int i = 1;
                foreach (var d in data)
                {
                    worksheet.Cells[row, i++] = d;
                }
                row++;
            }

            if (File.Exists(filePath))//删除已经存在的文件
            {
                try
                {
                    File.Delete(filePath);
                }
                catch (IOException e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            //保存,这里必须指定FormatNum文件的格式,否则无法打开创建的excel文件
            workbook.SaveAs(filePath, FormatNum);
            ClosePro(filePath, excel, workbook);
        }

        /// <summary>
        /// 关闭Excel进程
        /// </summary>
        /// <param name="excelPath"></param>
        /// <param name="excel"></param>
        /// <param name="wb"></param>
        public static void ClosePro(string excelPath, Excel.Application excel, Excel.Workbook wb)
        {
            Process[] localByNameApp = Process.GetProcessesByName(excelPath);//获取程序名的所有进程
            if (localByNameApp.Length > 0)
            {
                foreach (var app in localByNameApp)
                {
                    if (!app.HasExited)
                    {
                        #region
                        设置禁止弹出保存和覆盖的询问提示框   
                        //excel.DisplayAlerts = false;
                        //excel.AlertBeforeOverwriting = false;

                        保存工作簿   
                        //excel.Application.Workbooks.Add(true).Save();
                        保存excel文件   
                        //excel.Save("D:" + "\\test.xls");
                        确保Excel进程关闭   
                        //excel.Quit();
                        //excel = null; 
                        #endregion
                        app.Kill();//关闭进程  
                    }
                }
            }
            if (wb != null)
                wb.Close(true, Type.Missing, Type.Missing);
            excel.Quit();
            // 安全回收进程
            System.GC.GetGeneration(excel);
        }
    }

参考
C# Microsoft.Office.Interop.Excel读取excel中的日期问题
C#利用Microsoft.Office.Interop.Excel导出excel文件
C# 打开和保存文件对话框

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值