(1).实现功能:通过前台选择.xlsx文件的Excel,将其文件转化为DataTable和List集合

(2).开发环境:Window7旗舰版+vs2013+Mvc4.0

(2).在使用中需要用到的包和dll

  1.用NuGet引入OpenXML包【全名叫DocumentFormat.OpenXml】=》注意:现在导入的Excel只支持.xlsx结尾的Excel,若导入.xls结尾的则会出现【文件包含损坏的数据】的错误!

  2.WindowsBase.dll

(3).MVC中通过file选择文件并用submit提交到Controller方法如下:

3.1:前台代码

<form action="Home/FileUpload" method="post" enctype="multipart/form-data">
    <div style="width:100%;height:auto;
        <input id="uploadfile" type="file" name="file" />
        <input type="submit" value="上传Excel" />
    </div>
</form>

3.2:Controller代码

/// <summary>
/// form提交回的Action
/// </summary>
/// <returns></returns>
public ActionResult FileUpload()
{
    //1.假设选择一个Excel文件  获取第一个Excel文件
    var stream = Request.Files[0].InputStream;
    //2.将选择的文件转换为DataTable
    var rst = new StreamToDataTable().ReadExcel(stream);
    //3.将DataTable转换为List集合
    var list = this.TableToLists(rst);
    return View();
}
/// <summary>
/// 加载Excel数据
/// </summary>
public List<ExcelImport> TableToLists(System.Data.DataTable table)
{
    TBToList<ExcelImport> tables = new TBToList<ExcelImport>();
    var lists = tables.ToList(table);
    return lists;
}

(4).Excel流组织成Datatable方法实现

public class StreamToDataTable
   {
       /// <summary>
       /// Excel流组织成Datatable
       /// </summary>
       /// <param name="stream">Excel文件流</param>
       /// <returns>DataTable</returns>
       public DataTable ReadExcel(Stream stream)
       {
           using (SpreadsheetDocument document = SpreadsheetDocument.Open(stream, false))     //若导入.xls格式的Excel则会出现【文件包含损坏的数据】的错误!
           {
               //打开Stream
               IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>();
               if (sheets.Count() == 0)
               {//找出符合条件的sheet,没有则返回
                   return null;
               }
 
               WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
               //获取Excel中共享数据
               SharedStringTable stringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
               IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>();//得到Excel中得数据行
 
               DataTable dt = new DataTable("Excel");
               //因为需要将数据导入到DataTable中,所以我们假定Excel的第一行是列名,从第二行开始是行数据
               foreach (Row row in rows)
               {
                   if (row.RowIndex == 1)
                   {
                       //Excel第一行为列名
                       GetDataColumn(row, stringTable, ref dt);
                   }
                   GetDataRow(row, stringTable, ref dt);//Excel第二行同时为DataTable的第一行数据
               }
               return dt;
           }
       }
 
 
       /// <summary>
       /// 根据给定的Excel流组织成Datatable
       /// </summary>
       /// <param name="stream">Excel文件流</param>
       /// <param name="sheetName">需要读取的Sheet</param>
       /// <returns>组织好的DataTable</returns>
       public DataTable ReadExcelBySheetName(string sheetName, Stream stream)
       {
           using (SpreadsheetDocument document = SpreadsheetDocument.Open(stream, false))
           {//打开Stream
               IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName);
               if (sheets.Count() == 0)
               {//找出符合条件的sheet,没有则返回
                   return null;
               }
 
               WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
 
               //获取Excel中共享数据
               SharedStringTable stringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
               IEnumerable<Row> rows = worksheetPart.Worksheet.Descendants<Row>();//得到Excel中得数据行
 
               DataTable dt = new DataTable("Excel");
               //因为需要将数据导入到DataTable中,所以我们假定Excel的第一行是列名,从第二行开始是行数据
               foreach (Row row in rows)
               {
                   if (row.RowIndex == 1)
                   {
                       //Excel第一行为列名
                       GetDataColumn(row, stringTable, ref dt);
                   }
                   GetDataRow(row, stringTable, ref dt);//Excel第二行同时为DataTable的第一行数据
               }
               return dt;
           }
       }
 
       /// <summary>
       /// 构建DataTable的列
       /// </summary>
       /// <param name="row">OpenXML定义的Row对象</param>
       /// <param name="stringTablePart"></param>
       /// <param name="dt">需要返回的DataTable对象</param>
       /// <returns></returns>
       public void GetDataColumn(Row row, SharedStringTable stringTable, ref DataTable dt)
       {
           DataColumn col = new DataColumn();
           foreach (Cell cell in row)
           {
               string cellVal = GetValue(cell, stringTable);
               col = new DataColumn(cellVal);
               dt.Columns.Add(col);
           }
       }
 
       /// <summary>
       /// 构建DataTable的每一行数据,并返回该Datatable
       /// </summary>
       /// <param name="row">OpenXML的行</param>
       /// <param name="stringTablePart"></param>
       /// <param name="dt">DataTable</param>
       private void GetDataRow(Row row, SharedStringTable stringTable, ref DataTable dt)
       {
           // 读取算法:按行逐一读取单元格,如果整行均是空数据
           // 则忽略改行(因为本人的工作内容不需要空行)-_-
           DataRow dr = dt.NewRow();
           int i = 0;
           int nullRowCount = i;
           foreach (Cell cell in row)
           {
               string cellVal = GetValue(cell, stringTable);
               if (cellVal == string.Empty)
               {
                   nullRowCount++;
               }
               dr[i] = cellVal;
               i++;
           }
           if (nullRowCount != i)
           {
               dt.Rows.Add(dr);
           }
       }
 
 
       /// <summary>
       /// 获取单元格的值
       /// </summary>
       /// <param name="cell"></param>
       /// <param name="stringTablePart"></param>
       /// <returns></returns>
       private string GetValue(Cell cell, SharedStringTable stringTable)
       {
           //由于Excel的数据存储在SharedStringTable中,需要获取数据在SharedStringTable 中的索引
           string value = string.Empty;
           try
           {
               if (cell.ChildElements.Count == 0)
                   return value;
 
               value = double.Parse(cell.CellValue.InnerText).ToString();
 
               if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
               {
                   value = stringTable.ChildElements[Int32.Parse(value)].InnerText;
               }
           }
           catch (Exception)
           {
               value = "N/A";
           }
           return value;
       }
 
   }

(5).Datatable组织为List方法实现

public class TBToList<T> where T : new()
   {
       /// <summary>
       /// 获取列名集合
       /// </summary>
       private IList<string> GetColumnNames(DataColumnCollection dcc)
       {
           IList<string> list = new List<string>();
           foreach (DataColumn dc in dcc)
           {
               list.Add(dc.ColumnName);
           }
           return list;
       }
 
       /// <summary>
       ///属性名称和类型名的键值对集合
       /// </summary>
       private Hashtable GetColumnType(DataColumnCollection dcc)
       {
           if (dcc == null || dcc.Count == 0)
           {
               return null;
           }
           IList<string> colNameList = GetColumnNames(dcc);
 
           Type t = typeof(T);
           PropertyInfo[] properties = t.GetProperties();
           Hashtable hashtable = new Hashtable();
           int i = 0;
           if (properties.Length == colNameList.Count)
           {
               foreach (PropertyInfo p in properties)
               {
                   foreach (string col in colNameList)
                   {
                       if (!hashtable.Contains(col))
                       {
                           hashtable.Add(col, p.PropertyType.ToString() + i++);
                       }
                   }
               }
           }
           return hashtable;
       }
 
       /// <summary>
       /// DataTable转换成IList
       /// </summary>
       /// <param name="dt"></param>
       /// <returns></returns>
       public List<T> ToList(DataTable dt)
       {
           if (dt == null || dt.Rows.Count == 0)
           {
               return null;
           }
 
           PropertyInfo[] properties = typeof(T).GetProperties();//获取实体类型的属性集合
           Hashtable hh = GetColumnType(dt.Columns);//属性名称和类型名的键值对集合
           IList<string> colNames = GetColumnNames(hh);//按照属性顺序的列名集合
           List<T> list = new List<T>();
           T model = default(T);
           foreach (DataRow dr in dt.Rows)
           {
               model = new T();//创建实体
               int i = 0;
               foreach (PropertyInfo p in properties)
               {
                   if (p.PropertyType == typeof(string))
                   {
                       p.SetValue(model, dr[colNames[i++]], null);
                   }
                   else if (p.PropertyType == typeof(int))
                   {
                       p.SetValue(model, int.Parse(dr[colNames[i++]].ToString()), null);
                   }
                   else if (p.PropertyType == typeof(DateTime))
                   {
                       p.SetValue(model, DateTime.Parse(dr[colNames[i++]].ToString()), null);
                   }
                   else if (p.PropertyType == typeof(float))
                   {
                       p.SetValue(model, float.Parse(dr[colNames[i++]].ToString()), null);
                   }
                   else if (p.PropertyType == typeof(double))
                   {
                       p.SetValue(model, double.Parse(dr[colNames[i++]].ToString()), null);
                   }
               }
               list.Add(model);
           }
           return list;
       }
 
       /// <summary>
       /// 按照属性顺序的列名集合
       /// </summary>
       private IList<string> GetColumnNames(Hashtable hh)
       {
           PropertyInfo[] properties = typeof(T).GetProperties();//获取实体类型的属性集合
           IList<string> ilist = new List<string>();
           int i = 0;
           foreach (PropertyInfo p in properties)
           {
               ilist.Add(GetKey(p.PropertyType.ToString() + i++, hh));
           }
           return ilist;
       }
 
       /// <summary>
       /// 根据Value查找Key
       /// </summary>
       private string GetKey(string val, Hashtable tb)
       {
           foreach (DictionaryEntry de in tb)
           {
               if (de.Value.ToString() == val)
               {
                   return de.Key.ToString();
               }
           }
           return null;
       }
   }

转自:http://www.cnblogs.com/pfwbloghome/p/4969792.html

OpenXML_导入Excel到数据库(转)的更多相关文章

  1. OpenXML_导入Excel到数据库

    (1).实现功能:通过前台选择.xlsx文件的Excel,将其文件转化为DataTable和List集合 (2).开发环境:Window7旗舰版+vs2013+Mvc4.0 (2).在使用中需要用到的 ...

  2. 一步步实现ABAP后台导入EXCEL到数据库【3】

    在一步步实现ABAP后台导入EXCEL到数据库[2]里,我们已经实现计划后台作业将数据导入数据库的功能.但是,这只是针对一个简单的自定义结构的导入程序.在实践应用中,面对不同的表.不同的导入文件,我们 ...

  3. 一步步实现ABAP后台导入EXCEL到数据库【1】

    在SAP的应用当中,导入.导出EXCEL文件的情况是一个常见的需求,有时候用户需要将大量数据定期导入到SAP的数据库中.这种情况下,使用导入程序在前台导入可能要花费不少的时间,如果能安排导入程序为后台 ...

  4. 如何使用NPOI 导出到excel和导入excel到数据库

    近期一直在做如何将数据库的数据导出到excel和导入excel到数据库. 首先进入官网进行下载NPOI插件(http://npoi.codeplex.com/). 我用的NPOI1.2.5稳定版. 使 ...

  5. ASP.NET MVC导入excel到数据库

    MVC导入excel和webform其实没多大区别,以下为代码: 视图StationImport.cshtml的代码: @{ ViewBag.Title = "StationImport&q ...

  6. 一步步实现ABAP后台导入EXCEL到数据库【2】

    前文:http://www.cnblogs.com/hhelibeb/p/5912330.html 既然后台作业只能在应用服务器运行,那么,我们可以先将要上传的数据保存在应用服务器中,之后再以后台作业 ...

  7. jxl读取excel实现导入excel写入数据库

    @RequestMapping(params = "method=import", method = RequestMethod.POST) @ResponseBody publi ...

  8. .Net core 使用NPOI 直接导入Excel到数据库(即不先将Excel保存到服务器再读取文件到数据库)

    /// <summary> /// 导入信息 /// </summary> /// <param name="file"></param& ...

  9. VB导入Excel到数据库软件(持续更新中。)

    1.选择Excel文件版本 电脑上用的 Office2010 引用:Mircosoft Excel 14.0 Object Library 2.选择Excel文件 '选择文件公共变量 Public D ...

随机推荐

  1. 就是要你明白机器学习系列--决策树算法之悲观剪枝算法(PEP)

    前言 在机器学习经典算法中,决策树算法的重要性想必大家都是知道的.不管是ID3算法还是比如C4.5算法等等,都面临一个问题,就是通过直接生成的完全决策树对于训练样本来说是“过度拟合”的,说白了是太精确 ...

  2. PLC梯形图编程练习

    在PLC培训软件中完成如下两个练习,并把对应的梯形图程序发表在博客上. 交通灯控制 在如下图的场景中,打开SW1开关后,交通灯控制器开始工作,关闭SW1则控制器停止工作. SW2为控制模式选择开关: ...

  3. Hibernate 相关面试题

    谈谈你对Hibernate的理解 1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象.建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操 ...

  4. iOS使用AVFoundation实现二维码扫描(ios7以上)——转载

    关于二维码扫描有不少优秀第三方库: ZBar SDK 里面有详细的文档,相应介绍也非常多,如:http://rdcworld-iphone.blogspot.in/2013/03/how-to-use ...

  5. 20145208 《Java程序设计》第8周学习总结

    20145208 <Java程序设计>第8周学习总结 教材学习内容总结 NIO与NIO2 NIO与IO的区别 IO           NIO 面向流             面向缓冲 阻 ...

  6. EventBus框架在Android多Pane(Fragment)中的应用

    通常多pane的设计中,比如Fragment A是个Headline,Fragement B是detail,那么B通常需要实现A的点击事件的接口,这样子的话,两个fragment就高耦合了,而且需要在 ...

  7. jQuery理解之(二)功能函数

    在javascript编程中,开发者通常需要编写很多小程序来实现一些特定的功能.例如浏览器检测,字符串处理.数组的编辑等.jQuery对这些常用的程序进行了总结,提供了很多实用的函数. 1.检测浏览器 ...

  8. EF---结合三层方法的应用

    1 public class CustomerDAL 2 { 3 //数据库上下文对象 4 YYMMVCEntities db = new YYMMVCEntities(); 5 /// <su ...

  9. 某表含有N个字段超精简模糊查询方法

    我们在做多个字段模糊查询时,是不是觉得非常麻烦?比如我要模糊查询某表多个字段存在某数据时,如下 select * from table where a like '%key%' or b  like ...

  10. 用SQL打印乘法口诀表

    --用SQL打印出乘法口诀表 declare @i int ,@j int --@i是乘法口诀的行数 --一共九行 begin --每次都是从1*开始,j每循环一次递增 )--print每次输出都会换 ...