(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. GDB堆栈跟踪与汇编调试

    GDB堆栈跟踪与汇编调试 堆栈跟踪 源代码: 对预先编写的 stack.c 文件进行编译,并且使用 CGDB 进行调试,对堆栈进行跟踪,了解该代码堆栈是如何变化的. 在 CGDB 中,先设置 main ...

  2. 百度地图ip定位,不算bug的bug

    做为一个入行不足两年的菜鸟,能在博客园写下第一篇博客,是需要多大的勇气啊.主要还是怕大神们喷啊.其次自己文笔实在太差了. 哈哈~还请各位大神,口下留情啊. 首先说下我的需求:一个需要城市分站的手机站. ...

  3. C# Winform实现炫酷的透明动画界面

    做过.NET Winform窗体美化的人应该都很熟悉UpdateLayeredWindow吧,UpdateLayeredWindow可以实现窗体的任意透明,效果很好,不会有毛边.不过使用这个API之后 ...

  4. 疯狂的Java算法——插入排序,归并排序以及并行归并排序

    从古至今的难题 在IT届有一道百算不厌其烦的题,俗称排序.不管是你参加BAT等高端笔试,亦或是藏匿于街头小巷的草根笔试,都会经常见到这样一道百年难得一解的问题. 今天LZ有幸与各位分享一下算法届的草根 ...

  5. python3 入门 (三) 函数与lambda表达式、闭包

    函数 是组织好的.可重复使用的.用来实现单一或相关联功能的代码段. 函数代码块以def关键词开头,后接函数标识符名称和圆括号() 任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数 函 ...

  6. linux网络命令

    关键字 write wall last lastlog traceroute netstat mount 1.write 该命令可以给所有在线用户发送消息 示例: 接受消息用户:按回车可以退出 2.w ...

  7. 在Windows和UNIX下利用PHP和LDAP进行身份验证

    我现在的老板曾要求我为企业内部的Web服务提供一种标准的身份验证方法.我遇到的一个主要问题就是我们公司主要使用了两种平台:UNIX和.所以,我的第一个想法并不很成功:它要求每个员工都使用UNIX或者L ...

  8. jquery插件库

    jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多javascript高手加入其team. jQuery是继prototype之后又一个优秀的Javascrīpt框架.其经典 ...

  9. 金融自助设备WOSA/XFS规范介绍

    wosa(全称是windows开放式系统体系结构 windows open system architecture),是微软公司提出的一种在windows操作系统下的软件架构. wosa/xfs是基于 ...

  10. Chkrootkit Sourcecode Learning

    目录 . Chkrootkit Introduce . Source Code Frame . chklastlog.c . chkwtmp.c . ifpromisc.c . chkproc.c . ...