C#读取Excel数据丢失问题的解决方法

最近发现在Excel数据中的某一列存在日期和字母混合类型的数据时,C#读取到的Excel的数据将非日期类型的数据丢失了,读到的全部为“null”值,这个问题纠结了半天,在网上找到了解决方法。

方法一:

更新Excel的连接字符串:

之前的:{0}和{1}占位符分别为:Excel文件的路径和版本信息。

 private const string ConnectionStringTemplate = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source ={0};Extended Properties=Excel {1}; ";

应该更新为:

 private const string ConnectionStringTemplate = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source ={0};Extended Properties='Excel {1};IMEX=1' ";

这里大家请注意,之前在网上看到很多的也是这种解决方法,可是连接字符串的此部分:

Extended Properties='Excel {1};IMEX=1'

少了单引号,导致程序一直会出现“未找到可安装的ISAM”的异常,后来加上就解决了空值的问题了。不过这种方法,默认对于该列的前8条数据必须为混合型,该列才会作为混合型数据处理,否则只取前8条对于的数据类型。

改进方法 :

我还看到的一些改进的措施是IMEX=1与注册表值TypeGuessRows配合使用

TypeGuessRows 值决定了ISAM 驱动程序从前几条数据采样确定数据类型,默认为“8”。可以通过修改“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel”下的该注册表值来更改采样行数。但是这种改进还是没有根本上解决问题,即使我们把IMEX设为“1”, TypeGuessRows设得再大,例如1000,假设数据表有1001行,某列前1000行全为纯数字,该列的第1001行又是一个文本,ISAM驱动的这种机制还是让这列的数据变成空。

所以此方法适合确定多少行肯定为混合型的数据的Excel文件。

方法二:

在之前一直不知方法一问题出在哪的时候,尝试其它的解决方法,想到是否可以直接打开excel文件,逐行读取Excel数据的方法,很庆幸这个也可以达到期望的效果。不过,有个缺点就是,此方法执行需要花费较多的时间。具体方法如下,仅供参考:

        /// <summary>
        /// 直接打开Excel,逐行读取数据
         /// </summary>
        /// <param name="strPath">Excel文件路径</param>
        /// <param name="strName">读取的表名</param>
        /// <param name="lable">label进度</param>
        /// <returns>Excel数据存入的DataTable</returns>
        public static DataTable Excel2DataTableDirect(string strPath, string strName, Label lable)
        {
            Excel.Application excel = null;
            Excel.Workbooks wbs = null;
            Excel.Workbook wb = null;
            Excel.Worksheet ws = null;
            Excel.Range range1 = null;
            object Nothing = System.Reflection.Missing.Value;
            DataTable dt = new DataTable();

            excel = new Excel.Application();
            excel.UserControl = true;
            excel.DisplayAlerts = false;

            excel.Application.Workbooks.Open(strPath, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing);

            wbs = excel.Workbooks;
            wb = wbs[1];
            ws = (Excel.Worksheet)wb.Worksheets[strName];

            //获取行数
            int rowCount = ws.UsedRange.Rows.Count;

            //获取列数
            int colCount = ws.UsedRange.Columns.Count;

            if (rowCount <= 0)
                MessageBox.Show("此Excel为空!");
            if (colCount < 33)
                MessageBox.Show("此Excel列数不对!");


            //循环给DataTable数据赋值
            for (int i = 1; i <= rowCount; i++)
            {
                DataRow dr = dt.NewRow();
                for (int j = 1; j < 33; j++)
                {

                    range1 = ws.Range[ws.Cells[i, j], ws.Cells[i, j]];
                    //range1 = ws.get_Range(ws.Cells[i, j], ws.Cells[i, j]);
                    if (i == 1)
                        dt.Columns.Add((string)range1.Value);
                    dr[j - 1] = range1.Value;


                }
                lable.Text = "Importing lines:" + i + "/" + rowCount;
                dt.Rows.Add(dr);
            }


            //释放Excel
            if (excel != null)
            {
                if (wbs != null)
                {
                    if (wb != null)
                    {
                        if (ws != null)
                        {
                            if (range1 != null)
                            {
                                System.Runtime.InteropServices.Marshal.ReleaseComObject(range1);
                                range1 = null;
                            }
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
                            ws = null;
                        }
                        wb.Close(false, Nothing, Nothing);
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
                        wb = null;
                    }
                    wbs.Close();
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(wbs);
                    wbs = null;
                }
                excel.Application.Workbooks.Close();
                excel.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
                excel = null;
                GC.Collect();

            }
            return dt;

        }

 

 


 

 

posted @ 2012-05-08 13:19  IT女汉纸  阅读(1462)  评论(0编辑  收藏  举报