分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 代码编程

NET使用NPOI组件导出Excel-入门示例及通用方法

发布时间:2023-09-06 02:19责任编辑:赖小花关键词:组件

一、Excel导入及导出问题产生:

 
  从接触.net到现在一直在维护一个DataTable导出到Excel的类,时不时还会维护一个导入类。以下是时不时就会出现的问题:
 
导出问题:
 
  如果是asp.net,你得在服务器端装Office,几百M呢,还得及时更新它,以防漏洞,还得设定权限允许ASP.net访问COM+,听说如果导出过程中出问题可能导致服务器宕机。
 
  Excel会把只包含数字的列进行类型转换,本来是文本型的,它非要把你转成数值型的,像身份证后三位变成000,编号000123会变成123,够智能吧,够郁闷吧。不过这些都还是可以变通解决的,在他们前边加上一个字母,让他们不只包含数字。
 
  导出时,如果你的字段内容以"-"或"="开头,Excel好像把它当成了公式什么的,接下来就出错,提示:类似,保存到Sheet1的问题
 
导入问题:
 
  Excel会根据你的 Excel文件前8行分析数据类型,如果正好你前8行某一列只是数字,那它会认为你这一列就是数值型的,然后,身份证,手机,编号都转吧变成类似这样的1.42702E+17格式,日期列变成 包含日期和数字的,乱的很,可以通过改注册表让Excel分析整个表,但如果整列都是数字,那这个问题还是解决不了。
 
 
  以上问题,一般人初次做时肯定得上网查查吧,一个问题接着另一个问题,查到你郁郁而死,还有很多问题没解决,最终感觉已经解决的不错了,但还不能保证某一天还会出个什么问题。
 

二、使用第三方开源组件导入及导出Excel的解决方案:

 
  偶然间发现了NPOI与MyXls,相见恨晚,害的我在Excel上浪费了那么多时间,他们俩的好处是:就是.net的自定义类库,可以直接对Excel进行读或写,而不依赖Office 的 Excel,这不管对于ASP.net或Winform都非常有利,不用担心Excel进程的释放问题,服务器安全,设置,导出,导入“Excel智能识别”,公式日期等问题,可以说以前的Excel问题,全都不用管了,它们可以很好的帮你解决,NPOI || MyXls == 研究几年Excel。
 
  NPOI开源地址:http://npoi.codeplex.com/
 
  MyXls开源地址:http://sourceforge.net/projects/myxls/
 

三、下面来两个简单入门例子:

MyXls 快速入门例子:
 /// <summary> /// MyXls简单Demo,快速入门代码 /// </summary> /// <param name="dtSource"></param> /// <param name="strFileName"></param> /// <remarks>MyXls认为Excel的第一个单元格是:(1,1)</remarks> public static void ExportEasy(DataTable dtSource, ?string strFileName) { ????XlsDocument xls = new XlsDocument(); ????Worksheet sheet = xls.Workbook.Worksheets.Add("Sheet1"); ?????//填充表头 ????foreach (DataColumn col in dtSource.Columns) ????{ ????????sheet.Cells.Add(1, col.Ordinal + 1, col.ColumnName); ????} ?????//填充内容 ????for (int i = 0; i < dtSource.Rows.Count; i++) ????{ ????????for (int j = 0; j < dtSource.Columns.Count; j++) ????????{ ????????????sheet.Cells.Add(i + 2, j + 1, dtSource.Rows[i][j].ToString()); ????????} ????} ?????//保存 ????xls.FileName = strFileName; ????xls.Save(); }
NPOI 快速入门例子:
/// <summary> /// NPOI简单Demo,快速入门代码 /// </summary> /// <param name="dtSource"></param> /// <param name="strFileName"></param> /// <remarks>NPOI认为Excel的第一个单元格是:(0,0)</remarks> public static void ExportEasy(DataTable dtSource, string strFileName) { ????HSSFWorkbook workbook = new HSSFWorkbook(); ????HSSFSheet sheet = workbook.CreateSheet(); ?????//填充表头 ????HSSFRow dataRow = sheet.CreateRow(0); ????foreach (DataColumn column in dtSource.Columns) ????{ ????????dataRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName); ????} ??????//填充内容 ????for (int i = 0; i < dtSource.Rows.Count; i++) ????{ ????????dataRow = sheet.CreateRow(i + 1); ????????for (int j = 0; j < dtSource.Columns.Count; j++) ????????{ ????????????dataRow.CreateCell(j).SetCellValue(dtSource.Rows[i][j].ToString()); ????????} ????} ??????//保存 ????using (MemoryStream ms = new MemoryStream()) ????{ ????????using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write)) ????????{ ????????????workbook.Write(fs); ????????} ????} ????workbook.Dispose(); }

四、接下来是封装的可以用在实际项目中的类,实现的功能有(仅NPOI):

 
  1. 支持web及winform从DataTable导出到Excel。
  2. 生成速度很快。
  3. 准确判断数据类型,不会出现身份证转数值等上面提到的一系列问题。
  4. 如果单页条数大于65535时会新建工作表。
  5. 列宽自适应。
  6. 支持读取Excel。
  7. 调用方便,只一调用一个静态类就OK了。
  8. 因为测试期间发现MyXls导出速度要比NPOI慢3倍,而NPOI既能满足我们的导出需求,又能很好的满足我们的导入需求,所以只针对NPOI进行全方位功能实现及优化。
NPOI操作类 ?using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.IO; using System.Text; using NPOI; using NPOI.HPSF; using NPOI.HSSF; using NPOI.HSSF.UserModel; using NPOI.HSSF.Util; using NPOI.POIFS; using NPOI.Util; ??namespace SNF.Utilities { ????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, 0, 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(); ????????????HSSFSheet sheet = workbook.CreateSheet(); ?????????????#region 右击文件 属性信息 ????????????{ ????????????????DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation(); ????????????????dsi.Company = "NPOI"; ????????????????workbook.DocumentSummaryInformation = dsi; ?????????????????SummaryInformation si = PropertySetFactory.CreateSummaryInformation(); ????????????????si.Author = "文件作者信息"; //填加xls文件作者信息 ????????????????si.ApplicationName = "创建程序信息"; //填加xls文件创建程序信息 ????????????????si.LastAuthor = "最后保存者信息"; //填加xls文件最后保存者信息 ????????????????si.Comments = "作者信息"; //填加xls文件作者信息 ????????????????si.Title = "标题信息"; //填加xls文件标题信息 ????????????????si.Subject = "主题信息";//填加文件主题信息 ????????????????si.CreateDateTime = DateTime.Now; ????????????????workbook.SummaryInformation = si; ????????????} ????????????#endregion ?????????????HSSFCellStyle dateStyle = workbook.CreateCellStyle(); ????????????HSSFDataFormat format = workbook.CreateDataFormat(); ????????????dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); ?????????????//取得列宽 ????????????int[] arrColWidth = new int[dtSource.Columns.Count]; ????????????foreach (DataColumn item in dtSource.Columns) ????????????{ ????????????????arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length; ????????????} ????????????for (int i = 0; i < dtSource.Rows.Count; i++) ????????????{ ????????????????for (int j = 0; j < dtSource.Columns.Count; j++) ????????????????{ ????????????????????int intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[i][j].ToString()).Length; ????????????????????if (intTemp > arrColWidth[j]) ????????????????????{ ????????????????????????arrColWidth[j] = intTemp; ????????????????????} ????????????????} ????????????} ?????????????int rowIndex = 0; ?????????????foreach (DataRow row in dtSource.Rows) ????????????{ ????????????????#region 新建表,填充表头,填充列头,样式 ????????????????if (rowIndex == 65535 || rowIndex == 0) ????????????????{ ????????????????????if (rowIndex != 0) ????????????????????{ ????????????????????????sheet = workbook.CreateSheet(); ????????????????????} ?????????????????????#region 表头及样式 ????????????????????{ ????????????????????????HSSFRow headerRow = sheet.CreateRow(0); ????????????????????????headerRow.HeightInPoints = 25; ????????????????????????headerRow.CreateCell(0).SetCellValue(strHeaderText); ?????????????????????????HSSFCellStyle headStyle = workbook.CreateCellStyle(); ????????????????????????headStyle.Alignment = CellHorizontalAlignment.CENTER; ????????????????????????HSSFFont font = workbook.CreateFont(); ????????????????????????font.FontHeightInPoints = 20; ????????????????????????font.Boldweight = 700; ????????????????????????headStyle.SetFont(font); ????????????????????????headerRow.GetCell(0).CellStyle = headStyle; ????????????????????????sheet.AddMergedRegion(new Region(0, 0, 0, dtSource.Columns.Count - 1)); ????????????????????????headerRow.Dispose(); ????????????????????} ????????????????????#endregion ??????????????????????#region 列头及样式 ????????????????????{ ????????????????????????HSSFRow headerRow = sheet.CreateRow(1); ?????????????????????????HSSFCellStyle headStyle = workbook.CreateCellStyle(); ????????????????????????headStyle.Alignment = CellHorizontalAlignment.CENTER; ????????????????????????HSSFFont font = workbook.CreateFont(); ????????????????????????font.FontHeightInPoints = 10; ????????????????????????font.Boldweight = 700; ????????????????????????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] + 1) * 256); ?????????????????????????} ????????????????????????headerRow.Dispose(); ????????????????????} ????????????????????#endregion ?????????????????????rowIndex = 2; ????????????????} ????????????????#endregion ??????????????????#region 填充内容 ????????????????HSSFRow dataRow = sheet.CreateRow(rowIndex); ????????????????foreach (DataColumn column in dtSource.Columns) ????????????????{ ????????????????????HSSFCell newCell = dataRow.CreateCell(column.Ordinal); ?????????????????????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 = 0; ????????????????????????????int.TryParse(drValue, out intV); ????????????????????????????newCell.SetCellValue(intV); ????????????????????????????break; ????????????????????????case "System.Decimal"://浮点型 ????????????????????????case "System.Double": ????????????????????????????double doubV = 0; ????????????????????????????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 = 0; ?????????????????sheet.Dispose(); ????????????????//workbook.Dispose();//一般只用写这一个就OK了,他会遍历并释放所有资源,但当前版本有问题所以只释放sheet ????????????????return ms; ????????????} ?????????} ?????????/// <summary> ????????/// 用于Web导出 ????????/// </summary> ????????/// <param name="dtSource">源DataTable</param> ????????/// <param name="strHeaderText">表头文本</param> ????????/// <param name="strFileName">文件名</param> ????????public static void ExportByWeb(DataTable dtSource, string strHeaderText, string strFileName) ????????{ ?????????????HttpContext curContext = HttpContext.Current; ?????????????// 设置编码和附件格式 ????????????curContext.Response.ContentType = "application/vnd.ms-excel"; ????????????curContext.Response.ContentEncoding = Encoding.UTF8; ????????????curContext.Response.Charset = ""; ????????????curContext.Response.AppendHeader("Content-Disposition", ????????????????"attachment;filename=" + HttpUtility.UrlEncode(strFileName, Encoding.UTF8)); ?????????????curContext.Response.BinaryWrite(Export(dtSource, strHeaderText).GetBuffer()); ????????????curContext.Response.End(); ?????????} ??????????/// <summary>读取excel ????????/// 默认第一行为标头 ????????/// </summary> ????????/// <param name="strFileName">excel文档路径</param> ????????/// <returns></returns> ????????public static DataTable Import(string strFileName) ????????{ ????????????DataTable dt = new DataTable(); ?????????????HSSFWorkbook hssfworkbook; ????????????using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read)) ????????????{ ????????????????hssfworkbook = new HSSFWorkbook(file); ????????????} ????????????HSSFSheet sheet = hssfworkbook.GetSheetAt(0); ????????????System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); ?????????????HSSFRow headerRow = sheet.GetRow(0); ????????????int cellCount = headerRow.LastCellNum; ?????????????for (int j = 0; j < cellCount; j++) ????????????{ ????????????????HSSFCell cell = headerRow.GetCell(j); ????????????????dt.Columns.Add(cell.ToString()); ????????????} ?????????????for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) ????????????{ ????????????????HSSFRow 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; ????????} ????} }

五、NPOI操作类的调用方法  

   DataTable dt_Grade = Tools.Data.GetDataTable(strSQL);
   filename += "绩效考核结果分数统计表";
   PMS.Common.NPOIHelper.ExportByWeb(dt_Grade, filename, filename+".xls");

六、效果展示  

 

七、NPOI类库下载:

NPOI 下载地址: http://npoi.codeplex.com/releases

官方学习网站 : http://tonyqus.sinaapp.com/

信息来源:http://www.cnblogs.com/yongfa365/archive/2010/05/10/NPOI-MyXls-DataTable-To-Excel-From-Excel.html

八、参考地址:

 
NPOI导出Excel表功能实现(多个工作簿):http://www.cnblogs.com/zhengjuzhuan/archive/2010/02/01/1661103.html
在 Server 端存取 Excel 檔案的利器:NPOI Library:http://msdn.microsoft.com/zh-tw/ee818993.aspx
ASP.NET使用NPOI类库导出Excel:http://www.cnblogs.com/niunan/archive/2010/03/30/1700706.html
 
 

九、总结:

 
  通过以上分析,我们不难发现,用NPOI或MyXls代替是Excel是很明智的,在发文前,我看到NPOI及MyXls仍然在活跃的更新中。在使用过程中发现这两个组件极相似,以前看过文章说他们使用的内核是一样的。还有NPOI是国人开发的,且有相关中文文档,在很多地方有相关引用,下载量也很大。并且它支持Excel,看到MyXls相关问题基本上没人回答,所以推荐使用NPOI。MyXls可以直接Cell.Font.Bold操作,而NPOI得使用CellType多少感觉有点麻烦。 

出处:https://www.cnblogs.com/spring_wang/p/3145689.html

=================================================================================

简单使用NPOI读取和生成Excel文件

NPOI的下载地址:http://npoi.codeplex.com/
NPOI的使用教程(中文):http://tonyqus.sinaapp.com/

这里只是写一些简单的例子以便查阅。
读取Excel文件:
//打开Excel文件using (FileStream excelfs = new FileStream("c:\\workbook.xls", FileMode.Open, FileAccess.Read)){ ???//根据“文件流”来创建HSSFWorkbook,即整个excel的工作簿 ???HSSFWorkbook workbook = new HSSFWorkbook(excelfs); ???//获取excel的第一个sheet工作表 ???HSSFSheet sheet = (HSSFSheet)workbook.GetSheetAt(0); ???//循环读取所有行的内容 ???for (int i = sheet.FirstRowNum; i <= sheet.LastRowNum; i++) ???{ ???????DataRow newRow = table.NewRow(); ???????//读取excel的行 ????????HSSFRow row = (HSSFRow)sheet.GetRow(i); ???????if (row != null) ???????{ ???????????if (row.GetCell(0) != null) ???????????{ ???????????????//复制整行数据 ?????????????????for (int j = row.FirstCellNum; j < row.Cells.Count; j++) ???????????????{ ???????????????????newRow[j] = row.GetCell(j); ???????????????} ???????????????//添加到数据表中 ?????????????????table.Rows.Add(newRow); ???????????} ???????} ???}}

生成Excel文件:

//新建workbook工作簿HSSFWorkbook workbook = new HSSFWorkbook();
//新建sheet工作表HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet();
//设置默认列宽sheet.DefaultColumnWidth = 15;
//填充工作表的内容for (int i = 0; i < dataSource.Count; i++){ ???//新建row数据行 ???HSSFRow dataRow = (HSSFRow)sheet.CreateRow(i); ???//填充数据行的内容 ???for (int j = 0; j < dataSource.ToArray().Count(); j++) ???{ ???????//新建cell单元格并填充内容 ???????dataRow.CreateCell(j).SetCellValue(dataSource[i][j].ToString()); ???}}//保存文件using (FileStream fs = new FileStream("c:\\workbook.xls", FileMode.Create, FileAccess.Write)){ ???workbook.Write(fs);}

出处:https://www.cnblogs.com/xwgli/archive/2013/04/07/3006151.html

NET使用NPOI组件导出Excel-入门示例及通用方法

原文地址:https://www.cnblogs.com/mq0036/p/9835949.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved