NPOI 操作详解(操作Excel)

目录

[1. 安装 NPOI](#1. 安装 NPOI)

[2. 使用 NPOI 创建新 Excel 文件](#2. 使用 NPOI 创建新 Excel 文件)

[3. 设置列宽和行高](#3. 设置列宽和行高)

[1. 设置列宽](#1. 设置列宽)

[2. 设置行高](#2. 设置行高)

[3. 同时设置列宽和行高](#3. 同时设置列宽和行高)

[4. 设置统一的行高](#4. 设置统一的行高)

[5. 设置统一的列宽](#5. 设置统一的列宽)

[6. 应用统一的行高和列宽](#6. 应用统一的行高和列宽)

[4. 合并单元格](#4. 合并单元格)

[5. 设置单元格样式(字体、边框、背景色等)](#5. 设置单元格样式(字体、边框、背景色等))

[5. 向现有的 Excel 文件追加数据](#5. 向现有的 Excel 文件追加数据)

[6. 综合操作示例](#6. 综合操作示例)


概述:NPOI 是一个功能强大的第三方库,支持 .xls 和 .xlsx 格式,且完全开源。NPOI 可以在任何平台上运行,无需安装 Excel。

优点: 跨平台,支持 .xls 和 .xlsx 格式,性能较好。
**缺点:**与原生 Excel 功能兼容性较低,格式化和高级功能支持相对有限。

1. 安装 NPOI
2. 使用 NPOI 创建新 Excel 文件

以下代码演示了如何使用 NPOI 创建一个新的 Excel 文件,并向其中写入 DataTable 数据。

cs 复制代码
using System.Data;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel; // 对于 .xlsx 文件
using NPOI.HSSF.UserModel; // 对于 .xls 文件

public void CreateNewExcel(string filePath, DataTable dataTable)
{
    IWorkbook workbook;
    if (filePath.EndsWith(".xlsx"))
        workbook = new XSSFWorkbook(); // 创建 .xlsx 文件
    else
        workbook = new HSSFWorkbook(); // 创建 .xls 文件

    var sheet = workbook.CreateSheet("Sheet1");

    // 写入表头
    var headerRow = sheet.CreateRow(0);
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        headerRow.CreateCell(i).SetCellValue(dataTable.Columns[i].ColumnName);
    }

    // 写入数据
    for (int i = 0; i < dataTable.Rows.Count; i++)
    {
        var dataRow = sheet.CreateRow(i + 1);
        for (int j = 0; j < dataTable.Columns.Count; j++)
        {
            dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());
        }
    }

    // 保存文件
    using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        workbook.Write(stream);
    }
}
3. 设置列宽和行高
1. 设置列宽
cs 复制代码
public void SetColumnWidth(IWorkbook workbook, int sheetIndex, int columnIndex)
{
    var sheet = workbook.GetSheetAt(sheetIndex);

    // 设置列宽(单位是 1/256 字符宽度)
    sheet.SetColumnWidth(columnIndex, 20 * 256); // 设置第 1 列宽度为 20
}
2. 设置行高
cs 复制代码
public void SetColumnRowHeight(IWorkbook workbook, int sheetIndex, int rowIndex)
{
    var sheet = workbook.GetSheetAt(sheetIndex);

    // 设置行高(单位是点数)
    var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
    row.HeightInPoints = 25; // 设置行高为 25 点
}
3. 同时设置列宽和行高
cs 复制代码
public void SetColumnWidthAndRowHeight(IWorkbook workbook, int sheetIndex, int columnIndex, int rowIndex)
{
    var sheet = workbook.GetSheetAt(sheetIndex);

    // 设置列宽(单位是 1/256 字符宽度)
    sheet.SetColumnWidth(columnIndex, 20 * 256); // 设置第 1 列宽度为 20

    // 设置行高(单位是点数)
    var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
    row.HeightInPoints = 25; // 设置行高为 25 点
}
4. 设置统一的行高

在 NPOI 中,行高是通过每一行对象来设置的。可以遍历所有行并设置它们的行高,也可以在每次创建行时直接设定统一的高度。

cs 复制代码
public void SetUniformRowHeight(ISheet sheet, float heightInPoints)
{
    for (int i = 0; i <= sheet.LastRowNum; i++)
    {
        var row = sheet.GetRow(i) ?? sheet.CreateRow(i);
        row.HeightInPoints = heightInPoints; // 设置行高
    }
}
5. 设置统一的列宽

列宽可以直接对整个列进行设置,无需单独遍历单元格。列宽是以 1/256 字符宽度为单位的,设置时需要乘以 256。

cs 复制代码
public void SetUniformColumnWidth(ISheet sheet, int widthInCharacters)
{
    for (int i = 0; i < sheet.GetRow(0).LastCellNum; i++) // 以第一行的单元格数量为列数
    {
        sheet.SetColumnWidth(i, widthInCharacters * 256); // 设置列宽
    }
}
6. 应用统一的行高和列宽

可以将行高和列宽设置封装在一个方法中调用:

cs 复制代码
public void SetUniformRowHeightAndColumnWidth(ISheet sheet, float rowHeightInPoints, int columnWidthInCharacters)
{
    SetUniformRowHeight(sheet, rowHeightInPoints);
    SetUniformColumnWidth(sheet, columnWidthInCharacters);
}

使用示例:

假设我们有一个表格 sheet,要将所有行高统一设置为 20 点,列宽统一设置为 15 个字符宽:

cs 复制代码
SetUniformRowHeightAndColumnWidth(sheet, 20, 15);

这样就能高效地将整个表格的行高和列宽统一设置,无需遍历每个单元格。

4. 合并单元格

合并单元格可以通过 CellRangeAddress 设置,需要定义起始和结束的行列。

cs 复制代码
using NPOI.SS.Util;

public void MergeCells(IWorkbook workbook, int sheetIndex, int firstRow, int lastRow, int firstCol, int lastCol)
{
    var sheet = workbook.GetSheetAt(sheetIndex);

    // 合并单元格
    var cellRangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
    sheet.AddMergedRegion(cellRangeAddress);

    // 可以对合并后的单元格设置样式
    var cell = sheet.GetRow(firstRow).GetCell(firstCol) ?? sheet.GetRow(firstRow).CreateCell(firstCol);
    var style = workbook.CreateCellStyle();
    style.Alignment = HorizontalAlignment.Center;
    cell.CellStyle = style;
}
5. 设置单元格样式(字体、边框、背景色等)

使用 ICellStyle 进行字体、对齐、边框、背景等样式的配置:

cs 复制代码
public void SetCellStyle(IWorkbook workbook, int sheetIndex, int rowIndex, int colIndex)
{
    var sheet = workbook.GetSheetAt(sheetIndex);
    var cell = sheet.GetRow(rowIndex).GetCell(colIndex) ?? sheet.GetRow(rowIndex).CreateCell(colIndex);

    var style = workbook.CreateCellStyle();

    // 设置字体
    var font = workbook.CreateFont();
    font.FontHeightInPoints = 12;
    font.FontName = "Arial";
    font.IsBold = true;
    style.SetFont(font);

    // 设置边框
    style.BorderBottom = BorderStyle.Thin;
    style.BorderLeft = BorderStyle.Thin;
    style.BorderRight = BorderStyle.Thin;
    style.BorderTop = BorderStyle.Thin;

    // 设置背景颜色
    style.FillForegroundColor = IndexedColors.LightBlue.Index;
    style.FillPattern = FillPattern.SolidForeground;

    cell.CellStyle = style;
    cell.SetCellValue("示例文本");
}
5. 向现有的 Excel 文件追加数据

追加数据时,可以定位到现有数据的末尾,创建新行并写入。

cs 复制代码
public void AppendDataToExistingExcel(string filePath, DataTable dataTable)
{
    IWorkbook workbook;
    using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        workbook = filePath.EndsWith(".xlsx") ? (IWorkbook)new XSSFWorkbook(stream) : new HSSFWorkbook(stream);
    }

    var sheet = workbook.GetSheetAt(0);
    int lastRowNum = sheet.LastRowNum;

    for (int i = 0; i < dataTable.Rows.Count; i++)
    {
        var dataRow = sheet.CreateRow(lastRowNum + i + 1);
        for (int j = 0; j < dataTable.Columns.Count; j++)
        {
            dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());
        }
    }

    using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Write))
    {
        workbook.Write(stream);
    }
}
6. 综合操作示例

将所有设置组合在一起,确保不同操作可以在一个文件中同时应用:

cs 复制代码
public void FullExample(string filePath, DataTable dataTable)
{
    IWorkbook workbook = filePath.EndsWith(".xlsx") ? (IWorkbook)new XSSFWorkbook() : new HSSFWorkbook();
    var sheet = workbook.CreateSheet("Sheet1");

    // 设置表头
    var headerRow = sheet.CreateRow(0);
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        headerRow.CreateCell(i).SetCellValue(dataTable.Columns[i].ColumnName);
    }

    // 写入数据
    for (int i = 0; i < dataTable.Rows.Count; i++)
    {
        var dataRow = sheet.CreateRow(i + 1);
        for (int j = 0; j < dataTable.Columns.Count; j++)
        {
            dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());
        }
    }

    // 设置列宽和行高
    SetColumnWidthAndRowHeight(workbook, 0, 1, 1);

    // 合并单元格(比如合并第 2 行第 1 列到第 2 列)
    MergeCells(workbook, 0, 1, 1, 0, 1);

    // 设置单元格样式
    SetCellStyle(workbook, 0, 1, 1);

    // 保存文件
    using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        workbook.Write(stream);
    }
}

总结:

  • 创建、读取、追加、设置样式等基本操作可以涵盖常见的 NPOI 使用场景。
  • NPOI 适合处理数据量较大的 Excel 文件,不依赖于 Excel 安装,并且支持 .xls 和 .xlsx 格式。
相关推荐
E-iceblue19 小时前
Excel 列转行/行列转换全指南:从 4 种常见解法到 Python 批量自动化
python·excel·python库·spire.xls
Data-Miner1 天前
AI处理数据的脚本复用与逻辑复用有什么区别?哪种方式更能沉淀工作成果
数据分析·excel
福兮说1 天前
在浏览器里写一个“够用就好“的 Excel 公式求值器
前端·javascript·excel·编译原理
慧都小妮子2 天前
标签打印如何减少手工抄数?用Bartender 直连 Excel 批量打印
excel·bartender·条码打印·标签打印软件·数据驱动打印·工业打印机
SunnyDays10112 天前
Java 设置 Excel 数据验证:整数、日期、文本长度、下拉列表和时间
java·excel·数据验证·下拉列表
Metaphor6922 天前
使用 Python 设置 Excel 行列自适应 【代码示例】
python·excel
用户0332126663673 天前
使用 Python 设置 Excel 行列自适应 【代码示例】
python·excel
企业数字化笔记3 天前
固定资产Excel批量导入怎么防重复?资产编码、重复检查和错误回执
java·后端·excel
CORNERSTONE3653 天前
低代码开发有哪些应用场景?
低代码·excel·erp·mes·企业数字化
小葱炖豆腐4 天前
python绘制excel折线图
python·excel·numpy·pandas·matplotlib