.NET NPOI导出Excel详解
NPOI,顾名思义,就是POI的.NET版本。那POI又是什么呢?POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office的文件。
支持的文件格式包括xls, doc, ppt等。
官方网站:http://npoi.codeplex.com/
nuget直接获取使用
一、NPOI生成Excel
//创建工作薄
var workbook =
new HSSFWorkbook();
//创建表
var table = workbook.CreateSheet(
"joye.net");
//模拟20行20列数据
for (
var i =
0; i <
20; i++
)
{
var row =
table.CreateRow(i);
for (
int j =
0; j <
20; j++
)
{
var cell =
row.CreateCell(j);
cell.SetCellValue(j);
}
}
//打开xls文件,如没有则创建,如存在则在创建是不要打开该文件
using (
var fs = File.OpenWrite(
@"c:/joye.net.xls"))
{
workbook.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
Console.WriteLine(
"生成成功");
}
二、NPOI读取Excel
using (
var fs = File.OpenRead(
@"c:/joye.net.xls"))
{
//把xls文件中的数据写入workbook1中
var workbook1 =
new HSSFWorkbook(fs);
for (
var i =
0; i < workbook1.NumberOfSheets; i++
)
{
var sheet =
workbook1.GetSheetAt(i);
for (
var j =
0; j <= sheet.LastRowNum; j++
)
{
//读取当前行数据
var row =
sheet.GetRow(j);
if (row !=
null)
{
for (
var k =
0; k <= row.LastCellNum; k++
)
{ //当前表格
var cell =
row.GetCell(k);
if (cell !=
null)
{
Console.Write(cell.ToString() +
" ");
}
}
}
Console.WriteLine();
}
}
}
读出的结果
三、简单学习
/// <summary>
/// 组装workbook.
/// </summary>
/// <param name="dt">dataTable资源</param>
/// <param name="columnHeader">表头</param>
/// <returns></returns>
public static HSSFWorkbook BuildWorkbook1(DataTable dt,
string columnHeader =
"")
{
var workbook =
new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet(
string.IsNullOrWhiteSpace(dt.TableName) ?
"Sheet1" : dt.TableName);
#region 文件属性信息
{
var dsi =
PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company =
"NPOI";
workbook.DocumentSummaryInformation =
dsi;
SummaryInformation si =
PropertySetFactory.CreateSummaryInformation();
si.Author =
"文件作者信息";
si.ApplicationName =
"创建程序信息";
si.LastAuthor =
"最后保存者信息";
si.Comments =
"作者信息";
si.Title =
"标题信息";
si.Subject =
"主题信息";
si.CreateDateTime =
DateTime.Now;
workbook.SummaryInformation =
si;
}
#endregion
var dateStyle =
workbook.CreateCellStyle();
var format =
workbook.CreateDataFormat();
dateStyle.DataFormat = format.GetFormat(
"yyyy-mm-dd");
//取得列宽
var arrColWidth =
new int[dt.Columns.Count];
foreach (DataColumn item
in dt.Columns)
{
arrColWidth[item.Ordinal] = Encoding.GetEncoding(
936).GetBytes(item.ColumnName.ToString()).Length;
}
for (
var i =
0; i < dt.Rows.Count; i++
)
{
for (
var j =
0; j < dt.Columns.Count; j++
)
{
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 表头及样式
{
var headerRow = sheet.CreateRow(
0);
headerRow.HeightInPoints =
25;
headerRow.CreateCell(0).SetCellValue(columnHeader);
//CellStyle
ICellStyle headStyle =
workbook.CreateCellStyle();
headStyle.Alignment = 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 CellRangeAddress(
0,
0,
0, dt.Columns.Count -
1));
}
#endregion
#region 列头及样式
{
var headerRow = sheet.CreateRow(
1);
//CellStyle
ICellStyle headStyle =
workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
// 左右居中
headStyle.VerticalAlignment = VerticalAlignment.Center;
// 上下居中
//定义font
IFont font =
workbook.CreateFont();
font.FontHeightInPoints =
10;
font.Boldweight =
700;
headStyle.SetFont(font);
foreach (DataColumn column
in dt.Columns)
{
headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
headerRow.GetCell(column.Ordinal).CellStyle =
headStyle;
sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] +
1) *
256);
}
}
#endregion
if (columnHeader !=
"")
{
//header row
IRow row0 = sheet.CreateRow(
0);
for (
int i =
0; i < dt.Columns.Count; i++
)
{
ICell cell =
row0.CreateCell(i, CellType.String);
cell.SetCellValue(dt.Columns[i].ColumnName);
}
}
rowIndex =
2;
}
#endregion
#region 内容
var dataRow =
sheet.CreateRow(rowIndex);
foreach (DataColumn column
in dt.Columns)
{
var 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++
;
}
//自动列宽
for (
int i =
0; i <= dt.Columns.Count; i++
)
sheet.AutoSizeColumn(i, true);
return workbook;
}
var dt =
new DataTable();
//模拟20行20列数据
for (
var i =
0; i <
3; i++
)
{
dt.Columns.Add(i.ToString());
}
for (
var j =
0; j <
65537; j++
)
{
dt.Rows.Add(new object[] {
0 ,
1,
2 });
}
var newBook =
BuildWorkbook(dt);
using (
var fs = File.OpenWrite(
@"c:/joye.net1.xls"))
{
newBook.Write(fs);
Console.WriteLine("生成成功");
}
四、NPOI导出Excel 65536问题
public static HSSFWorkbook BuildWorkbook(DataTable dt)
{
var book =
new HSSFWorkbook();
ISheet sheet = book.CreateSheet(
"Sheet1");
//Data Rows
for (
int i =
0; i < dt.Rows.Count; i++
)
{
IRow drow =
sheet.CreateRow(i);
for (
int j =
0; j < dt.Columns.Count; j++
)
{
ICell cell =
drow.CreateCell(j, CellType.String);
cell.SetCellValue(dt.Rows[i][j].ToString());
}
}
//自动列宽
for (
int i =
0; i <= dt.Columns.Count; i++
)
sheet.AutoSizeColumn(i, true);
return book;
}
NPOI导出Excel超过65536会报异常,原来是由于NPOI这个动态库导致的,然后看了下版本,发现是1.2.5。然后百度了下,发现这个版本的NPOI只支持office2003,二office2003最多支持65536行
解决方式:
1、只是在插入数据的时候,加个判断,如果数据条数大于65536时,就在创建一个sheet
//65536判断处理
public static HSSFWorkbook BuildWorkbook(DataTable dt)
{
var book =
new HSSFWorkbook();
ISheet sheet1 = book.CreateSheet(
"Sheet1");
ISheet sheet2 = book.CreateSheet(
"Sheet2");
//填充数据
for (
int i =
0; i < dt.Rows.Count; i++
)
{
if (i <
65536)
{
IRow drow =
sheet1.CreateRow(i);
for (
int j =
0; j < dt.Columns.Count; j++
)
{
ICell cell =
drow.CreateCell(j, CellType.String);
cell.SetCellValue(dt.Rows[i][j].ToString());
}
}
if (i >=
65536)
{
IRow drow = sheet2.CreateRow(i -
65536);
for (
int j =
0; j < dt.Columns.Count; j++
)
{
ICell cell =
drow.CreateCell(j, CellType.String);
cell.SetCellValue(dt.Rows[i][j].ToString());
}
}
}
//自动列宽
for (
int i =
0; i <= dt.Columns.Count; i++
)
{
sheet1.AutoSizeColumn(i, true);
sheet2.AutoSizeColumn(i, true);
}
return book;
}
2、考虑使用高版本Office,使用用对象支持高版本的NPOI
//高版本
public static XSSFWorkbook BuildWorkbook(DataTable dt)
{
var book =
new XSSFWorkbook();
ISheet sheet = book.CreateSheet(
"Sheet1");
//Data Rows
for (
int i =
0; i < dt.Rows.Count; i++
)
{
IRow drow =
sheet.CreateRow(i);
for (
int j =
0; j < dt.Columns.Count; j++
)
{
ICell cell =
drow.CreateCell(j, CellType.String);
cell.SetCellValue(dt.Rows[i][j].ToString());
}
}
//自动列宽
for (
int i =
0; i <= dt.Columns.Count; i++
)
sheet.AutoSizeColumn(i, true);
return book;
}
五、web开发中导出Excel
public static void ExportExcel(DataTable dt,
string fileName =
"")
{
//生成Excel
IWorkbook book =
BuildWorkbook(dt);
//web 下载
if (fileName ==
"")
fileName =
string.Format(
"{0:yyyyMMddHHmmssffff}", DateTime.Now);
fileName =
fileName.Trim();
string ext =
Path.GetExtension(fileName);
if (ext.ToLower() ==
".xls" || ext.ToLower() ==
".xlsx")
fileName = fileName.Replace(ext,
string.Empty);
HttpResponse httpResponse =
HttpContext.Current.Response;
httpResponse.Clear();
httpResponse.Buffer =
true;
httpResponse.Charset =
Encoding.UTF8.BodyName;
httpResponse.AppendHeader("Content-Disposition",
"attachment;filename=" + fileName +
".xls");
httpResponse.ContentEncoding =
Encoding.UTF8;
httpResponse.ContentType =
"application/vnd.ms-excel; charset=UTF-8";
book.Write(httpResponse.OutputStream);
httpResponse.End();
}