.net数据导出excel数据有多种方法,最常用的就是使用office组件,但随之而来的问题也很棘手,又要调权限又要确定是否安装office很是麻烦,最近一个项目中也有数据导出功能,随使用excel模板完美完成功能,调试完成发布服务器,又是一通调试,最终可以导出。但是项目中不只一处要数据导出,有四个同事来做这就带来很多麻烦,大家每人都创建了很多模板(当然很多功能属同一模块的都放在一个模板中创建了若干sheet),以后维护很麻烦。于是网上搜索到了npoi,研究了一会尝试使用npoi导出数据。
首先添加npoidll引用( NPOI.dll和Ionic.Zip.dll 注: npoi版本是NPOI_1.2.5_binary)
#region NPOI导出 public MemoryStream DataMemory(DataTable dt, string headerText) { NOPIHelper nopi = new NOPIHelper(); MemoryStream ms = new MemoryStream(); HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet(headerText); #region 文件右键属性 { DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation(); dsi.Company = "Golden3C"; workbook.DocumentSummaryInformation = dsi; SummaryInformation si = PropertySetFactory.CreateSummaryInformation(); si.Author = "hbj"; //填加xls文件作者信息 si.CreateDateTime = DateTime.Now; workbook.SummaryInformation = si; } #endregion #region 导出excel的名称 IRow row = sheet.CreateRow(0); row.HeightInPoints = 30;//行高 row.CreateCell(0).SetCellValue(headerText); sheet.GetRow(0).GetCell(0).CellStyle = nopi.SetCellStyle(workbook, 20);//设置excel单元格样式 nopi.MergedRegion(sheet, 0, 0, 0, 20); #endregion #region 排列表头 { string[] arrRow1 = new string[] { "序号", "数据类型", "年/半年/季度/月", "区县", "企业名称", "企业类型(现有、新建)", "设计生产能力(万吨/年)", "治污设施主体处理工艺", "新建减排措施投运时间(XXXX年XX月)", "产品类型(浆、机制纸及纸板、纸制品)", "产品产量(吨)", "废水排放量(吨)", "排放去向", "", "平均出水COD浓度(mg/L)", "", "平均出水氨氮浓度(mg/L)", "", "是否有治污设施中控系统", "是否安装在线监测仪器、数据与地方环保部门联网并通过有效性审核", "备注" }; IRow row1 = sheet.CreateRow(1);//第二行 row1.HeightInPoints = 20; for (int i = 0; i < arrRow1.Length; i++) { row1.CreateCell(i).SetCellValue(arrRow1[i]); row1.GetCell(i).CellStyle = nopi.SetCellStyle(workbook, 10); } string[] arrRow2 = new string[] { "","","","","","","","","","","","", "是否纳管", "纳管后排入集中污水处理设施名称", "减排措施实施前平均出水COD浓度", "减排措施实施后平均出水COD浓度", "减排措施实施前平均出水氨氮浓度", "减排措施实施后平均出水氨氮浓度","","","" }; IRow row2 = sheet.CreateRow(2);//第三行 for (int j = 0; j < arrRow2.Length; j++) { row2.CreateCell(j).SetCellValue(arrRow2[j]); row2.GetCell(j).CellStyle = nopi.SetCellStyle(workbook, 10); } //开始合并单元格--跨行合并 nopi.MergedRegion(sheet, 1, 2, 0, 0); nopi.MergedRegion(sheet, 1, 2, 1, 1); nopi.MergedRegion(sheet, 1, 2, 2, 2); nopi.MergedRegion(sheet, 1, 2, 3, 3); nopi.MergedRegion(sheet, 1, 2, 4, 4); nopi.MergedRegion(sheet, 1, 2, 5, 5); nopi.MergedRegion(sheet, 1, 2, 6, 6); nopi.MergedRegion(sheet, 1, 2, 7, 7); nopi.MergedRegion(sheet, 1, 2, 8, 8); nopi.MergedRegion(sheet, 1, 2, 9, 9); nopi.MergedRegion(sheet, 1, 2, 10, 10); nopi.MergedRegion(sheet, 1, 2, 11, 11); nopi.MergedRegion(sheet, 1, 2, 18, 18); nopi.MergedRegion(sheet, 1, 2, 19, 19); nopi.MergedRegion(sheet, 1, 2, 20, 20); //跨列合并 nopi.MergedRegion(sheet, 1, 1, 12, 13); nopi.MergedRegion(sheet, 1, 1, 14, 15); nopi.MergedRegion(sheet, 1, 1, 16, 17); } #endregion 排列表头 #region 处理列值 { string[] arrColumn = new string[] { "TA032_Type", "TA032_dateTime", "EC001_SSQXMC", "EC101_WRYMC", "TA032_WSCLX", "TA032_SJSCNL", "TA032_ZWSSGY", "TA032_RunDate", "TA032_ProductType", "TA032_ProductNum", "TA032_FSPFL", "TA032_SFNG", "TA032_NGHCSMC", "TA032_CODJPSSQND", "TA032_CODJPSSHND", "TA032_NH3JPSSQND", "TA032_NH3JPSSHND", "TA032_SFYZK", "TA032_SFYZX", "TA032_remark" }; for (int j = 0; j < dt.Rows.Count; j++)//循环行 { IRow rowColumn = sheet.CreateRow(j + 3); rowColumn.CreateCell(0).SetCellValue(j + 1);//序号 rowColumn.GetCell(0).CellStyle = nopi.SetCellStyle(workbook, 10); for (int i = 1; i < arrColumn.Length - 1; i++) { //处理前两列(除去序号列) if (i == 1) { string time = dt.Rows[j]["TA032_dateTime"].ToString(); //存储的数据类型:0=年数据;1=月数据;2=季数据,3=半年数据 if (dt.Rows[j]["TA032_Type"].ToString() == "0") { rowColumn.CreateCell(1).SetCellValue("年数据"); rowColumn.CreateCell(2).SetCellValue(time.Substring(0, 4) + "年"); } else if (dt.Rows[j]["TA032_Type"].ToString() == "1") { rowColumn.CreateCell(1).SetCellValue("月数据"); rowColumn.CreateCell(2).SetCellValue(time.Substring(0, 4) + "年" + time.Substring(4, 2) + "月"); } else if (dt.Rows[j]["TA032_Type"].ToString() == "2") { string season = ""; rowColumn.CreateCell(1).SetCellValue("季度数据"); if (time.Substring(4, 2) == "21") season = "一季度"; else if (time.Substring(4, 2) == "22") season = "二季度"; else if (time.Substring(4, 2) == "23") season = "三季度"; else season = "四季度"; rowColumn.CreateCell(2).SetCellValue(time.Substring(0, 4) + "年" + season); } else if (dt.Rows[j]["TA032_Type"].ToString() == "3") { string halfYear = "下半年"; rowColumn.CreateCell(1).SetCellValue("半年数据"); if (time.Substring(4, 3) == "306") halfYear = "上半年"; rowColumn.CreateCell(2).SetCellValue(time.Substring(0, 4) + "年" + halfYear); } rowColumn.GetCell(1).CellStyle = nopi.SetCellStyle(workbook, 10); rowColumn.GetCell(2).CellStyle = nopi.SetCellStyle(workbook, 10); } //从第三列往后 0 1 2 3 4 switch (dt.Columns[arrColumn[i + 1]].DataType.ToString()) { case "System.String"://字符串类型 rowColumn.CreateCell(i + 2).SetCellValue(dt.Rows[j][arrColumn[i + 1]].ToString()); break; case "System.DateTime"://日期类型 DateTime dtime = DateTime.Parse(dt.Rows[j][arrColumn[i + 1]].ToString()); rowColumn.CreateCell(i + 2).SetCellValue(dtime.ToString("yyyy年MM月")); break; case "System.Boolean"://布尔型 bool boolValue = false; bool.TryParse(dt.Rows[j][arrColumn[i + 1]].ToString(), out boolValue); rowColumn.CreateCell(i + 2).SetCellValue(boolValue); break; case "System.Int16"://整型 case "System.Int32": case "System.Int64": case "System.Byte": int intValue = 0; int.TryParse(dt.Rows[j][arrColumn[i + 1]].ToString(), out intValue); rowColumn.CreateCell(i + 2).SetCellValue(intValue); break; case "System.Decimal"://浮点型 case "System.Double": double doubValue = 0; double.TryParse(dt.Rows[j][arrColumn[i + 1]].ToString(), out doubValue); rowColumn.CreateCell(i + 2).SetCellValue(doubValue); break; case "System.DBNull"://空值处理 rowColumn.CreateCell(i + 2).SetCellValue(""); break; default: rowColumn.CreateCell(i + 2).SetCellValue(""); break; } rowColumn.GetCell(i + 2).CellStyle = nopi.SetCellStyle(workbook, 10); } } } #endregion //自动设置列宽 AutoSizeColumns(sheet); workbook.Write(ms); ms.Flush(); ms.Position = 0; return ms; } #endregion NPOI导出
//***************************************************************************************************************************
//注释:排列表头中每个数组代表excel中的每一行,数组中的""作用是合并单元格,否则合并单元格后表头会很乱。
处理列值 即根据数据源dataset 和要导出的excel表头排列column,这要就不用循环去定位excel列对应dataset里的那个列
//***************************************************************************************************************************
#region 通用方法(单行or复杂表头)
/// <summary>
/// 合并单元格
/// </summary>
/// <param name="sheet">要合并单元格所在的sheet</param>
/// <param name="rowstart">开始行的索引</param>
/// <param name="rowend">结束行的索引</param>
/// <param name="colstart">开始列的索引</param>
/// <param name="colend">结束列的索引</param>
public void MergedRegion(HSSFSheet sheet, int rowstart, int rowend, int colstart, int colend)
{
CellRangeAddress cellRangeAddress = new CellRangeAddress(rowstart, rowend, colstart, colend);
sheet.AddMergedRegion(cellRangeAddress);
sheet.SetEnclosedBorderOfRegion(cellRangeAddress, NPOI.SS.UserModel.BorderStyle.THIN, HSSFColor.BLACK.index);//需要设置边框颜色,否则左侧没有 added by sean 2014-07-28
}
/// <summary>
/// 设置单元格样式
/// </summary>
/// <param name="workbook">工作簿</param>
/// <param name="fontSize">字体大小</param>
/// <returns>样式</returns>
public ICellStyle SetCellStyle(HSSFWorkbook workbook, short fontSize)
{
ICellStyle style = workbook.CreateCellStyle();
style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER;//居中
style.VerticalAlignment = VerticalAlignment.CENTER;//垂直居中
style.WrapText = true;//自动换行
//设置字体格式
IFont font = workbook.CreateFont();
font.FontName = "宋体";//字体
font.FontHeightInPoints = fontSize;//字号
//font1.Color = HSSFColor.RED.index;//颜色
font.Boldweight = 700;//粗体
//font.IsItalic = true;//斜体
//font.Underline = (byte)FontUnderlineType.DOUBLE;//添加双下划线
style.SetFont(font);
//单元格边框
style.BorderBottom = NPOI.SS.UserModel.BorderStyle.THIN;
style.BorderLeft = NPOI.SS.UserModel.BorderStyle.THIN;
style.BorderRight = NPOI.SS.UserModel.BorderStyle.THIN;
style.BorderTop = NPOI.SS.UserModel.BorderStyle.THIN;
return style;
}
/// <summary>
/// excel文件右键属性
/// </summary>
/// <param name="workbook"></param>
public void SetFileAttribute(HSSFWorkbook workbook)
{
DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company = "Golden3C";
workbook.DocumentSummaryInformation = dsi;
SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
si.Author = "hbj"; //填加xls文件作者信息
si.CreateDateTime = DateTime.Now;
workbook.SummaryInformation = si;
}
/// <summary>
/// 自动设置Excel列宽
/// </summary>
/// <param name="sheet">Excel表</param>
public void AutoSizeColumns(HSSFSheet sheet)
{
if (sheet.PhysicalNumberOfRows > 0)
{
IRow headerRow = sheet.GetRow(sheet.PhysicalNumberOfRows - 1);//获取最后一行,因为列是根据最后一行来排
for (int j = 0; j < headerRow.Cells.Count; j++)
{
sheet.AutoSizeColumn(j);
}
}
}
#endregion