做项目的时候参考网上的资源结合现有的项目写的方法,实现不同类型的内容置为对应的格式,内容为数字则单元格数值格式,识别为日期格式则单元格格式也是日期。
实际项目中写了一个判断,如果列名带有【号】、【码】字样的则即便是纯数字也保存为文本。例如银行账号、产品编码等是纯数字但并不应该是数字格式的。
重点为单元格样式以及单元格内的文本格式等都用到了:ICellStyle ,
实例一个CellStyle写法为: ICellStyle cellStyle1 = workbook.CreateCellStyle();
使用newCell.CellStyle = cellstyle;将一个单元格设置为对应的样式,注意ICellStyle的实例在一张表中不能超过4000个,所以切记不要将CellStyle的实例写在数据填充的for循环里哦。下面的代码里的样式使用主要是每个单元格加边框,以及日期格式的固定为yyyy-mm-dd。
下载NPOI的DLL文件:点击下载
类头引用:
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Web;
using NPOI;
using NPOI.HPSF;
using NPOI.HSSF;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.POIFS;
using NPOI.Util;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF;
using NPOI.XSSF.UserModel;
using NPOI.XSSF.Util;
using System.Linq;
using NPOI.SS.Formula.Functions;
方法代码:
/// <summary>
/// DataTable导出到Excel的MemoryStream
/// </summary>
/// <param name="dtSource">源DataTable</param>
/// <param name="strHeaderText">表头文本</param>
/// <param name="templateFile">模板文件</param>
/// <param name="fileName">导出的文件名</param>
public static MemoryStream ExportToMemoryStream(DataTable dtSource, string strHeaderText, string templateFile = "", string fileName = "")
{
IWorkbook workbook = null;
ISheet sheet = null;
bool isTemplateFile = false;//是否采用模板文件导出
int rowIndex = 0;
bool isExcel2007 = false;
if (!templateFile.IsNullOrEmpty() && File.Exists(templateFile))
{
string templateFilePath = templateFile;
isExcel2007 = templateFilePath.EndsWith("xlsx", StringComparison.CurrentCultureIgnoreCase);
using (FileStream file = new FileStream(templateFilePath, FileMode.Open, FileAccess.Read))
{
if (isExcel2007)
{
workbook = new XSSFWorkbook(file);
}
else
{
workbook = new HSSFWorkbook(file);
}
}
if (workbook != null)
{
sheet = workbook.GetSheetAt(0);
if (sheet != null)
{
isTemplateFile = true;
rowIndex = sheet.LastRowNum + 1;
}
}
}
else
{
isExcel2007 = fileName.EndsWith("xlsx", StringComparison.CurrentCultureIgnoreCase);
}
if (workbook == null)
{
if (isExcel2007)
{
workbook = new XSSFWorkbook();
}
else
{
workbook = new HSSFWorkbook();
}
}
if (sheet == null)
{
sheet = workbook.CreateSheet("Sheet1");
}
int[] arrColWidth = new int[] { };
string[] arrColDataType = new string[] { };
if (!isTemplateFile)
{
//取得列宽
arrColWidth = new int[dtSource.Columns.Count];
arrColDataType = new string[dtSource.Columns.Count];
foreach (DataColumn item in dtSource.Columns)
{
if (item.Caption.IsInt())
{
arrColWidth[item.Ordinal] = item.Caption.ToInt();
}
else
{
arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
}
arrColDataType[item.Ordinal] = item.DataType.ToString();
}
if (dtSource.Rows.Count > 0)
{
for (int j = 0; j < dtSource.Columns.Count; j++) { if (!dtSource.Columns[j].Caption.IsInt()) { int intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[0][j].ToString()).Length; if (intTemp > arrColWidth[j])
{
arrColWidth[j] = intTemp;
}
}
}
}
}
bool hasHeader = !strHeaderText.IsNullOrEmpty();//是否有表头
if (!isTemplateFile)
{
#region 新建表,填充表头,填充列头,样式
if (rowIndex == 65535 || rowIndex == 0)
{
#region 表头及样式
if (hasHeader)
{
IRow headerRow = sheet.CreateRow(0);
headerRow.HeightInPoints = 25;
headerRow.CreateCell(0).SetCellValue(strHeaderText);
ICellStyle headStyle = workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
IFont font = workbook.CreateFont();
font.FontHeightInPoints = 20;
font.Boldweight = 700;
headStyle.SetFont(font);
headStyle.BorderLeft = BorderStyle.Thin;
headStyle.BorderRight = BorderStyle.Thin;
headStyle.BorderTop = BorderStyle.Thin;
headStyle.BorderBottom = BorderStyle.Thin;
headerRow.GetCell(0).CellStyle = headStyle;
sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1));
}
#endregion
#region 列头及样式
{
IRow headerRow = sheet.CreateRow(hasHeader ? 1 : 0);
ICellStyle headStyle = workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
IFont font = workbook.CreateFont();
font.FontHeightInPoints = 10;
font.Boldweight = 700;
headStyle.BorderLeft = BorderStyle.Thin;
headStyle.BorderRight = BorderStyle.Thin;
headStyle.BorderTop = BorderStyle.Thin;
headStyle.BorderBottom = BorderStyle.Thin;
headStyle.IsLocked = true;
headStyle.SetFont(font);
ICellStyle cellStyle = workbook.CreateCellStyle();
foreach (DataColumn column in dtSource.Columns)
{
headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
//设置列宽
if (arrColWidth.Length > 0)
{
sheet.SetColumnWidth(column.Ordinal, Math.Min(arrColWidth[column.Ordinal] + 1, 200) * 256);
}
}
//sheet.CreateFreezePane(0, hasHeader ? 2 : 1, 0, dtSource.Columns.Count - 1);
}
#endregion
rowIndex = hasHeader ? 2 : 1;
}
#endregion
}
int columnsCount = dtSource.Columns.Count;
ICellStyle cellStyle1 = workbook.CreateCellStyle();
cellStyle1.BorderLeft = BorderStyle.Thin;
cellStyle1.BorderRight = BorderStyle.Thin;
cellStyle1.BorderTop = BorderStyle.Thin;
cellStyle1.BorderBottom = BorderStyle.Thin;
//日期格式的单元格格式
ICellStyle csDateFormat = workbook.CreateCellStyle();
csDateFormat.BorderLeft = BorderStyle.Thin;
csDateFormat.BorderRight = BorderStyle.Thin;
csDateFormat.BorderTop = BorderStyle.Thin;
csDateFormat.BorderBottom = BorderStyle.Thin;
IDataFormat dfDate = workbook.CreateDataFormat();
csDateFormat.DataFormat = dfDate.GetFormat("yyyy-mm-dd");
foreach (DataRow row in dtSource.Rows)
{
#region 填充内容
IRow dataRow = sheet.CreateRow(rowIndex);
for (int i = 0; i < columnsCount; i++) { ICell newCell = dataRow.CreateCell(i); //IDataFormat format = workbook.CreateDataFormat(); //cellStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); newCell.CellStyle = cellStyle1; string drValue = row[i].ToString(); //因列都是字符串型的,所以循环Parse来确认列的对应数据格式。 DateTime dateV; double doubV = 0; //大于8字节的才被认为符合日期格式(2000-1-1),防止-1也被认为是日期 if (drValue.Length >= 8 && DateTime.TryParse(drValue, out dateV))
{
newCell.CellStyle = csDateFormat;
if (dateV == Convert.ToDateTime(null))
newCell.SetCellValue("");
else
newCell.SetCellValue(dateV);
}
else if (double.TryParse(drValue, out doubV))
{
//如果标题含有号、码字样,即使是全数字也显示文本
if ((dtSource.Columns[i] + "").IndexOf("号") >= 0 || (dtSource.Columns[i] + "").IndexOf("码") >= 0)
{
newCell.SetCellValue(drValue);
}
else
{
newCell.SetCellValue(doubV);
}
}
else
{
newCell.SetCellValue(drValue);
}
}
#endregion
rowIndex++;
}
using (MemoryStream ms = new MemoryStream())
{
workbook.Write(ms);
ms.Flush();
//ms.Position = 0;
workbook = null;
sheet = null;
return ms;
}
}