欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Asp.net Core MVC 导出execl

程序员文章站 2024-02-27 21:28:45
...

Asp.net Core MVC 导出execl


分享话语

之前不知道做了多少导入导出文档的功能,最熟悉的就是 通过post提交到后台,后台语言来处理。不过遇到很坑,博文写的很少,还请大家多多指教,一起学习,共同进步。

来吧,先上图

Asp.net Core MVC 导出execl

说一下功能,点击导入,选择要导入的exel文档,把execl中的文档插入到数据库中,在显示到页面中

首先说一下思路哈

A 通过<input type='file'> 表单form 来提交文档到后台

B 后台接收文档,保存到服务器
C 对文档进行处理,拿到数据,存储到数据

前台代码

@*
    For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
    ViewData["Title"] = "经营计划";
    var date = ViewBag.dateTime;
}
@section Header{
   <style>
       tr td {
        border:1px solid black;
       }
       td {
       text-align:center;
       height:40px;
       }
       tbody input {
       width:100%;
       border:none;
       height:100%;
       text-align:center;
       }
       .boxtobdy {
        border:2px solid red;
       }
    </style>
}
<section class="content">

        <div class="box box-success condition">
            <div class="box-header with-border">
                <h5 class="box-title"><i class="fa fa-book"></i> 查询条件</h5>
            </div>
            <!-- 查询条件表单 -->
            <div class="box-body">
                <div class="row">

                    <input type="hidden" id="reportname" name="reportname" value="" />
                    <input type="hidden" id="htmlTableStr" name="htmlTableStr" value="" />
                    <div class="col-md-3">
                        <div class="input-group">
                            <div class="input-group-addon">
                                <i class="fa"><span>计划年份</span></i>
                            </div>
                            <div>
                                <input class="layui-input" id="datetime" name="datetime" value="@date" onfocus="WdatePicker({ dateFmt: 'yyyy', readOnly: true });" type="text">
                            </div>
                        </div>
                    </div>
                    <div class="col-md-1">
                        <button class="btn btn-primary" type="button" id="btnSearch"><i class='fa fa-search'></i>查询</button>
                    </div>
                    @*<div class="col-md-4">


                         <div class="input-group ">

                                  <input id="txt_Path" type="text" class="form-control">


                                  <span id="btn_Browse" style="cursor:pointer;" onclick="$('input[id=fileUpload]').click();" class="input-group-addon">
                                  <i class="glyphicon glyphicon-folder-open"></i>&nbsp;&nbsp;&nbsp;浏览文件
                            </span>

                        </div>

                    </div>*@


                    <div class="col-md-1">
                        <form id="exelform" enctype="multipart/form-data" method="post" action="/Operate/Report/ExportExecl"  >
                            <input id="fileUpload" type="file" name="file" style="display:none">
                            <button class="btn btn-primary" type="button" id="btnReport"><i class='fa fa-search'></i>导入</button>
                        </form>
                    </div>

                    <div class="col-md-2">
                        <button class="btn btn-primary" type="button" id="btnEdit"><i class='fa fa-pencil'></i>编辑(开始、结束)</button>
                    </div>
                </div>
            </div>
        </div>
    <form id="planSubmit" name="planSubmit" method="post" action="/Operate/Report/SubmitProdPlan">
        <div class="box result tab-content" style="border-top:0" id="review">

            <table id="prodplan" style="width:100%">
                <thead>
                    <tr>
                        <td rowspan="2" style="width:200px">年月</td>
                        <td colspan="2">能源生产计划</td>
                        <td colspan="3">能源消耗计划</td>
                        <td colspan="8">经营计划</td>

                    </tr>
                    <tr>
                        <td>发电(kWh)</td>
                        <td>供冷(kWh)</td>
                        <td>耗气(Nm3)</td>
                        <td>耗电(kWh)</td>
                        <td>耗水(Nm3)</td>
                        <td>收入计划(元)</td>
                        <td>支出计划(元)</td>
                        <td>边际贡献计划(元)</td>
                        <td>补贴收入(元)</td>
                        <td>固定成本(元)</td>
                        <td>人工成本(元)</td>
                        <td>四项费用(元)</td>
                        <td>管理费用(元)</td>
                    </tr>
                </thead>
                <tbody></tbody>
            </table>

        </div>
    </form>
</section>
@section Scripts{

    <script src="~/lib/My97DatePicker/WdatePicker.js"></script>
    <script src="~/js/web/operate/report/prodplan.js"></script>
    <script src="~/lib/jquery-other/jquery.form.js"></script>
    <script src="~/lib/moment/moment.js"></script>
}

脚注

这里说明一下,因为原本的<input type='file'> 很丑,基本上没有愿意用,所有把他给隐藏了,只是一个承载文档容器,用form 提交到后台,在这里我遇到很多问题,给大家展示一下

先上图
Asp.net Core MVC 导出execl

注意:这里如果用 HttpPostedFileBase 来接收的话,会报错,因为这个是ASP.net FrameWork 支持的方法,先给大家展示一下错误,如下图
Asp.net Core MVC 导出execl

看到没有,练后台都不会进,直接就报错,在给你们截一下后台调试的图片
Asp.net Core MVC 导出execl

经过仔细研究.Net Core 里面没有HttpPostedFileBase 这个类,所以不能用这个方法接收,后来,我用想,要不要用HttpContext 来接收一下,看行不行,继续上图

Asp.net Core MVC 导出execl

换成HttpContext 来试试,看看能不能得到execl文档,调试走去

Asp.net Core MVC 导出execl

同样不进后台直接报错,错误信息如上图,面对这个问题,我查看关于.net Core 的资料,终于懂了,把正确的代码贴个大家,如下:

 /// <summary>
        /// execl导入
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult ExportExecl()
        {
            var file = Request.Form.Files;
            var filename = ContentDispositionHeaderValue.Parse(file[0].ContentDisposition).FileName.Trim('"');

            if (string.Empty.Equals(filename) || ".xlsx" != Path.GetExtension(filename))
            {
                throw new ArgumentException("当前文件格式不正确,请确保正确的Excel文件格式!");
            }
            var severPath = FileHelper.MapPath("~/wwwroot/prodplanfile/");//获取当前虚拟文件路径

            var savePath = Path.Combine(severPath, filename); //拼接保存文件路径

            try
            {
                using (FileStream fs = System.IO.File.Create(savePath))
                {
                    file[0].CopyTo(fs);
                    fs.Flush();
                }
                var stus = ReadExcelToEntityList<prodplan>(savePath);//插入数据
                if (stus != null)
                {
                    string time = stus[0].plan_date;
                    ViewBag.dateTime = Convert.ToDateTime(time).ToString("yyyy");
                }

                return View("PordPlan");
            }
            finally
            {
                System.IO.File.Delete(savePath);//每次上传完毕删除文件
            }

        }

注意:这用不用给方法带什么参数,直接用 Request.Form.Files 就能接收到你想要的文档,这个就Core类库的改变,第一个问题算是解决了。还有就是 把文件保存在服务器上不能用file.save()方法了,要换种思维using (FileStream fs = System.IO.File.Create(savePath))
{
file[0].CopyTo(fs);
fs.Flush();
}
这样可以了。
下面的问题就好说了,贴代码

把execl中的数据读取到table中

/// <summary>
        /// 把Execl中的代码读取到table中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath"></param>
        /// <returns></returns>

        public  IList<T> ReadExcelToEntityList<T>(string filePath) where T : class, new()
        {
            System.Data.DataTable tbl = ReadExcelToDataTable(filePath);//读取Excel数据到DataTable

            IList<T> list = DataTableToList<T>(tbl);

            return list;

        }
//Excel数据转DataTable 使用的oledb读取方式
        public System.Data.DataTable ReadExcelToDataTable(string filePath)
        {

            if (filePath == string.Empty) throw new ArgumentNullException("路径参数不能为空");
            string ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Persist Security Info=False;Data Source=" + filePath + "; Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";
            OleDbDataAdapter adapter = new OleDbDataAdapter("select * From[Sheet1$]", ConnectionString); //默认读取的Sheet1,你也可以把它封装变量,动态读取你的Sheet工作表
            System.Data.DataTable table = new System.Data.DataTable("TempTable");
            adapter.Fill(table);

            System.Data.DataTable newTable = new System.Data.DataTable();
            newTable = table.Clone();//克伦架子
            foreach (DataColumn col in newTable.Columns)
            {
                if (col.DataType.FullName == "System.Double")
                {
                    col.DataType = Type.GetType("System.Decimal");
                }
            }

            newTable.Columns["计划日期"].ColumnName = "plan_date";
            newTable.Columns["发电量"].ColumnName = "power"; 
            newTable.Columns["供冷"].ColumnName = "cooling";
            //table.Columns["供冷"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["耗气"].ColumnName = "gas_consumption";
            //table.Columns["耗气"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["耗电"].ColumnName = "power_consumption";
            //table.Columns["耗电"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["耗水"].ColumnName = "water_consumption";
            //table.Columns["耗水"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["收入计划"].ColumnName = "income_plan";
            //table.Columns["收入计划"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["支出计划"].ColumnName = "expenditure_paln";
            //table.Columns["支出计划"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["边际贡献计划"].ColumnName = "contribution";
            //table.Columns["边际贡献计划"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["供热量"].ColumnName = "heatingload";
            //table.Columns["供热量"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["供蒸汽"].ColumnName = "steam_supply";
            //table.Columns["供蒸汽"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["供热水"].ColumnName = "heatingwater";
            //table.Columns["供热水"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["耗蒸汽"].ColumnName = "steam_consumption";
            //table.Columns["耗蒸汽"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["补贴收入"].ColumnName = "subincome";
            //table.Columns["补贴收入"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["固定成本"].ColumnName = "fixedcost";
            //table.Columns["固定成本"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["人工成本"].ColumnName = "labourcost";
            //table.Columns["人工成本"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["四项成本"].ColumnName = "fourcost";
            //table.Columns["四项成本"].DataType = Type.GetType("System.Decimal");
            newTable.Columns["管理费用"].ColumnName = "managecost";
            //table.Columns["管理费用"].DataType = Type.GetType("System.Decimal");
            newTable.Columns.Add("year");
            newTable.Columns.Add("month");
            //往新的table中添加数据
            foreach (DataRow row in table.Rows)
            {
                DataRow rowNew = newTable.NewRow();
                rowNew["plan_date"] = row["计划日期"];
                rowNew["power"] = row["发电量"];
                rowNew["cooling"] = row["供冷"];
                rowNew["gas_consumption"] = row["耗气"];
                rowNew["power_consumption"] = row["耗电"];
                rowNew["water_consumption"] = row["耗水"];
                rowNew["income_plan"] = row["收入计划"];
                rowNew["expenditure_paln"] = row["支出计划"];
                rowNew["contribution"] = row["边际贡献计划"];
                rowNew["heatingload"] = row["供热量"];
                rowNew["steam_supply"] = row["供蒸汽"];
                rowNew["heatingwater"] = row["供热水"];
                rowNew["steam_consumption"] = row["耗蒸汽"];
                rowNew["subincome"] = row["补贴收入"];
                rowNew["fixedcost"] = row["固定成本"];
                rowNew["labourcost"] = row["人工成本"];
                rowNew["fourcost"] = row["四项成本"];
                rowNew["managecost"] = row["管理费用"];
                rowNew["year"] = row["计划日期"].ToString().Split('-')[0];
                rowNew["month"] = Convert.ToInt32(row["计划日期"].ToString().Split('-')[1]).ToString();
                newTable.Rows.Add(rowNew);
            }
            return newTable;
        }

注意:因为execl中的列类型和实体列的类型不一致,所有我特意新建一个datatable,把列的类型也顺便修改了

 //DataTable转List<T>
        public List<T> DataTableToList<T>(System.Data.DataTable dt) where T : class, new()
        {
            if (dt == null) return null;
            List<T> list = new List<T>();
            //遍历DataTable中所有的数据行  
            foreach (DataRow dr in dt.Rows)
            {
                T t = new T();
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pro in propertys)
                {

                    //检查DataTable是否包含此列(列名==对象的属性名)    
                    if (dt.Columns.Contains(pro.Name))
                    {
                        try
                        {
                            if (pro.Name == "year")
                            {
                                object value = dr["plan_date"];

                                //value = Convert.ChangeType(value, pro.PropertyType);//强制转换类型
                                                                                    //如果非空,则赋给对象的属性  PropertyInfo
                                if (value != DBNull.Value)
                                {
                                    string year = value.ToString().Trim().Split('-')[0];
                                    pro.SetValue(t, year, null);
                                }
                            }
                            else if (pro.Name == "month")
                            {
                                object value = dr["plan_date"];
                                //value = Convert.ChangeType(value, pro.PropertyType);//强制转换类型
                                                                                    //如果非空,则赋给对象的属性  PropertyInfo
                                if (value != DBNull.Value)
                                {
                                    string month = Convert.ToInt32(value.ToString().Trim().Split('-')[1]).ToString();
                                    pro.SetValue(t, month, null);
                                }
                            }
                            else
                            {
                                object value = dr[pro.Name];
                                if (value != null)
                                {
                                    //value = Convert.ChangeType(value, pro.PropertyType);//强制转换类型                                                       
                                    //如果非空,则赋给对象的属性  PropertyInfo
                                    if (value != DBNull.Value)
                                    {
                                        if (pro.PropertyType.FullName == "System.String")
                                        {
                                            pro.SetValue(t, Convert.ToString(value), null);
                                        }
                                        else
                                        {
                                            pro.SetValue(t, Convert.ToDecimal(value), null);
                                        }
                                        //if (pro.PropertyType.FullName == "System.Decimal")
                                        //{
                                        //}
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            throw;
                        }
                    }
                }
                //对象添加到泛型集合中  
                list.Add(t);
            }
            return list;
          }

注意:不能使用value = Convert.ChangeType(value, pro.PropertyType);//强制转换类型
这样强转的话会报错,要改成if (pro.PropertyType.FullName == "System.String") { pro.SetValue(t, Convert.ToString(value), null); }这种方式去写,就会避免报错。


好了,就写到这里了,第一次,写的不好,请大家见谅!这个编辑器还没有用熟,多写写可能就好了。
欢迎大家批评和指导!


相关标签: mvc asp-net-core