从Excel导入数据到数据库

开发工具与关键技术:VS2015,ASP.NET MVC

撰写时间:2019年5月24日

通过网页页面把Execl的数据导入到数据库。
在导入数据之前要先设计出一个导入数据的Excel模板,写入数据就规定按照此模板写入。
把设计好的模板放入到项目的文件夹中。
接着写一个下载模板的代码,调用浏览器下载窗口,进行下载模板

 public ActionResult DownImportTemplate()
        {
            //Server  系统
            //MapPath  自动找到这个项目所在路径
            string filePath = Server.MapPath("~/Document/Template/英雄信息导入模板.xls");
            //因为是文件 所以要转换成流.所以要用到IO流
            if (System.IO.File.Exists(filePath))//判断此文件是否存在,并判断是否能用IO流输出
            {
                //把这个路径转换成文件的名字  Path 路径  GetFileName 获取文件名
                string strFileName = Path.GetFileName(filePath);
                //文件返回可以接收三个参数,前面是具体返回的值,中间是返回的类型,最后可以读取文件的长度
                return File(new FileStream(filePath, FileMode.Open), "application-octet-stream", strFileName);
                    //FileStream 文件流   FileMode 下载文件的模态框   Open,在点击下载模板是自动打开下载浏览器自带的下载框   
                    //application-octet-stream 通过流的格式返回
                    //strFileName 文件名字
            }
            else
            {
                return Content("模板文件不存在,请联系系统运维人员");
            }
        }

效果图:
从Excel导入数据到数据库_第1张图片
接下来就是把模板填好
把数据导入到数据库。

public ActionResult EnterHeroData(HttpPostedFileBase file)
        {
            Fantasy fancy = new Fantasy();
            fancy.State = false;
            try
            {
                //把session中的ImportExcel移除避免残留以前数据
                Session.Remove("IportExcel");
                //获取文件的后缀
                //判断是否是Excel
                //上传的工作簿的格式必须是 .xls
                string fileExtension = System.IO.Path.GetExtension(file.FileName);
                //判断类型是不是  .xls
                //Equals  等于   判断前后是否相等
                if (".xls".Equals(fileExtension)||".XLS".Equals(fileExtension))
                {
                    //声明二进制数组存放文件  数组的长度以文件的长度决定
                    byte[] fileBytes = new byte[file.ContentLength];
                    //将传入的文件转化为二进制的数组存入fileBytes
                    file.InputStream.Read(fileBytes, 0, file.ContentLength);
                    //InputStream IO流读取
                    //将二进制数组转化为内存流
                    System.IO.MemoryStream excelFileStream = new System.IO.MemoryStream(fileBytes);
                    //MemoryStream 内存流
                    //将内存流转化为工作簿
                    NPOI.SS.UserModel.IWorkbook workbook = new HSSFWorkbook(excelFileStream);

                    //判断工作簿里是否有工作表
                    //NumberOfSheets > 0 工作表的数量是否大于零
                    //Number 数量   sheets  工作表
                    if (workbook.NumberOfSheets>0)
                    {
                        //查询出 英雄所在阵营ID 英雄技能ID 伤害类型ID 攻击方式ID 英雄点券ID 英雄金币ID
                        List dbHeroSame = (from tbHeroSame in myModel.A01_HeroSame
                                                         select tbHeroSame).ToList();
                        List dbHeroType = myModel.A02_HeroType.ToList();
                        List dbHeroSkill = myModel.A03_HeroSkill.ToList();
                        List dbHeroCapability = myModel.A04_HeroCapability.ToList();
                        List dbHeroBattle = myModel.A05_HeroBattle.ToList();
                        List dbHeroMoney = myModel.A06_HeroMoney.ToList();
                        List dbHeroGold = myModel.A07_HeroGold.ToList();
                        

                        //对象列表
                        List listHero = new List();
                        //获取第一个工作表  下标为零
                        NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0);
                        

                        //判断工作表中是否有数据
                        if(sheet.PhysicalNumberOfRows > 0)
                        {
                            //工作表有数据
                            
                            //定义DataTable
                            DataTable dtExcel = new DataTable();
                            //获取标题行---  第二行,索引为1;第一行是说明
                            NPOI.SS.UserModel.IRow rowHeader = sheet.GetRow(1);

                            //获取表格的列数
                            int cellCount = rowHeader.LastCellNum;//LastCellNum 最后一个单元格是多大就获取列数是多大
                            //获取表格行数
                            int rowCount = sheet.LastRowNum + 1;//因为有个导入说明,所以要加1

                            //用到两个for循环,因为行和列
                            //创建dataTable中的列,循环获取表头中各个单元格的值

                            //获取列
                            //FirstCellNum 从第一列开始读取
                            for (int i = rowHeader.FirstCellNum; i < cellCount; i++)
                            {
                                //通过遍历行中的每一个单元格,获取表头中的各个单元格的值
                                DataColumn dtColumn = new DataColumn(rowHeader.GetCell(i).StringCellValue);
                                //将获取到的所有标题列数据放到datatable中;
                                dtExcel.Columns.Add(dtColumn);
                                //Columns  获取有所有列
                            }
                            //获取行
                            //(sheet.FirstRowNum) + 2 第一行是说明  第二行是表条(标题)第三行才是数据,所以要+2
                            for (int i = (sheet.FirstRowNum)+2; i < rowCount; i++)
                            {
                                //获取行的数据
                                NPOI.SS.UserModel.IRow row = sheet.GetRow(i);
                                DataRow dtRow = dtExcel.NewRow();
                                if(row != null)
                                {
                                    //遍历excel中一行的所有单元格
                                    for (int  y = row.FirstCellNum;  y < cellCount; y++)
                                    {
                                        //行中的每一个单元格都不为空
                                        if(row.GetCell(y) != null) {
                                            dtRow[y] = row.GetCell(y).ToString();
                                        }
                                    }
                                }
                                //将数据装到DataTable中
                                //将填入数据的dtRow添入dtExcel
                                dtExcel.Rows.Add(dtRow);
                                //Rows 获取所有行
                            }
                            int intSuccess = 0; //记录导入成功的条数
                            int intFail = 0;//记录导入失败的条数 
                            //数据的准确性
                            foreach (DataRow row in dtExcel.Rows)
                            {
                                //创建studentVo对象保存每一条数据
                                HeroData Hero = new HeroData();
                                try
                                {
                                    //英雄所在阵营 和 获取英雄所在阵营ID
                                    Hero.HeroSame = row["英雄所在阵营"].ToString().Trim();
                                    //通过dataTable中的HeroSame到dbHeroSame中查找相应的HeroSameID
                                    Hero.HeroSameID = dbHeroSame.Where(m => m.HeroSame.Trim() == Hero.HeroSame).SingleOrDefault().HeroSameID;

                                    Hero.HeroCapability = row["伤害类型"].ToString().Trim();
                                    Hero.HeroCapabilityID = dbHeroCapability.Where(m => m.HeroCapability.Trim() == Hero.HeroCapability).SingleOrDefault().HeroCapabilityID;

                                    Hero.HeroBattle = row["攻击方式"].ToString().Trim();
                                    Hero.HeroBattleID = dbHeroBattle.Where(m => m.HeroBattle.Trim() == Hero.HeroBattle).SingleOrDefault().HeroBattleID;

                                    Hero.HeroMoney = row["英雄点券"].ToString().Trim();
                                    var HeroMoney = Convert.ToDecimal(Hero.HeroMoney);
                                    Hero.HeroMoneyID = dbHeroMoney.Where(m => m.HeroMoney == HeroMoney).SingleOrDefault().HeroMoneyID;

                                    Hero.HeroGold = row["英雄金币"].ToString().Trim();
                                    var HeroGold = Convert.ToDecimal(Hero.HeroGold);
                                    Hero.HeroGoldID = dbHeroGold.Where(m => m.HeroGold == HeroGold).SingleOrDefault().HeroGoldID;

                                    Hero.HeroTitle = row["英雄昵称"].ToString().Trim();
                                    Hero.HeroName = row["英雄名字"].ToString().Trim();
                                    Hero.HeroAddTime = row["英雄加入时间"].ToString().Trim();
                                    var HeroAddTimeLS = Convert.ToDateTime(Hero.HeroAddTime);
                                    Hero.PassiveSkill = row["被动技能"].ToString().Trim();
                                    Hero.SkillQ = row["技能Q"].ToString().Trim();
                                    Hero.SkillW = row["技能W"].ToString().Trim();
                                    Hero.SkillE = row["技能E"].ToString().Trim();
                                    Hero.SkillR = row["技能R"].ToString().Trim();

                                    //将每一条数据都添加到对象列表中
                                    listHero.Add(Hero);
                                    intSuccess++;//记录成功的条数
                                }
                                catch (Exception)
                                {
                                    intFail++;
                                    fancy.State = false;
                                    fancy.Text = "数据处理出错";
                                }
                            }
                            //把数据保存到Session当中
                            Session["ImportExcel"] = listHero;
                            fancy.State = true;
                            fancy.Text = String.Format("文件中共有" + dtExcel.Rows.Count + "条英雄数据,导入成功" + intSuccess + "条,导入失败" + intFail + "条");
                        }
                        else
                        {
                            fancy.Text = "工作表中没有数据";
                        }

                    }
                    else
                    {
                        fancy.Text = "工作簿中没有工作表"; 
                    }
                }
                else
                {
                    fancy.Text = "选择的文件类型不正确";
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                fancy.State = false;
                fancy.Text = "上传失败,类型不对应;请检查是否有工作簿,是否有数据,是否按照模板填写";
            }
            return Json(fancy,JsonRequestBehavior.AllowGet);
        }

以上是控制器这边完整的数据导入代码
以上的代码只需要根据自己的需要进行更改套用就好

你可能感兴趣的:(C#)