C#使用OLEDB的方式读写Excel

在C#中读取Excel的方式有很多种,下面使用OLEDB的方式:

优点:

        1.简单快速,能够操作高版本Excel

        2.可以直接使用SQL语句操作数据

        3.不需要安装Office Excel

缺点:

        1.Excel的数据量不能过大,当内存不够时会抛出内存溢出的异常。

        2.不能灵活操作Excel,如设置单元格字体,颜色,格式等。

本文采用的是mvc的写法来进行

一:前端视图部分

1.首先在视图里引入jquery脚本文件,然后建立两个input标签,type一个为file,一个为button:

file用于选取导入的Excel,button用于提交到后台处理

<script src="~/Scripts/jquery-3.4.1.min.js"></script>

<input type="file" name="xlsfile" id="xlsfile" value="" />
<input type="button" name="import" id="import" value="import" />

2.然後使用Ajax的方式把文件提交到後台處理:

相应的代码都会有对应的注解

<script>
    $("#import").on("click", function () {
        // 创建一个 FormData 对象,用于将数据以键值对形式发送到服务器
        var formData = new FormData();
        //将 id 为 "xlsfile" 的 input 元素中选择的文件添加到 FormData 中
        formData.append("file", $("#xlsfile")[0].files[0]);
        // 将选定文件的文件名添加到 FormData 中
        formData.append("filename", $("#xlsfile")[0].files[0].name);
        $.ajax({
            //后台处理上传文件的URL
            url: "@Url.Action("import", "oledbDemo")",
            //必须使用POST的方式上传文件
            type: "POST",
            //提交到后台的数据
            data: formData,
             //不设置内容类型
            contentType: false,
            //不对数据进行序列化处理
            processData: false,
            //禁用缓存
            cache: false,
            //同步请求,等待请求完成后再执行后续操作
            async: false,
            //请求成功后的回调函数
            success: function (r) {
                //解析返回的 JSON 数据
                var json = JSON.parse(r)
                //在控制台输出返回的 JSON 数据,方便查看数据传递过来的数据
                console.log(json)
                //判断传递过来的参数
                if (json.state == "OK") {
                    alert("导入文件成功!!!")
                } else {
                    alert("导入失败,错误的地方为:" + json.alert)
                }
            }
        })
    })
</script>

二:后台控制器部分

1.创建方法,获取前端传入过来的参数:

“HttpPostedFileBase”类是用于表示通过HTTP POST请求上传的单个文件,接收前端传递过来的file值和filename值

public Object import(HttpPostedFileBase file, string filename){
    
}

2.对前端传递过来的参数进行处理:

保存文件在指定的路径:

//把文件保存在指定的路径
file.SaveAs(Server.MapPath("/Content/Excel/" + filename));

注:保存的路径需要相对路径,不能使用绝对路径,否则会报错,下图为绝对路径的报错情况

创建链接字符串:这里就是使用oledb的方式来读写Excel

//连接字符串
string strCon;
strCon = "Provider= Microsoft.ACE.OLEDB.12.0;Data Source=" + Server.MapPath("/Content/Excel/" + filename) + "; Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1;\";";

"Provider= Microsoft.ACE.OLEDB.12.0;":

这部分指定了使用的 OLE DB 提供程序,这里使用的是 Microsoft Office 12.0 Access Database Engine,可以使用的Excel格式为.xlsx和.xls

而“Microsoft.Jet.OLEDB.4.0”主要使用的格式为.xls

Data Source=: 指定数据源,即 Excel 文件的路径。这里使用了 Server.MapPath 方法将相对路径转换为服务器上的绝对路径

"Extended Properties="Excel 12.0;HDR=YES;IMEX=1;": 这部分是指定了连接的扩展属性,包括使用的 Excel 版本(此处为 Excel 12.0,即 Excel 2007及以上版本)

“HDR=YES”为是否包含表头( YES第一行是表头,NO不包含表头)、

以及强制使用文本格式导入:

        IMEX=0,开启的Excel文档只能用来做“写入”用途

        IMEX=1,开启的Excel文档只能用来做“读取”用途

        IMEX=2,可“写入”也可“读取”

这里使用的为读取Excel。

注:在使用oledb的时候,特别需要注意的是自己的电脑是属于32位的应用程式还是64位的应用程式

否則就可能会出出以下报错情況

        

解决办法:

        (1).进入IIS找到应用程序池,找到自己的网站,并打开高级设置

        (2).修改应用程式:

3.与数据库进行链接:

//引入oledb类,是用于与数据库进行链接的类
OleDbConnection con = new OleDbConnection(strCon);
//打开链接
con.Open();

//返回Excel的架构,包括各个sheet的名称,类型,创建时间,修改时间
DataTable dtSheetName = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });

4.获取Excel的表格数据:

因为我只需要一个表格的数据,所以这里做了判断

其中“FilterDatabase”的解释可以查看:https://blog.csdn.net/cmhdl521/article/details/105512818

//获取第0个表(索引从0开始)
string strTableName = dtSheetName.Rows[0]["TABLE_NAME"].ToString();

//判斷 表名中是否包含(FilterDatabase)
int TableNum = strTableName.IndexOf("FilterDatabase");
if (TableNum >= 1)
{
    strTableName = dtSheetName.Rows[1]["TABLE_NAME"].ToString();
}

5.查询获取到的Excel数据:

//查询Excel的数据
OleDbDataAdapter da = new OleDbDataAdapter($"select * from [{strTableName}]", con);
//将数据表转为集合
DataSet ds = new DataSet();
//把數據填充到dateset
da.Fill(ds);
//关闭链接
con.Close();

查询数据的时候,可以根据自己的需求去进行查询,逻辑跟SQL Server是一样的。没什么区别。

举几个例子:这个是举例数据

        (1).判断非空:

OleDbDataAdapter da = new OleDbDataAdapter($"select * from [{strTableName}] where Sex is not null", con);

得到的结果为李四性别列为空,所以排除掉。

        (2).当某一列数据有问题的时候找到并显示原因:

一般在SQL Server里是这样写的:

SELECT [Desc]=CASE when LEN(Name)>2 THEN N'名字不能大于2字符' ELSE N'符合' END, * FROM dbo.Student

 但是在oledb就是另外的写法:IIF(条件 , '条件为真' , '条件为假')

OleDbDataAdapter da = new OleDbDataAdapter($"select *,IIF(Age>17,'年龄不能大于17岁','正确') AS Remark FROM [{strTableName}]", con);

 这样的写法逻辑就跟三元运算的逻辑相当,当条件正确的时候返回的是左边的条件,否则为右边的条件

结果:

注:在使用第一行数据当做表头的时候,如果某列有空格的时候,需要使用[]包裹起来,这样才会被识别为一个整体,否则会出现错误。

OleDbDataAdapter da = new OleDbDataAdapter($"select * FROM [{strTableName}] order by [Cliss id] desc", con);

根据cliss id降序排序,结果为:

好了,到这里oledb的使用就已经结束了,接下来就要根据自己的需求进行下一步了

如果是把数据传送到页面的话:

有几个表就获取几个表的数据传送到视图即可。

//获取Dateset的第一个表
DataTable dt = ds.Tables[0];
//传值到前端进行展示
ViewBag.dt = dt;

如果是需要把数据导入到数据库的话:

直接定义需要添加字段的变量,然后循环添加即可。

//添加到数据库
var Name = "";
var Sex = "";
var Age = "";
var Classid = "";
string sql = "";
for (int i = 0; i < dt.Rows.Count; i++)
{
     Name = dt.Rows[i]["Name"].ToString();
     Sex = dt.Rows[i]["Sex"].ToString();
     Age = dt.Rows[i]["Age"].ToString();
     Classid = dt.Rows[i]["Class id"].ToString();

     sql = $"insert into Student (Name, Sex, Age, ClassId) values (N'{Name}','{Sex}','{Age}','{Classid}')";
     DBHelper.executeNonQuery(sql);
}

6.使用完毕后删除文件

因为我这里的写法是把文件保存到项目的路径里,所以为了防止导入的文件过多,每一次执行完毕后需要删除掉指定路径里的文件。 

//使用完后删除文件
string dirPath = Server.MapPath("/Content/Excel/" + filename);
System.IO.File.Delete(dirPath);

后台完整的代码如下:

        public Object import(HttpPostedFileBase file, string filename)
        {
            var result = new { state = "OK", alert = "成功" };
            try
            {
                //把文件保存在指定的路径
                file.SaveAs(Server.MapPath("/Content/Excel/" + filename));
                //连接字符串
                string strCon;
                strCon = "Provider= Microsoft.ACE.OLEDB.12.0;Data Source=" + Server.MapPath("/Content/Excel/" + filename) + "; Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1;\";";
                
                //引入oledb类,是用于与数据库进行链接的类
                OleDbConnection con = new OleDbConnection(strCon);
                //打开链接
                con.Open();

                //返回Excel的架构,包括各个sheet的名称,类型,创建时间,修改时间
                DataTable dtSheetName = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });

                //获取第0个表(索引从0开始)
                string strTableName = dtSheetName.Rows[0]["TABLE_NAME"].ToString();

                //判斷 表名中是否包含(FilterDatabase) 解释:https://blog.csdn.net/cmhdl521/article/details/105512818
                int TableNum = strTableName.IndexOf("FilterDatabase");
                if (TableNum >= 1)
                {
                    strTableName = dtSheetName.Rows[1]["TABLE_NAME"].ToString();
                }

                //查询Excel的数据
                OleDbDataAdapter da = new OleDbDataAdapter($"select * FROM [{strTableName}] order by [Class id] desc", con);
                //将数据表转为集合
                DataSet ds = new DataSet();
                //把數據填充到dateset
                da.Fill(ds);
                //关闭链接
                con.Close();

                //获取Dateset的第一个表
                DataTable dt = ds.Tables[0];
                //传值到前端进行展示
                ViewBag.dt = dt;

                //添加到数据库
                var Name = "";
                var Sex = "";
                var Age = "";
                var Classid = "";
                string sql = "";
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    Name = dt.Rows[i]["Name"].ToString();
                    Sex = dt.Rows[i]["Sex"].ToString();
                    Age = dt.Rows[i]["Age"].ToString();
                    Classid = dt.Rows[i]["Class id"].ToString();

                     sql = $"insert into Student (Name, Sex, Age, ClassId) values (N'{Name}','{Sex}','{Age}','{Classid}')";
                    DBHelper.executeNonQuery(sql);
                }

                //使用完后删除文件
                string dirPath = Server.MapPath("/Content/Excel/" + filename);
                System.IO.File.Delete(dirPath);
            }
            catch (Exception ex)
            {
                result = new { state = "Error", alert = ex.Message };
            }

            return JsonConvert.SerializeObject(result);
        }

全文完。

  • 25
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值