asp.net 利用NPOI导出Excel通用类的方法
解决中文文件名保存Excel乱码问题,主要是判断火狐或者IE浏览器,然后做对应的判断处理,核心代码如下:
System.Web.HttpContext.Current.Response.ContentType="application/vnd.ms-excel"; //设置下载的Excel文件名\ if(System.Web.HttpContext.Current.Request.ServerVariables["http_user_agent"].ToString().IndexOf("Firefox")!=-1) { //火狐浏览器 System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition",string.Format("attachment;filename={0}","=?UTF-8?B?"+Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(fileName))+"?=")); } else { //IE等浏览器 System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition",string.Format("attachment;filename={0}",System.Web.HttpUtility.UrlEncode(fileName,System.Text.Encoding.UTF8))); }
废话不多说,直接上类库代码,ATNPOIHelper.cs:
usingSystem; usingSystem.Linq; usingSystem.Web; usingSystem.IO; usingNPOI; usingNPOI.SS.Util; usingNPOI.HSSF.Util; usingNPOI.SS.UserModel; usingNPOI.HSSF.UserModel; usingSystem.Data; usingSystem.Collections.Generic; usingSystem.Text; namespaceAT.Utility.DotNetFile { /* 导出Excel包含的功能: 1.多表头导出最多支持到三行,表头格式说明 相邻父列头之间用'#'分隔,父列头与子列头用空格('‘)分隔,相邻子列头用逗号分隔(‘,') 两行:序号#分公司#组别#本日成功签约单数预警,续约,流失,合计#累计成功签约单数预警,续约,流失,合计#任务数#完成比例#排名 三行:等级#级别#上期结存件数,重量,比例#本期调入收购调入件数,重量,比例#本期发出车间投料件数,重量,比例#本期发出产品外销百分比件数,重量,比例#平均值 三行时请注意:列头要重复 2.添加表头标题功能 3.添加序号功能 4.根据数据设置列宽 缺陷: 数据内容不能合并列合并行 改进思路: 添加一属性:设置要合并的列,为了实现多列合并可以这样设置{“列1,列2”,”列4”} */ //////利用NPOI实现导出Excel /// publicclassATNPOIHelper { #region初始化 //////声明HSSFWorkbook对象 /// privatestaticHSSFWorkbook_workbook; //////声明HSSFSheet对象 /// privatestaticHSSFSheet_sheet; #endregion #regionExcel导出 //////Excel导出 /// ///文件名称如果为空或NULL,则默认“新建Excel.xls” /// /// 合计:末行合计时,合并的列数 /// 导出方式1:WEB导出(默认)2:按文件路径导出 /// 文件路径如果WEB导出,则可以为空;如果按文件路径导出,则默认桌面路径 publicstaticvoidExport(stringfileName,IList list,intColMergeNum,intmethod=1,stringfilePath=null) { //文件名称 if(!string.IsNullOrEmpty(fileName)) { if(fileName.IndexOf('.')==-1) { fileName+=".xls"; } else { fileName=fileName.Substring(1,fileName.IndexOf('.'))+".xls"; } } else { fileName="新建Excel.xls"; } //文件路径 if(2==method&&string.IsNullOrEmpty(filePath)) { filePath=Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } //调用导出处理程序 Export(list,ColMergeNum); //WEB导出 if(1==method) { System.Web.HttpContext.Current.Response.ContentType="application/vnd.ms-excel"; //设置下载的Excel文件名\ if(System.Web.HttpContext.Current.Request.ServerVariables["http_user_agent"].ToString().IndexOf("Firefox")!=-1) { //火狐浏览器 System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition",string.Format("attachment;filename={0}","=?UTF-8?B?"+Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(fileName))+"?=")); } else { //IE等浏览器 System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition",string.Format("attachment;filename={0}",System.Web.HttpUtility.UrlEncode(fileName,System.Text.Encoding.UTF8))); } using(MemoryStreamms=newMemoryStream()) { //将工作簿的内容放到内存流中 _workbook.Write(ms); //将内存流转换成字节数组发送到客户端 System.Web.HttpContext.Current.Response.BinaryWrite(ms.GetBuffer()); System.Web.HttpContext.Current.Response.End(); _sheet=null; _workbook=null; } } elseif(2==method) { using(FileStreamfs=File.Open(filePath,FileMode.Append)) { _workbook.Write(fs); _sheet=null; _workbook=null; } } } /// ///导出方法实现 /// ///privatestaticvoidExport(IList list,intColMergeNum) { #region变量声明 //初始化 _workbook=newHSSFWorkbook(); //声明Row对象 IRow_row; //声明Cell对象 ICell_cell; //总列数 intcols=0; //总行数 introws=0; //行数计数器 introwIndex=0; //单元格值 stringdrValue=null; #endregion foreach(NPOIModelmodelinlist) { //工作薄命名 if(model.sheetName!=null) _sheet=(HSSFSheet)_workbook.CreateSheet(model.sheetName); else _sheet=(HSSFSheet)_workbook.CreateSheet(); //获取数据源 DataTabledt=model.dataSource; //初始化 rowIndex=0; //获取总行数 rows=GetRowCount(model.headerName); //获取总列数 cols=GetColCount(model.headerName); //合计:合并表格末行N列,rows为表头行数,dt.Rows.Count为数据行数 if(ColMergeNum>1) { CellRangeAddressregion_Merge=newCellRangeAddress(rows+dt.Rows.Count,rows+dt.Rows.Count,0,ColMergeNum-1); _sheet.AddMergedRegion(region_Merge); } ICellStylemyBodyStyle=bodyStyle; ICellStylemyTitleStyle=titleStyle; ICellStylemyDateStyle=dateStyle; ICellStylemyBodyRightStyle=bodyRightStyle; //循环行数 foreach(DataRowrowindt.Rows) { #region新建表,填充表头,填充列头,样式 if(rowIndex==65535||rowIndex==0) { if(rowIndex!=0) _sheet=(HSSFSheet)_workbook.CreateSheet(); //构建行 for(inti=0;i 0) { //获取行 _row=_sheet.GetRow(0); //合并单元格 CellRangeAddressregion=newCellRangeAddress(0,0,0,(cols-1)); _sheet.AddMergedRegion(region); //填充值 _row.CreateCell(0).SetCellValue(model.tableTitle); //设置样式 _row.GetCell(0).CellStyle=myTitleStyle; //设置行高 _row.HeightInPoints=20; } //取得上一个实体 NPOIHeaderlastRow=null; IList hList=GetHeaders(model.headerName,rows,model.isTitle); //创建表头 foreach(NPOIHeaderminhList) { vardata=hList.Where(c=>c.firstRow==m.firstRow&&c.lastCol==m.firstCol-1); if(data.Count()>0) { lastRow=data.First(); if(m.headerName==lastRow.headerName) m.firstCol=lastRow.firstCol; } //获取行 _row=_sheet.GetRow(m.firstRow); //合并单元格 CellRangeAddressregion=newCellRangeAddress(m.firstRow,m.lastRow,m.firstCol,m.lastCol); _sheet.AddMergedRegion(region); //填充值 _row.CreateCell(m.firstCol).SetCellValue(m.headerName); } //填充表头样式 for(inti=0;i ///表头解析 /// /// /// ///表头 /// 总行数 /// 外加行 /// 外加列 /// privatestaticIList GetHeaders(stringheader,introws,intaddRows) { //临时表头数组 string[]tempHeader; string[]tempHeader2; //所跨列数 intcolSpan=0; //所跨行数 introwSpan=0; //单元格对象 NPOIHeadermodel=null; //行数计数器 introwIndex=0; //列数计数器 intcolIndex=0; // IList list=newList (); //初步解析 string[]headers=header.Split(newstring[]{"#"},StringSplitOptions.RemoveEmptyEntries); //表头遍历 for(inti=0;i ///获取最大列 /// /// /// privatestaticintGetMaxCol(IList list) { intmaxCol=0; if(list.Count>0) { foreach(NPOIHeadermodelinlist) { if(maxCol ///获取表头行数 /// /// 表头文字 /// privatestaticintGetRowCount(stringnewHeaders) { string[]ColumnNames=newHeaders.Split(newchar[]{'@'}); intCount=0; if(ColumnNames.Length<=1) ColumnNames=newHeaders.Split(newchar[]{'#'}); foreach(stringnameinColumnNames) { intTempCount=name.Split(newchar[]{''}).Length; if(TempCount>Count) Count=TempCount; } returnCount; } /// ///获取表头列数 /// ///表头文字 /// privatestaticintGetColCount(stringnewHeaders) { string[]ColumnNames=newHeaders.Split(newchar[]{'@'}); intCount=0; if(ColumnNames.Length<=1) ColumnNames=newHeaders.Split(newchar[]{'#'}); Count=ColumnNames.Length; foreach(stringnameinColumnNames) { intTempCount=name.Split(newchar[]{','}).Length; if(TempCount>1) Count+=TempCount-1; } returnCount; } /// ///列头跨列数 /// ////// ///表头文字 /// privatestaticintGetColSpan(stringnewHeaders) { returnnewHeaders.Split(',').Count(); } /// ///列头跨行数 /// ////// ///列头文本 /// 表头总行数 /// privatestaticintGetRowSpan(stringnewHeaders,introws) { intCount=newHeaders.Split(newstring[]{""},StringSplitOptions.RemoveEmptyEntries).Length; //如果总行数与当前表头所拥有行数相等 if(rows==Count) Count=1; elseif(Count ///数据单元格样式 /// privatestaticICellStylebodyStyle { get { ICellStylestyle=_workbook.CreateCellStyle(); style.Alignment=HorizontalAlignment.CENTER;//居中 style.VerticalAlignment=VerticalAlignment.CENTER;//垂直居中 style.WrapText=true;//自动换行 //边框 style.BorderBottom=BorderStyle.THIN; style.BorderLeft=BorderStyle.THIN; style.BorderRight=BorderStyle.THIN; style.BorderTop=BorderStyle.THIN; //字体 //IFontfont=_workbook.CreateFont(); //font.FontHeightInPoints=10; //font.FontName="宋体"; //style.SetFont(font); returnstyle; } } /// ///数据单元格样式 /// privatestaticICellStylebodyRightStyle { get { ICellStylestyle=_workbook.CreateCellStyle(); style.Alignment=HorizontalAlignment.RIGHT;//居中 style.VerticalAlignment=VerticalAlignment.CENTER;//垂直居中 style.WrapText=true;//自动换行 //边框 style.BorderBottom=BorderStyle.THIN; style.BorderLeft=BorderStyle.THIN; style.BorderRight=BorderStyle.THIN; style.BorderTop=BorderStyle.THIN; //字体 //IFontfont=_workbook.CreateFont(); //font.FontHeightInPoints=10; //font.FontName="宋体"; //style.SetFont(font); returnstyle; } } //////标题单元格样式 /// privatestaticICellStyletitleStyle { get { ICellStylestyle=_workbook.CreateCellStyle(); style.Alignment=HorizontalAlignment.CENTER;//居中 style.VerticalAlignment=VerticalAlignment.CENTER;//垂直居中 style.WrapText=true;//自动换行 //IFontfont=_workbook.CreateFont(); //font.FontHeightInPoints=14; //font.FontName="宋体"; //font.Boldweight=(short)FontBoldWeight.BOLD; //style.SetFont(font); returnstyle; } } //////日期单元格样式 /// privatestaticICellStyledateStyle { get { ICellStylestyle=_workbook.CreateCellStyle(); style.Alignment=HorizontalAlignment.CENTER;//居中 style.VerticalAlignment=VerticalAlignment.CENTER;//垂直居中 style.WrapText=true;//自动换行 //边框 style.BorderBottom=BorderStyle.THIN; style.BorderLeft=BorderStyle.THIN; style.BorderRight=BorderStyle.THIN; style.BorderTop=BorderStyle.THIN; //字体 //IFontfont=_workbook.CreateFont(); //font.FontHeightInPoints=10; //font.FontName="宋体"; //style.SetFont(font); IDataFormatformat=_workbook.CreateDataFormat(); style.DataFormat=format.GetFormat("yyyy-MM-dd"); returnstyle; } } #endregion #endregion } //////实体类 /// publicclassNPOIModel { //////数据源 /// publicDataTabledataSource{get;privateset;} //////要导出的数据列数组 /// publicstring[]fileds{get;privateset;} //////工作薄名称数组 /// publicstringsheetName{get;privateset;} //////表标题 /// publicstringtableTitle{get;privateset;} //////表标题是否存在1:存在0:不存在 /// publicintisTitle{get;privateset;} //////是否添加序号 /// publicintisOrderby{get;privateset;} //////表头 /// publicstringheaderName{get;privateset;} //////取得列宽 /// publicint[]colWidths{get;privateset;} //////构造函数 /// ////// ///数据来源DataTable /// 要导出的字段,如果为空或NULL,则默认全部 /// 工作薄名称 /// 表头名称如果为空或NULL,则默认数据列字段 ///相邻父列头之间用'#'分隔,父列头与子列头用空格('')分隔,相邻子列头用逗号分隔(',') ///两行:序号#分公司#组别#本日成功签约单数预警,续约,流失,合计#累计成功签约单数预警,续约,流失,合计#任务数#完成比例#排名 ///三行:等级#级别#上期结存件数,重量,比例#本期调入收购调入件数,重量,比例#本期发出车间投料件数,重量,比例#本期发出产品外销百分比件数,重量,比例#平均值 ///三行时请注意:列头要重复 /// /// 表标题 /// 是否添加序号0:不添加1:添加 publicNPOIModel(DataTabledataSource,stringfiled,stringsheetName,stringheaderName,stringtableTitle=null,intisOrderby=0) { if(!string.IsNullOrEmpty(filed)) { this.fileds=filed.ToUpper().Split(newstring[]{";"},StringSplitOptions.RemoveEmptyEntries); //移除多余数据列 for(inti=dataSource.Columns.Count-1;i>=0;i--) { DataColumndc=dataSource.Columns[i]; if(!this.fileds.Contains(dataSource.Columns[i].Caption.ToUpper())) { dataSource.Columns.Remove(dataSource.Columns[i]); } } //列索引 intcolIndex=0; //循环排序 for(inti=0;i colWidths[j]) { colWidths[j]=intTemp; } } } if(isOrderby>0) { this.isOrderby=isOrderby; this.headerName="序号#"+this.headerName; } } /// ///获取列名下标 /// ///列名称 /// privateintGetColIndex(stringcolName) { for(inti=0;i ///表头构建类 /// publicclassNPOIHeader { /// ///表头 /// publicstringheaderName{get;set;} //////起始行 /// publicintfirstRow{get;set;} //////结束行 /// publicintlastRow{get;set;} //////起始列 /// publicintfirstCol{get;set;} //////结束列 /// publicintlastCol{get;set;} //////是否跨行 /// publicintisRowSpan{get;privateset;} //////是否跨列 /// publicintisColSpan{get;privateset;} //////外加行 /// publicintrows{get;set;} publicNPOIHeader(){} //////构造函数 /// ///表头 /// 起始行 /// 结束行 /// 起始列 /// 结束列 /// 外加行 /// 外加列 publicNPOIHeader(stringheaderName,intfirstRow,intlastRow,intfirstCol,intlastCol,introws=0) { this.headerName=headerName; this.firstRow=firstRow; this.lastRow=lastRow; this.firstCol=firstCol; this.lastCol=lastCol; //是否跨行判断 if(firstRow!=lastRow) isRowSpan=1; if(firstCol!=lastCol) isColSpan=1; this.rows=rows; } } }
3、导出代码示例如下:
//////导出测点列表表格 /// [HttpGet] [AllowAnonymous] publicvoidExportMeasurePointData(stringTreeID,stringTreeType) { DataTabledtResult=newDataTable(); DataTabledtExcel=newDataTable(); try { stringsql=string.Format("EXECP_GET_ZXJG_TagList'{0}','{1}'",TreeID,TreeType); dtResult=QuerySQL.GetDataTable(sql); dtExcel=dtResult.Copy(); dtExcel.Columns.Add("xuhao",typeof(string)); dtExcel.Columns.Add("StrValueTime",typeof(string)); dtExcel.Columns["xuhao"].SetOrdinal(0); dtExcel.Columns["StrValueTime"].SetOrdinal(2); for(inti=0;ilist=newList (); list.Add(newNPOIModel(dtExcel,"xuhao;F_Description;StrValueTime;F_Value;F_Unit;F_AlmLow;F_AlmUp","sheet","序号#监测点#采集时间#当前数值#工程单位#报警下限#报警上限")); ATNPOIHelper.Export("测点列表",list,0); } catch(Exceptionex) { } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。