.Net之Nopi Excel数据导出和批量导入功能
一、介绍NPOI和编写demo的原因
Npoi是什么:
它是一个专门用于读写Microsoft Office二进制和OOXML文件格式的.NET库,我们使用它能够轻松的实现对应数据的导入,导出功能,并且还能通过其对应的属性对Excel进行对应的样式调整。是一个简洁而又强大的第三方库。
编写该demo的原因:
首先是为了巩固自己,其次是为了帮助一些刚开始接触的开发者更快的了解该库的操作原理。并且很多开发者在使用npoi进行大量数据导入的时候经常会遇到数据操作时间过长问题,不知道如何优化的。其实这样优化导入的方式有很多,不过一般为了提高效率都会使用T-sql进行数据批量的导入,大家需要优化导入的话可以参考下邹大佬的(http://www.cnblogs.com/jiekzou/p/6145550.html)这篇博客写的非常的详细,而我在这次使用的是EF 的 AddRange 批量插入,并且是用来layui前端框架进行了相应的布局,该demo已上传到了我的github中,需要的可以下载,地址会在文章结尾奉上。
二、导入、导出的功能实现和逻辑代码展示
首先看看界面效果:

首先通过Nuget下载安装Npoi:

批量导入:
/// <summary>
/// 数据导入
/// </summary>
/// <param name="FileStram"></param>
/// <returns></returns>
public ActionResult DataImport(HttpPostedFileBase file)
{
var message="";
int Columns = ;
//判断是否提交excel文件
var FileName = file.FileName.Split('.');
if (file!=null&&file.ContentLength>)
{
if (FileName[]=="xls"||FileName[]== "xlsx")
{
//首先我们需要导入数据的话第一步其实就是先把excel数据保存到本地中,然后通过Npoi封装的方法去读取已保存的Excel数据 string DictorysPath=Server.MapPath("~/Content/ExcelFiles/"+ DateTime.Now.ToString("yyyyMMdd"));
if (!System.IO.Directory.Exists(DictorysPath))
{
System.IO.Directory.CreateDirectory(DictorysPath);
} file.SaveAs(System.IO.Path.Combine(DictorysPath,file.FileName)); //将Excel数据转化为DataTable数据源
DataTable Dt=NpoiHelper.Import(System.IO.Path.Combine(DictorysPath, file.FileName), FileName[]);
List<UserInfo> list = new List<UserInfo>(); for (int i = ; i < Dt.Rows.Count; i++)
{
UserInfo U = new UserInfo();
//从行索引从1开始,标题除外
U.UserName = Dt.Rows[i][].ToString();
U.Sex = Dt.Rows[i][].ToString();
U.Phone = Dt.Rows[i][].ToString();
U.Hobby = Dt.Rows[i][].ToString();
list.Add(U);
} //数据全部添加
UserEntites.Set<UserInfo>().AddRange(list);
Columns=UserEntites.SaveChanges();
if (Columns>)
{
message = "导入成功";
}
else
{
message = "导入失败";
} }
else
{
message = "格式错误";
}
}
else
{
message = "未找到需要导入的数据";
}
ViewBag.Columns = Columns;
ViewBag.Message = message;
return View();
}
导出:
/// <summary>
/// 数据导出
/// </summary>
/// <returns></returns>
[HttpPost]
public JsonResult Export()
{
try
{
//导出所有数据
var All_ListData = UserEntites.UserInfo.ToList(); //将list 转化为datatable类型
var Dt = DatabaseOpreas._.ListToDataTable(All_ListData); NpoiHelper.Export(Dt, "用户信息", Server.MapPath("~/Content/Export.xls"));//这里的路径是需要写入你需要保存的文件格式的,不需要创建自动检测创建 return Json(new {code=,msg= "/Content/Export.xls" });
}
catch (Exception ex)
{
return Json(new {code=,msg=ex.Message });
} }
NPOI导入导出帮助类:
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Utility
{
/// <summary>
/// NPOI操作帮助类
/// </summary>
public class NpoiHelper
{
/// <summary>
/// DataTable导出到Excel文件
/// </summary>
/// <param name="dtSource">源DataTable</param>
/// <param name="strHeaderText">表头文本</param>
/// <param name="strFileName">保存位置</param>
public static void Export(DataTable dtSource, string strHeaderText, string strFileName)
{
using (MemoryStream ms = Export(dtSource, strHeaderText))
{
using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
{
//数据填写
byte[] data = ms.ToArray();
fs.Write(data, , data.Length);
fs.Flush();
}
}
} /// <summary>
/// DataTable导出到Excel的MemoryStream
/// </summary>
/// <param name="dtSource">源DataTable</param>
/// <param name="strHeaderText">表头文本</param>
public static MemoryStream Export(DataTable dtSource, string strHeaderText)
{
HSSFWorkbook workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet(); ICellStyle dateStyle = workbook.CreateCellStyle();
IDataFormat format = workbook.CreateDataFormat();
dateStyle.DataFormat = format.GetFormat("yyyy-MM-dd"); #region 取得每列的列宽(最大宽度)
int[] arrColWidth = new int[dtSource.Columns.Count];
foreach (DataColumn item in dtSource.Columns)
{
//GBK对应的code page是CP936
arrColWidth[item.Ordinal] = Encoding.GetEncoding().GetBytes(item.ColumnName.ToString()).Length;
}
for (int i = ; i < dtSource.Rows.Count; i++)
{
for (int j = ; j < dtSource.Columns.Count; j++)
{
int intTemp = Encoding.GetEncoding().GetBytes(dtSource.Rows[i][j].ToString()).Length;
if (intTemp > arrColWidth[j])
{
arrColWidth[j] = intTemp;
}
}
}
#endregion int rowIndex = ; foreach (DataRow row in dtSource.Rows)
{
#region 新建表,填充表头,填充列头,样式
if (rowIndex == || rowIndex == )
{
if (rowIndex != )
{
sheet = workbook.CreateSheet();
} #region 表头及样式
{
IRow headerRow = sheet.CreateRow();
headerRow.HeightInPoints = ;
headerRow.CreateCell().SetCellValue(strHeaderText);//第一列表头名称 ICellStyle headStyle = workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
IFont font = workbook.CreateFont();
font.FontHeightInPoints = ;
font.Boldweight = ;
headStyle.SetFont(font); headerRow.GetCell().CellStyle = headStyle; sheet.AddMergedRegion(new CellRangeAddress(, , , dtSource.Columns.Count - ));
}
#endregion #region 列头及样式
{
//也可自定义标题名称,填写到 headerRow.CreateCell(1).SetCellValue();需使用directory<string,string>先填写标题,然后遍历操作中即可
IRow headerRow = sheet.CreateRow();
ICellStyle headStyle = workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
IFont font = workbook.CreateFont();
font.FontHeightInPoints = ;
font.Boldweight = ;
headStyle.SetFont(font); foreach (DataColumn column in dtSource.Columns)
{
headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
headerRow.GetCell(column.Ordinal).CellStyle = headStyle; //设置列宽
sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + ) * ); }
}
#endregion rowIndex = ;
}
#endregion #region 填充内容
ICellStyle contentStyle = workbook.CreateCellStyle();
contentStyle.Alignment = HorizontalAlignment.Left;
IRow dataRow = sheet.CreateRow(rowIndex);
foreach (DataColumn column in dtSource.Columns)
{
ICell newCell = dataRow.CreateCell(column.Ordinal);
newCell.CellStyle = contentStyle; string drValue = row[column].ToString(); switch (column.DataType.ToString())
{
case "System.String"://字符串类型
newCell.SetCellValue(drValue);
break;
case "System.DateTime"://日期类型
DateTime dateV;
DateTime.TryParse(drValue, out dateV);
newCell.SetCellValue(dateV); newCell.CellStyle = dateStyle;//格式化显示
break;
case "System.Boolean"://布尔型
bool boolV = false;
bool.TryParse(drValue, out boolV);
newCell.SetCellValue(boolV);
break;
case "System.Int16"://整型
case "System.Int32":
case "System.Int64":
case "System.Byte":
int intV = ;
int.TryParse(drValue, out intV);
newCell.SetCellValue(intV);
break;
case "System.Decimal"://浮点型
case "System.Double":
double doubV = ;
double.TryParse(drValue, out doubV);
newCell.SetCellValue(doubV);
break;
case "System.DBNull"://空值处理
newCell.SetCellValue("");
break;
default:
newCell.SetCellValue("");
break;
} }
#endregion rowIndex++;
} using (MemoryStream ms = new MemoryStream())
{
workbook.Write(ms);
ms.Flush();
ms.Position = ; //sheet.Dispose();
//workbook.Dispose();//一般只用写这一个就OK了,他会遍历并释放所有资源,但当前版本有问题所以只释放sheet
return ms;
} } /// <summary>
/// 读取excel,将数据Excel数据源转化为datatable类型
/// 默认第一行为标头
/// </summary>
/// <param name="strFileName">excel文档路径</param>
/// <returns></returns>
public static DataTable Import(string strFileName,string FileType)
{
IWorkbook hssfworkbook;
DataTable dt = new DataTable(); //HSSFWorkbook hssfworkbook;
using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))//数据读取
{
////XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式
//不同格式excle判断
if (FileType == "xls")
{
hssfworkbook = new HSSFWorkbook(file);
}
else
{
hssfworkbook = new XSSFWorkbook(file);
}
}
ISheet sheet = hssfworkbook.GetSheetAt();
System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); IRow headerRow = sheet.GetRow();
int cellCount = headerRow.LastCellNum; for (int j = ; j < cellCount; j++)
{
ICell cell = headerRow.GetCell(j);
dt.Columns.Add(cell.ToString());
} for (int i = (sheet.FirstRowNum + ); i <= sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);
DataRow dataRow = dt.NewRow(); for (int j = row.FirstCellNum; j < cellCount; j++)
{
if (row.GetCell(j) != null)
dataRow[j] = row.GetCell(j).ToString();
} dt.Rows.Add(dataRow);
}
return dt;
} }
}
三、总结
其实做任何东西我们都需要总结和积累,首先通过自己的搜索然后参考各位网上前辈的经验然后再根据自己的理解去写。其实没有什么事情是通过自己的努力解决不了的,解决不了就是说明你还不够努力,就像我做的导入就是一次导入五六十万的数据,通过查阅了一些大佬的经验最终将导入速度优化到了比较理想的结果,当然这里我只是写了一个完整的demo,大家想要深入研究的话就得花时间自己学了啦,最后附上项目地址:https://github.com/YSGStudyHards/ShipBuilding/tree/master/C%23%EF%BC%8C.Net%EF%BC%8C.Net%20Core%20%E7%BC%96%E7%A8%8B%E7%BB%83%E4%B9%A0/Asp.NetMVC%E4%B9%8BNpoi%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA%E5%AE%9E%E4%BE%8B
.Net之Nopi Excel数据导出和批量导入功能的更多相关文章
- 【基于WinForm+Access局域网共享数据库的项目总结】之篇二:WinForm开发扇形图统计和Excel数据导出
篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...
- excel数据导出新妙招
之前在做项目的时候需要将数据库中的数据导出为excel表格一遍打印查阅,在网上找了很多插件也没有找到自己理想的好用的插件(也就是说没有找到令我满意的插件),最近在学习a标签的相关知识时理解到,a标签不 ...
- java实现Excel数据导出
java实现Excel数据导出: 目前,比较常用的实现Java导入.导出Excel的技术有两种Jakarta POI和Java Excel Jakarta POI 是一套用于访问微软格式文档的Java ...
- php做EXCEL数据导出导入开发的一些小问题
前两天刚刚做开发CRM系统项目,在做要做EXCEL导出导入功能,因为以前做.NET开发用的是NPOI,但可是没找到PHP版本的,所以就网搜找了个国外的开源PHPEXCEL , 一开始只是做了简单的导入 ...
- NOPI Excel 数据导入到数据库
/// <summary> /// 上传excel文件 并将文件数据导入到数据库 /// </summary> /// <param name="file&qu ...
- Excel 数据导出
Web controller /// <summary> /// 导出数据 /// </summary> /// <param name="UserID&qu ...
- python Excel数据导出
import pymysql,os,time,xlwtpymysql.install_as_MySQLdb() try: #创建一个excel工作簿,编码utf-8,表格中支持中文 wb=xlwt.W ...
- epplus excel数据导出(数据量有点大的情况) Web和Client
Asp.net MVC后台代码 public ActionResult Export() { OfficeOpenXml.ExcelPackage ep = new OfficeOpenXml.Exc ...
- PHPExcel 导入Excel数据 (导出下一篇我们继续讲解)
一:使用composer下载 phpoffice/phpexcel 或者直接下载安装包 composer require phpoffice/phpexcel 二 1:导入数据 原理:读取文件,获取文 ...
随机推荐
- Java集合排序及java集合类详解--(Collection, List, Set, Map)
1 集合框架 1.1 集合框架概述 1.1.1 容器简介 到目前为止,我们已经学习了如何创建多个不同的对象,定义了这些对象以后,我们就可以利用它们来做一 ...
- Java Script 学习笔记 (二) Casper JS
1. click() VS mouse.click() 在写自动化脚本要勾选一个复选框时,用casper.mouse.click() 无法选上这个checkbox, 需要用到casper.click( ...
- orcl数据库先决条件检查时失败
在服务里面开启下面服务,在cmd输入 services.msc 就能打开[服务] 在cmd输入以下命令 我的是server服务没开,然后开了资源共享,就安装成功了
- bzoj5342 CTSC2018 Day1T3 青蕈领主
首先显然的是,题中所给出的n个区间要么互相包含,要么相离,否则一定不合法. 然后我们可以对于直接包含的关系建出一棵树,于是现在的问题就是给n个节点分配权值,使其去掉最后一个点后不存在非平凡(长度大于1 ...
- loj548 「LibreOJ β Round #7」某少女附中的体育课
这道题好神啊!!! 发现这题就是定义了一种新的卷积,然后做k+1次卷积. 这里我们就考虑构造一个变换T,使得$T(a) \cdot T(b) =T(a∘b)$,这里是让向量右乘这个转移矩阵. 于是我们 ...
- 【建图+拓扑判环】BZOJ3953: [WF2013]Self-Assembly
Description 自动化学制造(Automatic Chemical Manufacturing,简称ACM)正在对一个叫自组装(self-assembly)的过程进行实验.在这个过程中,有着天 ...
- BZOJ_3011_[Usaco2012 Dec]Running Away From the Barn _可并堆
BZOJ_3011_[Usaco2012 Dec]Running Away From the Barn _可并堆 Description 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于l的 ...
- 用Java为Hyperledger Fabric(超级账本)编写区块链智能合约链代码
编写第一个 Java 链代码程序 在上一节中,您已经熟悉了如何构建.运行.部署和调用链代码,但尚未编写任何 Java 代码. 在本节中,将会使用 Eclipse IDE.一个用于 Eclipse 的 ...
- ISCC 2018 Writeup
题解部分:Misc(除misc500).Web(除Only Admin.Only admin can see flag.有种你来绕.试试看).Reverse.Pwn.Mobile Misc( Auth ...
- 使用Entity Framework Core访问数据库(Oracle篇)
前言 哇..看看时间 真的很久很久没写博客了 将近一年了. 最近一直在忙各种家中事务和公司的新框架 终于抽出时间来更新一波了. 本篇主要讲一下关于Entity Framework Core访问ora ...