一、概述
NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目, 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。
1、操作Excel的类库:
- NPOI: V2.5.1 快速生成 https://github.com/tonyqus/npoi
- MyXls: (已停止)
- Aspose.Cell.dll: 收费
- EPPlus 5: https://github.com/EPPlusSoftware/
- Spire.XLS: 收费
2、引用DLL
使用时需引用需要引用所有5个dll
- ICSharpCode.SharpZipLib.dll
- NPOI.dll
- NPOI.OOXML.dll
- NPOI.OpenXml4Net.dll
- NPOI.OpenXmlFormats.dll
程序集构成
二、通过NPOI,将Excel文件导到数据表DataTable
DataTable dt = ImportToTable("00.xls");
if (dt != null)
{
Console.Write(dt.Rows.Count);
Console.ReadKey();
}
public static DataTable ImportToTable(string fileName)
{
DataTable dt = new DataTable();
IWorkbook workbook;
string fileExt = Path.GetExtension(fileName).ToLower();
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
//XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式
if (fileExt == ".xlsx")
{
workbook = new XSSFWorkbook(fs);
}
else if (fileExt == ".xls")
{
workbook = new HSSFWorkbook(fs);
}
else
{
workbook = null;
return null;
}
ISheet sheet = workbook.GetSheetAt(0);//Sheet总数量:workbook.NumberOfSheets
//表头
IRow header = sheet.GetRow(sheet.FirstRowNum);
for (int i = 0; i < header.LastCellNum; i++)
{
object obj = GetValueType(header.GetCell(i));
if (obj == null || obj.ToString() == string.Empty)
{
dt.Columns.Add(new DataColumn("Columns" + i.ToString()));
}
else
dt.Columns.Add(new DataColumn(obj.ToString()));
}
//数据
for (int i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++)
{
DataRow dr = dt.NewRow();
bool hasValue = false;
IRow row = sheet.GetRow(i);
for (int j = row.FirstCellNum; j < row.LastCellNum; j++)
{
dr[j] = GetValueType(sheet.GetRow(i).GetCell(j));
if (dr[j] != null && dr[j].ToString() != string.Empty)
{
hasValue = true;
}
}
if (hasValue)
{
dt.Rows.Add(dr);
}
}
return dt;
}
}
///
/// 获取单元格类型
///
///
///
///
static object GetValueType(ICell cell)
{
if (cell == null)
return null;
switch (cell.CellType)
{
case CellType.Blank: //BLANK:
return null;
case CellType.Boolean: //BOOLEAN:
return cell.BooleanCellValue;
case CellType.Numeric: //NUMERIC:
return cell.NumericCellValue;
case CellType.String: //STRING:
return cell.StringCellValue;
case CellType.Error: //ERROR:
return cell.ErrorCellValue;
case CellType.Formula: //FORMULA:
default:
return "=" + cell.CellFormula;
}
}
四、常见用法:
1、查找
IEnumerator rows = sheet.GetEnumerator();
while (rows.MoveNext())
{
IRow row = (HSSFRow)rows.Current;
ICell cell = row.GetCell(0);
if (cell != null && cell.StringCellValue == "XX")
{
return row.GetCell(1).StringCellValue;
}
}
2、插入图片
IWorkbook workbook = new HSSFWorkbook();
//add picture data to this workbook.
byte[] bytes = System.IO.File.ReadAllBytes(@"00.jpg");
int pictureIdx = workbook.AddPicture(bytes, PictureType.JPEG);
//create sheet
ISheet sheet = workbook.CreateSheet("Sheet1");
// Create the drawing patriarch. This is the top level container for all shapes.
IDrawing patriarch = sheet.CreateDrawingPatriarch();
//add a picture
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 0, 0, 0, 1, 3);
IPicture pict = patriarch.CreatePicture(anchor, pictureIdx);
//保存为Excel文件
using (FileStream fs = new FileStream("00_new.xls", FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}
五、填充Excel模板
IWorkbook workbook;
using (FileStream fs = new FileStream("模板文件.xls", FileMode.Open, FileAccess.Read))
{
workbook = new HSSFWorkbook(fs);
}
ISheet cloneSheet = workbook.CloneSheet(workbook.GetSheetIndex("Sheet1"));//复制第一个模板Sheet
cloneSheet.ForceFormulaRecalculation = true;
workbook.SetSheetName(workbook.GetSheetIndex(cloneSheet), "SheetClone");//设置新SheetName
cloneSheet.GetRow(4).GetCell(1).SetCellValue("a");//为已经存在的单元格赋值
IRow row = cloneSheet.GetRow(15);
if (row == null)
row = cloneSheet.CreateRow(15);
ICell cell = row.GetCell(7);
if (cell == null)
cell = row.CreateCell(7);
cell.SetCellValue("XX");// 为不存在的单元格,先新建再赋值
cloneSheet.ShiftRows(51, 60, 34);//51-60行(尾部)整体移动34行,腾出更多控件插入多行数据
workbook.RemoveSheetAt(workbook.GetSheetIndex("Sheet1"));//移除原模板Sheet
FileStream fs_new = new FileStream(DateTime.Now.Ticks + ".xls", FileMode.Create);
workbook.Write(fs_new);
fs_new.Close();
六、DataTable导出到Excel文件
1、直接导出到Excel:
调用方式:
ExportToExcel(dt, "00_new.xls");
代码
public static void ExportToExcel(DataTable dt, string fileName)
{
IWorkbook workbook;
string fileExt = Path.GetExtension(fileName).ToLower();
//XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式
if (fileExt == ".xlsx")
{
workbook = new XSSFWorkbook();
}
else if (fileExt == ".xls")
{
workbook = new HSSFWorkbook();
}
else
{
workbook = null;
return;
}
ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(dt.TableName);
//表头
IRow row = sheet.CreateRow(0);
for (int i = 0; i < dt.Columns.Count; i++)
{
ICell cell = row.CreateCell(i);
cell.SetCellValue(dt.Columns[i].ColumnName);
}
//数据
for (int i = 0; i < dt.Rows.Count; i++)
{
IRow row1 = sheet.CreateRow(i + 1);
for (int j = 0; j < dt.Columns.Count; j++)
{
ICell cell = row1.CreateCell(j);
cell.SetCellValue(dt.Rows[i][j].ToString());
}
}
//保存为Excel文件
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}
}
2、将DataTable导出到Excel:先导出到MemoryStream
public static MemoryStream ExportToExcel(DataTable dt, string HeaderText)
{
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();//超过65535行,则新建一个Sheet
}
#region 表头及样式
{
var headerRow = sheet.CreateRow(0);
headerRow.HeightInPoints = 25;
headerRow.CreateCell(0).SetCellValue(HeaderText);
//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));//合并区域
}
#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);
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
rowIndex = 2;//数据行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("");//设置单元格公式:newCell.SetCellFormula("SUM($B0:$D0)")
break;
}
}
#endregion
rowIndex++;
}
//自动列宽
for (int i = 0; i <= dt.Columns.Count; i++)
sheet.AutoSizeColumn(i, true);
using (MemoryStream ms = new MemoryStream())
{
workbook.Write(ms);
ms.Flush();
ms.Position = 0;
return ms;
}
}
3、应用
1、Web导出
public static void ExportToExcelByWeb(DataTable dt, string HeaderText, string FileName)
{
HttpContext context = HttpContext.Current;
context.Response.ContentType = "application/vnd.ms-excel";
context.Response.ContentEncoding = Encoding.UTF8;
context.Response.Charset = "UTF-8";
context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", HttpUtility.UrlEncode(FileName, Encoding.UTF8)));
byte[] data = ExportToExcel(dt, HeaderText).GetBuffer();//Read()方法也可以
context.Response.BinaryWrite(data);// 或者: context.Response.OutputStream.Write(data,0,data.Length)
context.Response.End();
}
2、Winform导出
public static void ExportToExcel(DataTable dt, string HeaderText, string FileName)
{
using (MemoryStream ms = ExportToExcel(dt, HeaderText))
{
using (FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write))
{
byte[] data = ms.ToArray();//跟GetBuffer()对比,速度稍慢,但无空数据
fs.Write(data, 0, data.Length);
fs.Flush();
}
}
}
GridView导出到Excel
Web中的GridView可直接导出到Excel:renderControl()
到此这篇关于C#使用NPOI导入导出Excel的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。