(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. Secure CRT 如何连接虚拟机里面的CentOS系统——当主机使用无线网的时候 作者原创 欢迎转载

    第一步:设置自己的无线网,并且分享给VM8这个虚拟网卡 第二步:查看VM8网卡的IP地址,如图是192.168.137.1 第三步:设置虚拟机的配置:选择VM8网卡并且是NAT的 第四步:设置虚拟机里 ...

  2. 使用github创建博客

    本文主要介绍以下几个内容: 1.使用githbu创建自己的博客 2.将博客域名映射到自己的域名 3.如果写博客   一.使用github创建自己的博客 具体可参考https://pages.githu ...

  3. 转:初学者,手工注入测试方法小节 (出处:: 51Testing软件测试网--jie)

    1.加入单引号 ’提交,  结果:如果出现错误提示,则该网站可能就存在注入漏洞.    2.数字型判断是否有注入; 语句:and 1=1 ;and 1=2 (经典).' and '1'=1(字符型)  ...

  4. iOS开发——C篇&文件操作

    今天开始C语言中的重点难点就基本上技术忘了,但是还有最后一个知识点不得不提,那就是文件操作. 我们都知道,我们每天都在使用电脑,手机,或者其他电子或者移动设备,其实我们在使用的时候每时每刻都在执行文件 ...

  5. ie浏览器下HTML上传控件input=file的美化

    近期写东西用到了input=file这个按钮,给其添加背景,在其它浏览器上都可以正常的显示,可一到ie上便不听话了,完全没有添加上,显的很难看.今天在网上找到一方法,试过后感觉很好,终于把这个问题给解 ...

  6. GPIO的8种模式详解

    和stm32的GPIO相关的寄存器有 (1)两个32位的配置寄存器(GPIOX_CRL,GPIOX_CRH) 每一个IO占用4位,16个IO占用64位就是两个32为寄存器. 其中CNF[1:0]是用来 ...

  7. Android Timer的使用

    1:服务端使用PHP <?php echo date('Y-m-d H:i:s'); ?> 2:activity_main.xml <RelativeLayout xmlns:and ...

  8. android传送照片到FTP服务器

    package com.photo; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundE ...

  9. Inno Setup for Windows service

    Inno Setup for Windows service? up vote86down votefavorite 77 I have a .Net Windows service. I want ...

  10. RTSP Monitor的总结

    项目描述: 一个本地的IP  Camera 实时发送RTSP视频流到本机上,视频的帧是H264编码,需要解码并显示到屏幕上.并把每帧视频对应的时间戳转换成日期年月日时分秒打印到每帧的图像上显示. 使用 ...