NPOI导出excel
Posted bmyblogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NPOI导出excel相关的知识,希望对你有一定的参考价值。
本人工作之余特地写了这篇文章,鄙人不才,以前几乎没做过导出导入这类的工作,最近自己独立开发了几个项目,都用到了导出,于是便来一篇文章,记录一下,方便以后查找,也方便各位新手!
例子比较简单,不喜勿喷,如果有其它补充,请留言!谢谢!以下导出采用的是导出DataTable,没有做过多复杂的!
1. NPOI 帮助类,我使用的是 V2.3.0,改造的代码:
using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.SS.Util; using NPOI.XSSF.UserModel; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Text; namespace bmy.Common { public static class NPOIExcelHelper { /// <summary> /// 组装workbook. /// </summary> /// <param name="dictionary">列头</param> /// <param name="dt">dataTable数据</param> /// <param name="columnHeader">表头</param> /// <returns></returns> public static HSSFWorkbook BuildWorkbook1(Dictionary<string, string> dictionary, DataTable dt, string columnHeader = "") { var workbook = new HSSFWorkbook(); ISheet sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName); var dateStyle = workbook.CreateCellStyle(); var format = workbook.CreateDataFormat(); dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); //取得列宽 // var arrColWidth = new int[dt.Columns.Count]; var arrColWidth = new int[dictionary.Count + 1]; int itemCoutn = 0;//需要导出的列的数量. foreach (DataColumn item in dt.Columns) { //判断需要导出的 “列” if (dictionary.ContainsKey(item.ColumnName)) { arrColWidth[itemCoutn] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length; itemCoutn++; } } itemCoutn = 0; for (var i = 0; i < dt.Rows.Count; i++) { for (var j = 0; j < dt.Columns.Count; j++) { //判断需要导出的 “列” if (dictionary.ContainsKey(dt.Rows[i][j].ToString())) { int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length; if (intTemp > arrColWidth[j]) { arrColWidth[j] = intTemp; } } } } int rowIndex = 0;//行索引,第一行为:表头(列头) foreach (DataRow row in dt.Rows) { #region 表头 列头 if (rowIndex == 65535 || rowIndex == 0) { if (rowIndex != 0) { sheet = workbook.CreateSheet(); } #region 表头及样式 { IRow headerRow = sheet.CreateRow(0); headerRow.HeightInPoints = 19.5F; headerRow.Height = 40 * 20; headerRow.CreateCell(0).SetCellValue(columnHeader); //CellStyle ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中 headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 // 设置单元格的背景颜色(单元格的样式会覆盖列或行的样式) headStyle.FillForegroundColor = (short)11; //定义font IFont font = workbook.CreateFont(); font.FontHeightInPoints = 20; font.Boldweight = 700; headStyle.SetFont(font); headerRow.GetCell(0).CellStyle = headStyle; //根据表的列数计算 //sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dt.Columns.Count - 1)); sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dictionary.Count)); #endregion } { #region 列头及样式 var headerRow = sheet.CreateRow(1); //CellStyle ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中 headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 //定义font IFont font = workbook.CreateFont(); font.FontHeightInPoints = 10; font.Boldweight = 700; headStyle.SetFont(font); int columnCount = 0; foreach (var dic in dictionary) { foreach (DataColumn column in dt.Columns) { //判断需要导出的 “列” if (dic.Key.ToLower()==column.ColumnName.ToLower()) { //headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName); //headerRow.GetCell(column.Ordinal).CellStyle = headStyle; //sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256); headerRow.CreateCell(columnCount).SetCellValue(dic.Value);//column.ColumnName headerRow.GetCell(columnCount).CellStyle = headStyle; sheet.SetColumnWidth(columnCount, (arrColWidth[columnCount]) * 256); columnCount++; continue; } } } #endregion } rowIndex = 2; } #endregion #region 内容 var dataRow = sheet.CreateRow(rowIndex); int columnContentCount = 0; //column.Ordinal foreach (var dicKey in dictionary) { foreach (DataColumn column in dt.Columns) { //判断需要导出的 “列” if (dicKey.Key.ToLower()==column.ColumnName.ToLower()) { var newCell = dataRow.CreateCell(columnContentCount); 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; } columnContentCount++;//列索引 continue; } } } #endregion rowIndex++; } //自动列宽 for (int i = 0; i <= dictionary.Count; i++) sheet.AutoSizeColumn(i, true); return workbook; } } }
2.调用,先保存数据到文件夹,再将文件返回给调用页面提供下载,下载完成就删除文件,节省资源。
public static string WriteSheet(Dictionary<string, string> dictionary, DataTable dt, string path, string sheetName) { HSSFWorkbook newBook = BuildWorkbook1(dictionary, dt, sheetName); string date = DateTime.Now.ToString("yyyyMMddHHmmss"); string fileName = sheetName + "_" + date; #region 保存C:ExcelList //string urlPath = "\ExcelList\" + fileName; //string filePath = urlPath; //string directoryName = Path.GetDirectoryName(urlPath); //if (!Directory.Exists(directoryName)) //{ // Directory.CreateDirectory(directoryName); //} //using (var fs = File.OpenWrite(urlPath + ".xls")) //{ // newBook.Write(fs); // Console.WriteLine("生成成功"); //} #endregion string urlPath2 = "/ExcelList/" + fileName; string directoryName2 = Path.GetDirectoryName(urlPath2); string newUrl = path + directoryName2; if (!Directory.Exists(newUrl)) { Directory.CreateDirectory(newUrl); } using (var fs = File.OpenWrite(path + urlPath2 + ".xls")) { newBook.Write(fs); Console.WriteLine("生成成功"); } return fileName + ".xls"; }
3.页面调用方法, Dictionary<string, string>的作用就是将要导出的DataTable数据的字段,换成中文名称,方便阅读。
Dictionary<string, string> dictionary = new Dictionary<string, string>(); DataTable dt = ExcelExport(1, 10000); if (dt.Rows.Count > 0) { sheetName = "待审核订单列表"; dictionary.Add("OrderNo", "待审核订单号"); dictionary.Add("Mobile", "手机号码"); //返回路径下载 string path = System.AppDomain.CurrentDomain.BaseDirectory; string fileName = MxWeiXinPF.Common.NPOIExcelHelper.WriteSheet(dictionary, dt, path, sheetName); //文件夹 string folder = "/ExcelList/"; //下载 this.ResponDown(Response, path, folder, fileName);
4.下载方法
/// <summary> /// 下载 /// </summary> /// <param name="response">封装来自ASP.NET 的http相应消息</param> /// <param name="path">文件路径</param> /// <param name="folder">文件夹</param> /// <param name="fileName">文件名</param> public void ResponDown(HttpResponse response, string path, string folder, string fileName) { response.Clear(); response.ClearHeaders(); response.Buffer = false; response.ContentType = "application/ms-excel"; response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)); //Response.Write(writer); FileStream file = new FileStream(path + folder + fileName, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader br = new BinaryReader(file); response.AppendHeader("Content-Length", file.Length.ToString()); // StringReader sr = new StringReader(writer.GetStringBuilder().ToString()); long flen = file.Length; int size = 102400;//每100k同时下载数据 byte[] readdata = new byte[size];//指定缓冲区的大小 if (size > flen) size = Convert.ToInt32(flen); long fpos = 0; bool isend = false; while (!isend) { if (response.IsClientConnected) { if ((fpos + size) > flen) { size = Convert.ToInt32(flen - fpos); readdata = new byte[size]; isend = true; } if (size > 1) { br.Read(readdata, 0, size);//读入一个压缩块 // byte[] re = Encoding.UTF8.GetBytes(readdata, 0, readdata.Length); response.BinaryWrite(readdata); //Response.OutputStream.Write(re, 0, size); } fpos += size; } else { response.End(); } } file.Close(); br.Close(); response.Flush(); Response.Close(); File.Delete(path + folder + fileName); //删除文件 response.End(); }
最后,完成!只是简单记录,对于代码没有更好的优化,尽量以后整理好点贡献给大家!
以上是关于NPOI导出excel的主要内容,如果未能解决你的问题,请参考以下文章