(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. Android使用service后台更新计划任务

    Service是Android的四大组件之一,这里就不再过多的去描述,下面主要实现启动应用时候利用service后台执行计划任务,退出应用后,关闭service,只存在整个应用的周期中. 首先使用se ...

  2. Core Data 使用

    coredata使用了一种完全不同 的方法,你不需要创建类,而是在数据模型编辑器中创建一些实体,然后为这些实体创建托管对象. 实体由属性组成.有三种:特性:关系:提取属性. 使用键值编码来设置属性或检 ...

  3. 20145222黄亚奇《Java程序设计》第2周学习总结

    教材学习内容总结 类型: 整数:short(占2字节).int(4).long(8). 浮点数:float(4).double(8) 字符:char(2) 布尔:boolean类型表示true与fal ...

  4. PHP Yii2.0(一):环境搭建 & 问题集锦

    第一节 简单认识版本的异同 (1)版本说明 在安装和使用之前,我们需要知道 PHP Yii 有两个不同的版本(Yii 1.*或者Yii 2.*),这两个版本的目录结构不一样,其具体使用方式差异较大,因 ...

  5. ORA-00911: 无效字符

    思路:遇到这样问题首先第一步:将有误sql粘至数据库运行一下,如果报错,说明sql存在问题. 第二步:数据库没问题.那么就要想你的书写方式是否正确,是否是ibatasi里的写法,或许是多了个 :  或 ...

  6. 【JVM】模板解释器--字节码的resolve过程

    1.背景 上文探讨了:[JVM]模板解释器--如何根据字节码生成汇编码? 本篇,我们来关注下字节码的resolve过程. 2.问题及准备工作 上文虽然探讨了字节码到汇编码的过程,但是: mov %ra ...

  7. iptables 的使用

    iptables 是Linux 防火墙规则配置命令 iptables -L -n 查看目前配置 iptables -F        清除预设表filter中的所有规则链的规则 iptables -A ...

  8. python 逐行读取文件的三种方法

    方法一: 复制代码代码如下: f = open("foo.txt")             # 返回一个文件对象  line = f.readline()             ...

  9. KK录像机破解补丁

    KK录像机是由杭州凯凯科技有限公司出品的免费的集游戏录像.视频录制.视频剪辑.添加字幕.添加音乐等功能于一体的高清视频录制软件.操作简单,且兼容录制所有游戏视频,是玩家分享精彩的工具. KK VIP功 ...

  10. python 元祖(tuple)

    元祖和列表几乎相同,但是元祖一旦初始化是不可变更内容的 元祖的表示方式是caassmates=(), 要记住所有列表能用的.元祖都能用,但是就是不能变内容 注:记住,在python中的元祖,为了引起不 ...