目录
引言
Excel文件作为数据处理的重要工具,广泛应用于各种场景。然而,在没有安装Microsoft Office的环境下,如何高效地操作Excel文件成为了一个挑战。NPOI库的出现,为我们提供了一个强大的解决方案。本文将详细介绍NPOI库的基本使用方法和高级特性,帮助读者轻松操作Excel文件。
一、NPOI概述
NPOI是一个开源的.NET库,它允许开发者在无需安装Microsoft Office的情况下读写Excel文件。NPOI构建在Apache POI项目之上,并提供了丰富的API来操作Excel文件。NPOI支持xls(Excel 97-2003)和xlsx(Excel 2007及更高版本)两种文件格式,并且兼容大部分Excel的特性,如单元格样式、数据格式、公式等。
与其他类似库相比,NPOI具有以下优势:
- 无需安装Office:NPOI不依赖于Microsoft Office,可以在没有Office的环境下运行。
- 支持多种文件格式:除了xls和xlsx外,NPOI还支持docx文件格式的读写。
- 丰富的Excel特性支持:NPOI包含了大部分Excel的特性,如单元格样式、数据格式、公式等。
二、NPOI的主要用途
- Excel文件的读写:NPOI允许开发者在不需要安装Microsoft Office的情况下,对Excel文件进行读写操作。这对于需要在没有Office环境的服务器上进行数据处理的应用非常有用。
- 支持多种文件格式:除了Excel文件(xls、xlsx)外,NPOI还支持Word文件(docx)的读写。
- 丰富的Excel特性支持:NPOI包含了大部分Excel的特性,如单元格样式、数据格式、公式等,使得开发者能够更灵活地操作Excel文件。
三、安装NPOI库
安装NPOI库非常简单,只需要通过NuGet包管理器即可。在Visual Studio中,右键点击项目 -> 选择"管理NuGet程序包" -> 在"浏览"选项卡中搜索"NPOI" -> 点击"安装"按钮即可。
四、NPOI基本使用
- 文件内容示例
- 代码示例
cs
/// <summary>
/// 简单读取文件内容
/// </summary>
static void SimpleRead()
{
//文件路径
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "01.xlsx");
//判断文件路径,存在则继续
if (File.Exists(filePath))
{
//文件流
FileStream fs = null;
//Excel工作簿操作对象
IWorkbook workbook = null;
//开启异常捕捉
try
{
StringBuilder sb = new StringBuilder();
//定义文件流打开
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//定义工作簿
workbook = new XSSFWorkbook(fs);
//读取工作表数量
var numberOfSheets = workbook.NumberOfSheets;
//判断工作表数量,大于零则继续
if (numberOfSheets > 0)
{
//获取第一个工作表
var sheet0 = workbook.GetSheetAt(0);
sb.AppendLine($"工作表名称:{sheet0.SheetName}");
sb.AppendLine($"行数量:{sheet0.LastRowNum + 1}");
if (sheet0.LastRowNum >= 0)
{
//读取每一行信息
for (int i = 0; i <= sheet0.LastRowNum; i++)
{
var row = sheet0.GetRow(i);
if (row != null)
{
sb.Append($"第{i + 1}行数据:");
//获取最后一列
var lastCellNum = row.LastCellNum;
for (int j = 0; j < lastCellNum; j++)
{
//获取单元格
var cell = row.GetCell(j);
object cellValue = null;
if (cell != null)
{
#region 根据不同单元格格式提取内容
switch (cell.CellType)
{
case CellType.Boolean: cellValue = cell.BooleanCellValue; break;
case CellType.Numeric: cellValue = cell.NumericCellValue; break;
case CellType.Formula:
var cachedCellType = cell.GetCachedFormulaResultTypeEnum();
switch (cachedCellType)
{
case CellType.Boolean: cellValue = cell.BooleanCellValue; break;
case CellType.Numeric: cellValue = cell.NumericCellValue; break;
default: cellValue = cell.StringCellValue; break;
}
break;
default: cellValue = cell.StringCellValue; break;
}
#endregion
}
sb.Append($"\t{cellValue}");
}
sb.AppendLine();
}
}
}
Console.WriteLine(sb.ToString());
}
//关闭相关资源
workbook.Close();
workbook = null;
//关闭相关资源
fs.Close();
fs = null;
}
catch (Exception ex)
{
//显示异常信息
Console.WriteLine($"发生异常:{ex.Message}");
}
finally
{
//关闭工作簿
if (workbook != null)
{
workbook.Close();
}
//关闭文件流
if (fs != null)
{
fs.Close();
}
}
}
}
- 运行结果
简单文件写入
代码示例
cs
/// <summary>
/// 简单写文件内容
/// </summary>
static void SimpleWrite()
{
//文件路径
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "02.xlsx");
//文件流
FileStream fs = null;
//Excel工作簿操作对象
IWorkbook workbook = null;
//开启异常捕捉
try
{
#region 判断或创建文件
var dir = Path.GetDirectoryName(filePath);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
if (!File.Exists(filePath))
{
using (FileStream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
using (var wb = new XSSFWorkbook())
{
wb.Write(stream);
wb.Close();
stream.Close();
}
}
#endregion
//定义工作簿
workbook = new XSSFWorkbook();
#region 预防性处理工作表
ISheet sheet = workbook.CreateSheet("数据");
#region 第一行,标题:时间,内容
var row1 = sheet.CreateRow(0);
row1.CreateCell(0).SetCellValue("时间");
row1.CreateCell(1).SetCellValue("内容");
#endregion
#region 增加几行数据
int rowIndex = 1;
for (int i = 0; i < 10; i++)
{
var row = sheet.CreateRow(rowIndex++);
row.CreateCell(0).SetCellValue(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
row.CreateCell(1).SetCellValue(Guid.NewGuid().ToString().ToUpper());
}
#endregion
//自适应
sheet.AutoSizeColumn(0);
sheet.AutoSizeColumn(1);
#endregion
#region 保存
using (fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}
#endregion
//关闭相关资源
workbook.Close();
workbook = null;
//关闭相关资源
fs.Close();
fs = null;
}
catch (Exception ex)
{
//显示异常信息
Console.WriteLine($"发生异常:{ex.Message}");
}
finally
{
//关闭工作簿
if (workbook != null)
{
workbook.Close();
}
//关闭文件流
if (fs != null)
{
fs.Close();
}
}
}
运行结果
定义单元格格式
代码示例
cs
/// <summary>
/// 11 加粗 格式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
static ICellStyle GetHeaderStyle(IWorkbook workbook)
{
var style = GetStyle(workbook, true);
style.FillPattern = FillPattern.SolidForeground;
style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
return style;
}
/// <summary>
/// 红色背景 格式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
static ICellStyle GetRedBackNormalStyle(IWorkbook workbook)
{
var style = GetStyle(workbook);
style.FillPattern = FillPattern.SolidForeground;
style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
return style;
}
/// <summary>
/// 红色字体 格式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
static ICellStyle GetRedNormalStyle(IWorkbook workbook)
{
IFont font = workbook.CreateFont();
font.Color = IndexedColors.Red.Index;
font.FontHeightInPoints = 11;
return GetStyle(workbook, font);
}
/// <summary>
/// 常规 格式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
static ICellStyle GetNormalStyle(IWorkbook workbook)
{
return GetStyle(workbook);
}
/// <summary>
/// 时间 格式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
static ICellStyle GetDateTimeStyle(IWorkbook workbook)
{
return GetStyle(workbook, false, 11, "yyyy-mm-dd hh:mm:ss");
}
/// <summary>
/// 数字 格式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
static ICellStyle GetIntStyle(IWorkbook workbook)
{
return GetStyle(workbook, false, 11, "0");
}
/// <summary>
/// 浮点数 格式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
static ICellStyle GetFloatStyle(IWorkbook workbook)
{
return GetStyle(workbook, false, 11, "0.00");
}
/// <summary>
/// 设定格式
/// </summary>
/// <param name="workbook">工作簿</param>
/// <param name="isBold">是否粗体,默认非粗体</param>
/// <param name="fontHeightInPoints">字高度(理解为字大小)</param>
/// <param name="dataFormat">自定义格式</param>
/// <param name="isWrapText">是否自动换行,默认是</param>
/// <returns></returns>
static ICellStyle GetStyle(IWorkbook workbook,
bool isBold = false,
double fontHeightInPoints = 11,
string dataFormat = "",
bool isWrapText = true)
{
IFont font = workbook.CreateFont();
font.IsBold = isBold;
font.FontHeightInPoints = fontHeightInPoints;
return GetStyle(workbook, font, dataFormat, isWrapText);
}
/// <summary>
/// 设定格式
/// </summary>
/// <param name="workbook">工作簿</param>
/// <param name="dataFormat">自定义格式</param>
/// <param name="isWrapText">是否自动换行,默认是</param>
/// <returns></returns>
static ICellStyle GetStyle(IWorkbook workbook,
IFont font,
string dataFormat = "",
bool isWrapText = true)
{
ICellStyle style = workbook.CreateCellStyle();
style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
style.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
style.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
style.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
style.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
if (!string.IsNullOrWhiteSpace(dataFormat))
{
style.DataFormat = HSSFDataFormat.GetBuiltinFormat(dataFormat);
if (style.DataFormat == -1) {
IDataFormat format = workbook.CreateDataFormat();
style.DataFormat = format.GetFormat(dataFormat);
}
}
style.SetFont(font);
style.WrapText = isWrapText;
return style;
}
日常使用1
- 代码示例
cs
/// <summary>
/// 日常应用
/// </summary>
static void CommonApplicaiton()
{
//文件路径
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "03.xlsx");
//文件流
FileStream fs = null;
//Excel工作簿操作对象
IWorkbook workbook = null;
//开启异常捕捉
try
{
#region 判断或创建文件
var dir = Path.GetDirectoryName(filePath);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
if (!File.Exists(filePath))
{
using (FileStream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
using (var wb = new XSSFWorkbook())
{
wb.Write(stream);
wb.Close();
stream.Close();
}
}
#endregion
//定义工作簿
workbook = new XSSFWorkbook();
//整数格式单元格样式
var intStyle = GetIntStyle(workbook);
//时间格式单元格样式
var dateTimeStyle = GetDateTimeStyle(workbook);
//普通单元格样式
var normalStyle = GetNormalStyle(workbook);
//标题样式
var headerStyle = GetHeaderStyle(workbook);
#region 创建工作表
ISheet sheet = workbook.CreateSheet("数据");
#region 第一行,标题:序号,时间,整数随机数
var row1 = sheet.CreateRow(0);
var orderCell = row1.CreateCell(0);
orderCell.CellStyle = headerStyle;
orderCell.SetCellValue("序号");
sheet.SetColumnWidth(0, 3 * 512);
var timeCell = row1.CreateCell(1);
timeCell.CellStyle = headerStyle;
timeCell.SetCellValue("时间");
sheet.SetColumnWidth(1, 10 * 512);
var randomCell = row1.CreateCell(2);
randomCell.CellStyle = headerStyle;
randomCell.SetCellValue("整数随机数");
sheet.SetColumnWidth(2, 10 * 512);
#endregion
#region 增加几行数据
Random random = new Random();
int rowIndex = 1;
for (int i = 0; i < 10; i++)
{
var row = sheet.CreateRow(rowIndex++);
//序号,直接用公式
var cell1 = row.CreateCell(0);
cell1.CellStyle = normalStyle;
cell1.CellFormula = "ROW()-1";
var cell2 = row.CreateCell(1);
cell2.SetCellValue(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
cell2.CellStyle = normalStyle;
var cell3 = row.CreateCell(2);
cell3.CellStyle = intStyle;
cell3.SetCellValue(random.Next());
}
#endregion
#endregion
#region 保存
using (fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}
#endregion
//关闭相关资源
workbook.Close();
workbook = null;
//关闭相关资源
fs.Close();
fs = null;
}
catch (Exception ex)
{
//显示异常信息
Console.WriteLine($"发生异常:{ex.Message}");
}
finally
{
//关闭工作簿
if (workbook != null)
{
workbook.Close();
}
//关闭文件流
if (fs != null)
{
fs.Close();
}
}
}
运行结果
五、高级特性应用
- 数据验证
NPOI支持在Excel单元格中设置数据验证规则,例如限制输入的数据类型、范围等。
- 条件格式化
使用NPOI可以创建条件格式化规则,根据单元格的值改变其外观(如颜色、字体等)。
- 图表
NPOI支持创建和编辑Excel图表,包括柱状图、折线图、饼图等。
六、性能优化和内存管理
- 使用流(Stream)来读写文件
使用FileStream
而不是将整个文件加载到内存中,以提高性能和减少内存使用。
- 及时释放资源
在操作完Excel文件后,确保释放所有相关的资源,如FileStream
、IWorkbook
等。
七、常见问题与解决方案
- 无法打开xlsx文件
确保已正确安装NPOI库,并且使用了正确的文件路径和文件名。
- 单元格样式不生效
检查是否已正确创建和应用了单元格样式。
八、结论
NPOI库为.NET环境下的Excel文件操作提供了强大的支持。通过本文的介绍,相信读者已经掌握了NPOI库的基本使用方法和高级特性。鼓励大家尝试使用NPOI来处理Excel文件,并分享自己的使用经验和技巧。
附录
-
更多内容请参考以下网址 https://github.com/nissl-lab/npoi
-
NPOI官方文档链接:NPOI官方网站
-
相关资源下载地址:[NPOI NuGet包](NuGet Gallery | NPOI 2.7.0