简介:本文全面解析NPOI库的核心功能与使用技巧,涵盖基础操作、高级特性及实际场景应用,为开发者提供系统化的技术指导。
NPOI作为.NET平台下领先的开源Office文件操作库,凭借其轻量级、高性能和跨版本兼容性,已成为企业级应用中处理Excel、Word等文档的核心工具。本手册从基础环境搭建到高级功能实现,系统梳理NPOI的核心组件与典型应用场景,结合代码示例与最佳实践,帮助开发者快速掌握文档生成、数据解析与格式控制的完整技术链。
NPOI是POI项目的.NET移植版本,通过抽象层设计同时支持XSSF(Office Open XML格式)和HSSF(二进制BIFF格式),实现Excel 2003-2019及后续版本的全面兼容。其核心优势体现在:
| 组件包 | 功能范围 | 适用场景 |
|---|---|---|
| NPOI | 基础功能(Excel/Word读写) | 通用文档处理需求 |
| NPOI.OOXML | Office 2007+格式支持 | 需要处理xlsx/docx等新格式 |
| NPOI.OpenXml4Net | 高级XML处理扩展 | 复杂文档结构解析 |
建议通过NuGet安装最新稳定版(当前推荐2.6.0+),在.NET Core 3.1+/NET 5+环境中可获得最佳性能表现。
// 创建新工作簿IWorkbook workbook = new XSSFWorkbook(); // xlsx格式// IWorkbook workbook = new HSSFWorkbook(); // xls格式// 添加工作表ISheet sheet = workbook.CreateSheet("销售数据");// 获取已有工作表ISheet existingSheet = workbook.GetSheetAt(0);// 工作表属性设置sheet.DefaultColumnWidth = 15; // 默认列宽sheet.SetZoomRatio(120); // 显示比例
IRow row = sheet.CreateRow(0);// 文本类型row.CreateCell(0).SetCellValue("产品名称");// 数值类型row.CreateCell(1).SetCellValue(1250.75);// 日期类型(需配合样式)ICellStyle dateStyle = workbook.CreateCellStyle();dateStyle.DataFormat = workbook.CreateDataFormat().GetFormat("yyyy-mm-dd");ICell dateCell = row.CreateCell(2);dateCell.SetCellValue(new DateTime(2023,5,15));dateCell.CellStyle = dateStyle;
using (FileStream fs = new FileStream("data.xlsx", FileMode.Open)){IWorkbook readWorkbook = new XSSFWorkbook(fs);ISheet readSheet = readWorkbook.GetSheetAt(0);for (int i = 0; i <= readSheet.LastRowNum; i++){IRow readRow = readSheet.GetRow(i);if (readRow != null){for (int j = 0; j < readRow.LastCellNum; j++){ICell cell = readRow.GetCell(j);switch (cell.CellType){case CellType.String:Console.Write(cell.StringCellValue + "\t");break;case CellType.Numeric:if (DateUtil.IsCellDateFormatted(cell))Console.Write(cell.DateCellValue.ToString("yyyy-MM-dd") + "\t");elseConsole.Write(cell.NumericCellValue + "\t");break;// 其他类型处理...}}Console.WriteLine();}}}
ISheet conditionSheet = workbook.CreateSheet("条件格式");ICellStyle highlightStyle = workbook.CreateCellStyle();IFont redFont = workbook.CreateFont();redFont.Color = IndexedColors.Red.Index;highlightStyle.SetFont(redFont);// 创建条件格式规则ISheetConditionalFormatting cf = conditionSheet.SheetConditionalFormatting;ConditionalFormattingRule rule = cf.CreateConditionalFormattingRule(ComparisonOperator.GreaterThanOrEqual,"90"); // 数值比较// 应用规则到区域CellRangeAddress[] regions = { new CellRangeAddress(0, 100, 0, 0) };cf.AddConditionalFormatting(regions, rule, highlightStyle);
IDrawing drawing = sheet.CreateDrawingPatriarch();IClientAnchor anchor = drawing.CreateAnchor(0, 0, 0, 0, 3, 0, 10, 20);// 创建折线图IChart chart = ((XSSFDrawing)drawing).CreateChart(anchor);IChartLegend legend = chart.GetOrCreateLegend();legend.Position = LegendPosition.Bottom;// 数据系列配置ILineChartData data = chart.ChartDataFactory.CreateLineChartData();IChartAxis bottomAxis = chart.ChartAxisFactory.CreateCategoryAxis(AxisPosition.Bottom);IChartAxis leftAxis = chart.ChartAxisFactory.CreateValueAxis(AxisPosition.Left);// 添加数据系列(需配合实际数据范围)// ...
XWPFDocument doc = new XWPFDocument();// 创建带样式的段落XWPFParagraph para = doc.CreateParagraph();para.Alignment = ParagraphAlignment.CENTER;para.SpacingAfter = 200; // 200 twips单位// 创建运行对象并应用样式XWPFRun run = para.CreateRun();run.SetText("年度销售报告");run.SetBold(true);run.FontSize = 18;run.SetColor("4F81BD");// 保存文档using (FileStream outStream = new FileStream("report.docx", FileMode.Create)){doc.Write(outStream);}
// 创建5列3行的表格XWPFTable table = doc.CreateTable(3, 5);table.Width = "90%"; // 相对宽度// 设置表头样式XWPFTableRow headerRow = table.GetRow(0);foreach (XWPFTableCell cell in headerRow.GetTableCells()){cell.SetText("表头内容");cell.SetVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);}// 填充数据(示例)for (int i = 1; i < 3; i++){XWPFTableRow row = table.GetRow(i);for (int j = 0; j < 5; j++){row.GetCell(j).SetText($"数据{i}-{j}");}}
分块写入:对超过10万行数据,采用每5000行保存一次的机制
for (int batch = 0; batch < totalBatches; batch++){// 处理当前批次数据...if (batch % 10 == 0) // 每10个批次强制刷新{using (FileStream tempStream = new FileStream("temp.xlsx", FileMode.Create)){workbook.Write(tempStream);}}}
样式复用:预先创建常用样式对象池
```csharp
// 创建样式模板
Dictionary
ICellStyle headerStyle = workbook.CreateCellStyle();
// 设置样式属性…
stylePool.Add(“Header”, headerStyle);
// 使用时直接从池中获取
row.CreateCell(0).CellStyle = stylePool[“Header”];
### 4.2 异常处理机制```csharptry{// NPOI操作代码...}catch (EncryptedDocumentException ex){// 处理加密文件异常Console.WriteLine($"文件加密错误: {ex.Message}");}catch (IOException ex) when (ex.HResult == -2147024864) // 特定错误码处理{// 处理文件占用错误Console.WriteLine("请关闭已打开的Excel文件");}catch (Exception ex){// 记录完整堆栈Logger.Error(ex, "NPOI操作异常");throw;}
// 配置财务专用样式ICellStyle currencyStyle = workbook.CreateCellStyle();currencyStyle.DataFormat = workbook.CreateDataFormat().GetFormat("¥#,##0.00");// 生成利润表ISheet profitSheet = workbook.CreateSheet("利润表");// 写入表头...// 循环写入科目数据(示例)decimal[] revenues = { 1250000, 980000, 1520000 };for (int i = 0; i < revenues.Length; i++){IRow dataRow = profitSheet.CreateRow(i + 2);dataRow.CreateCell(0).SetCellValue($"Q{i + 1}");ICell revenueCell = dataRow.CreateCell(1);revenueCell.SetCellValue(revenues[i]);revenueCell.CellStyle = currencyStyle;}
// 使用模板文件using (FileStream template = new FileStream("template.xlsx", FileMode.Open)){IWorkbook templateWorkbook = new XSSFWorkbook(template);ISheet dataSheet = templateWorkbook.GetSheet("Data");// 填充动态数据Dictionary<string, object> dataMap = new Dictionary<string, object>{{"${CompanyName}", "ABC科技"},{"${ReportDate}", DateTime.Now.ToString("yyyy年MM月dd日")}};// 实现模板替换逻辑(需自行实现或使用现有模板引擎)// ...}
ICellStyle chineseStyle = workbook.CreateCellStyle();
chineseStyle.SetFont(chineseFont);
### 6.2 内存溢出处理- **症状**:处理10万+行数据时出现OutOfMemoryException- **优化方案**:1. 使用`SXSSFWorkbook`(NPOI.OOXML扩展)实现流式写入```csharp// 创建流式工作簿(行访问窗口设为100)SXSSFWorkbook streamingWorkbook = new SXSSFWorkbook(100);// 后续操作与普通Workbook一致// 处理完成后显式调用Dispose()释放资源
var options = new XSSFWorkbook.CompressionOption{CompressTempFiles = true};IWorkbook compressedWorkbook = new XSSFWorkbook(null, options);
本手册通过系统化的技术解析与实战案例,全面覆盖了NPOI在文档处理中的核心应用场景。开发者可通过示例代码快速实现功能开发,同时结合性能优化策略应对企业级应用的复杂需求。建议在实际项目中建立样式模板库与异常处理中间件,进一步提升开发效率与系统稳定性。