C# 导入Excel文件数据的几种方法

方法一:利用OleDb直接连接Excel文件进行读取数据。

//获取Excel路径
        string fileUrl = GetExcel(fuImportStudent);

        //适合老旧版本的xls文件
        const string cmdText = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1;\"";
        //适合新版的xlsx文件
        //const string cmdText = "Provider=Microsoft.Ace.OleDb.12.0;Data Source={0};Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'";

        System.Data.DataTable dt = null;
        //建立连接
        OleDbConnection connOleDb = new OleDbConnection(string.Format(cmdText, fileUrl));

        //打开连接
        if (connOleDb.State == ConnectionState.Broken || connOleDb.State == ConnectionState.Closed)
        {
            connOleDb.Open();
        }

        System.Data.DataTable schemaTable = connOleDb.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

        //获取Excel的第一个Sheet名称
        string sheetName = schemaTable.Rows[0]["TABLE_NAME"].ToString().Trim();

        //查询sheet中的数据
        string strSql = "select * from [" + sheetName + "]";
        OleDbDataAdapter da = new OleDbDataAdapter(strSql, connOleDb);
        DataSet ds = new DataSet();
        da.Fill(ds);
        //将Excel数据转写成DataTable
        dt = ds.Tables[0];

        //关闭连接
        connOleDb.Close();

        if (dt.Rows.Count > 0)
        {
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                //这里进行写入数据库操作
                //获取数据:dt.Rows[i]["表头名称"].ToString()
            }
        }

如果是用Microsoft.Jet.OLEDB.4.0连接的,需要设置IIS允许32位程序:

优点:适合简单固定格式的Excel表格,只要表头名称对上就行,不用管顺序问题。

缺点:如果直接读取MyXls导出的Excel会出现只能读取第一列的问题(重新编辑一下或者另存xls又可以解决这个问题)。

方法二:利用MyXls读取Excel数据。

        //获取Excel路径
        string fileUrl = GetExcel(fuImportContact);

        //加载要导入的Excel
        XlsDocument xls = new XlsDocument(fileUrl);
        //获得Excel中的指定一个工作页
        Worksheet sheet = xls.Workbook.Worksheets[0];
        //读取数据 循环每sheet工作页的每一行,不读取前1行
        for (int i = 2; i < sheet.Rows.Count; i++)
        {
            //这里进行写入数据库操作
            //获取数据:sheet.Rows[ushort.Parse(i.ToString())].GetCell(1).Value.ToString()
        }

优点:不依赖服务器,可以读取MyXls导出的Excel文件。

缺点:必须按照Excel列的顺序获取字段数据,对时间格式要求严格,会出现数字格式的日期,需要转换一下。如果列的数据为空也可能导致读取不了列的情况,比较不稳定。

方法三:调用Microsoft.Office.Interop.Excel组件读取Excel数据。

Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();

            Microsoft.Office.Interop.Excel.Workbook workbook;

            Microsoft.Office.Interop.Excel.Worksheet worksheet;

            object oMissing = System.Reflection.Missing.Value;//相当null

            workbook = excel.Workbooks.Open(filename, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);

            worksheet = (Worksheet)workbook.Worksheets[1];

            //int rowCount = int.Parse(txtRow1.Text.Trim()) + 1;// worksheet.UsedRange.Rows.Count;

            int colCount = worksheet.UsedRange.Columns.Count;

            Microsoft.Office.Interop.Excel.Range range1;

            System.Data.DataTable dt = new System.Data.DataTable();

            for (int i = 0; i < colCount; i++)
            {
                range1 = worksheet.Range[worksheet.Cells[1, i + 1], worksheet.Cells[1, i + 1]];

                if (range1.Value2 != null)
                {
                    dt.Columns.Add(range1.Value2.ToString());
                }
            }

            for (int j = 1; j < rowCount; j++)
            {
                SetCount(j, label);

                DataRow dr = dt.NewRow();

                for (int i = 0; i < colCount; i++)
                {
                    range1 = worksheet.Range[worksheet.Cells[j + 1, i + 1], worksheet.Cells[j + 1, i + 1]];

                    if (range1.Value2 != null)
                    {
                        dr[i] = range1.Value2.ToString();
                    }
                }

                dt.Rows.Add(dr);

            }

            excel.Quit();

        if (dt.Rows.Count > 0)
        {
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                //这里进行写入数据库操作
                //获取数据:dt.Rows[i]["表头名称"].ToString()
            }
        }

优点:可以读取复杂的Excel表格数据,读取列时不用管顺序。

缺点:依赖服务器组件,服务器需要安装Excel组件。

如果遇到时间字段变成数字,如:

需要转换一下:

private string ToDateTimeValue(string strNumber)
        {
            if (!string.IsNullOrWhiteSpace(strNumber))
            {
                Decimal tempValue;
                //先检查 是不是数字;
                if (Decimal.TryParse(strNumber, out tempValue))
                {
                    //天数,取整
                    int day = Convert.ToInt32(Math.Truncate(tempValue));
                    //这里也不知道为什么. 如果是小于32,则减1,否则减2
                    //日期从1900-01-01开始累加 
                    // day = day < 32 ? day - 1 : day - 2;
                    DateTime dt = new DateTime(1900, 1, 1).AddDays(day < 32 ? (day - 1) : (day - 2));

                    //小时:减掉天数,这个数字转换小时:(* 24) 
                    Decimal hourTemp = (tempValue - day) * 24;//获取小时数
                                                              //取整.小时数
                    int hour = Convert.ToInt32(Math.Truncate(hourTemp));
                    //分钟:减掉小时,( * 60)
                    //这里舍入,否则取值会有1分钟误差.
                    Decimal minuteTemp = Math.Round((hourTemp - hour) * 60, 2);//获取分钟数
                    int minute = Convert.ToInt32(Math.Truncate(minuteTemp));
                    //秒:减掉分钟,( * 60)
                    //这里舍入,否则取值会有1秒误差.
                    Decimal secondTemp = Math.Round((minuteTemp - minute) * 60, 2);//获取秒数
                    int second = Convert.ToInt32(Math.Truncate(secondTemp));

                    //时间格式:00:00:00
                    string resultTimes = string.Format("{0}:{1}:{2}",
                            (hour < 10 ? ("0" + hour) : hour.ToString()),
                            (minute < 10 ? ("0" + minute) : minute.ToString()),
                            (second < 10 ? ("0" + second) : second.ToString()));

                    if (day > 0)
                        return string.Format("{0} {1}", dt.ToString("yyyy-MM-dd"), resultTimes);
                    else
                        return resultTimes;
                }
            }
            return string.Empty;
        }

猜你喜欢

转载自blog.csdn.net/mojocube/article/details/104532469