(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;background-color:#808080">
   <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;
}
}

(6).既然List集合都得到了,那么导入数据到数据库中那也不是什么难事了.......

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. 极度郁闷的错误调试——ajax jquery

     今天在写一个简单邮件验证的页面时,本来以为二十分钟的事情,却调试了一个半小时,简直郁闷,具体的错误如下: 在页面中,有一段如下的代码: <td colspan="3"> ...

  2. impdp/expdp 总结

      impdp/expdp   1.创建DIRECTORY create directory dir_dp as '/tmp';   --建议将DIRECTORY 建在 /tmp 表下面,该目录肯定存 ...

  3. TreeView无刷新获取text及value

    前台代码: <html xmlns="http://www.w3.org/1999/xhtml"><head id="Head1" runat ...

  4. 用异提交时,后台通过校验规则文件,校验不通过时,跳转到INPUT视图时,前台显示错误信息的解决办法

    1.第一种: 最近项目使用了struts2的校验(其实我觉得后台校验,特别是struts的校验,完全可以放在其他地方处理,比如交给js或者业务逻辑),而且系统刚好还使用了extjs,此时问题出现了:假 ...

  5. Linux下快速静态编译Qt以及Qt动态/静态版本共存

    Qt下静态编译Qt,根据我的经验,如果按照Windows下那种直接拿官方sdk安装之后的文件来编译是行不通的,需要直接下载Qt的source包,目前诺基亚的源码叫做qt-everywhere-open ...

  6. Android 获取imageview的图,在另一个imageview里显示。

    当我点击默认头像里的其中一个然后在点确定就在最上面的那个imageview里显示选择的头像.求大神. img1和img2都是ImageView,要把img1中的图片显示到img2中 前景(对应src属 ...

  7. 8.2.1.1 Speed of SELECT Statements 加速SELECT 语句

    8.2.1 Optimizing SELECT Statements 8.2.2 Optimizing Data Change Statements 8.2.3 Optimizing Database ...

  8. redis 异常排查

    异常排查 redis-server redis.windows.conf D:\redis-2.8.17>redis-server.exe redis.windows.conf[4692] 27 ...

  9. poj2955:括号匹配,区间dp

    题目大意: 给一个由,(,),[,]组成的字符串,其中(),[]可以匹配,求最大匹配数 题解:区间dp: dp[i][j]表示区间 [i,j]中的最大匹配数 初始状态 dp[i][i+1]=(i,i+ ...

  10. hadoop2.2.0的WordCount程序

    package com.my.hadoop.mapreduce.wordcount; import java.io.IOException; import org.apache.hadoop.conf ...