当前位置: 代码迷 >> 综合 >> C# Npoi 操作Excel 简单实例
  详细解决方案

C# Npoi 操作Excel 简单实例

热度:34   发布时间:2024-02-06 20:47:07.0

文章目录

  • 一、读取 Excel 数据
    • 1-1 读取 Excel 文档
    • 1-2 获取Sheet
    • 1-3 读取 Sheet 数据 并输出
    • 1-4 修改单元格数据
    • 1-5 删除 Sheet 表
    • 1-6 清空 Sheet 表某一行数据
    • 1-7 删除 Sheet 表某一行
  • 二、导入 Excel 数据
    • 2-1 创建 WorkBook
    • 2-2 写入 Excel 文档
  • 三、单元格样式

简单记录一下 NPOI 对 Excel 表的操作

一、读取 Excel 数据

1-1 读取 Excel 文档

① 查看 Excel 扩展名是 “.xls”,还是".xlsx";
② 打开文件流,读取 Excel 文件;
③ 通过 Excel 扩展名,实例化一个 IWorkbook 并将获取的文件流传入 :“.xls” 创建“HSSFWorkbook”;“.xlsx” 创建“XSSFWorkbook”;
④ 关闭文件流(非常重要)。

/// <summary>
/// 读取IWorkbook
/// </summary>
public IWorkbook ReadWorkbook = null;/// <summary>
/// 获取读取 WorkBook
/// </summary>
public void GetReadWorkbook(string FilePath)
{// 获取扩展名string ExtensionName = System.IO.Path.GetExtension(FilePath);// 文件流FileStream FileStream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite);// 把xls写入workbook中 2003版本if (ExtensionName.Equals(".xls")){ReadWorkbook = new HSSFWorkbook(FileStream);}// 把xlsx 写入workbook中 2007版本else if (ExtensionName.Equals(".xlsx")){ReadWorkbook = new XSSFWorkbook(FileStream);}else{ReadWorkbook = null;}FileStream.Close();
}

1-2 获取Sheet

1. 获取所有Sheet

通过循环遍历 Workbook,获取所有Sheet。

/// <summary>
/// 获取表中的Sheet名称
/// </summary>
public List<ISheet> Sheets = null;/// <summary>
/// 获取所有 Sheet表
/// </summary>
public void GetSheets()
{// 获取表Sheets = new List<ISheet>();var SheetCount = ReadWorkbook.NumberOfSheets;for (int i = 0; i < SheetCount; i++){Sheets.Add(ReadWorkbook.GetSheetAt(i));}
}

2. 通过 Sheet名 获取Sheet

① 通过Sheet 名获取 Sheet。
② 通过Sheet 名获取 Sheet数组对应的下标;
通过Sheet下标获取Sheet。

// 1. 通过Sheet 名获取 Sheet
int sheetIndex =ReadWorkbook.GetSheet("SheetName")
// 2.1 通过Sheet 名获取 Sheet数组对应的下标;
int sheetIndex =ReadWorkbook.GetSheetIndex("SheetName")
// 2.2 通过 Sheet下标获取 对应的 Sheet 数据
Isheet  sheet =ReadWorkbook.GetSheetAt(sheetIndex )

1-3 读取 Sheet 数据 并输出

① 获取 Sheet 表的行数:rowCount;
② 获取 Sheet 行对应列数: column;
③ 获取某行某列对应的单元格数据: cellValue =row.GetCell(j).ToString();
④ 将获取的 cell 输出:Console.Wlite(cellValue )。

/// <summary>
/// 获取 Sheet 表数据
/// </summary>
/// <param name="Sheet"></param>
private void GetSheetData(ISheet Sheet)
{if (Sheet == default){return null;}IRow row;// 1. 获取行数var rowCount = Sheet.LastRowNum;// 从第四行(下标为3)开始获取数据,前三行是表头// 如果从第一行开始,则i=0就可以了for (int i = 3; i <= rowCount; i++){var dataTable = new DataTable_Model();// 获取具体行row = Sheet.GetRow(i);if (row != null){// 2. 获取行对应的列数var column = row.LastCellNum;for (int j = 0; j < column; j++){// 3. 获取某行某列对应的单元格数据var cellValue = row.GetCell(j).ToString();      // 4. 输出单元格数据 Console.Wlite(cellValue+" ");}// 换行Console.WliteLine();}}
}

1-4 修改单元格数据

① 通过Sheet名 获取对应的ISheet;
② 获取修改 Sheet 的行数;
③ 获取修改Sheet 的对应行的列数;
④ 获取某行某列对应的单元格数据;
⑤ 向单元格传值,以覆盖对应单元格数据;
⑥ 对 Workbook 的修改写入文件流,对文件进行相应操作;
⑦ 备注:当文件打开时,文件流会报错。为了不影响再次操作,一定要关闭文件流。

同理:修改Sheet 表某行数据 / 修改Sheet 表指定单元格数据 则指定到 某行 / 某单元格 修改对应单元格数据即可。

/// <summary>
/// 修改 Field Sheet
/// </summary>
/// <param name="SheetName"></param>
/// <returns></returns>
private void UpdateSheet(string SheetName, string FilePath)
{// 创建文件流FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);try{// 1. 通过Sheet名 获取对应的ISeet--其中 ReadWorkbook 为读取Excel文档时获取var sheet = ReadWorkbook.GetSheet(SheetName);// 2. 获取行数int rowCount = sheet.LastRowNum;for (int i = 0; i < rowCount; i++){// 3. 获取行对应的列数int columnount = sheet.GetRow(i).LastCellNum;for (int j = 0; j < columnount; j++){// 4. 获取某行某列对应的单元格数据// 其中前三行设计为表头,故i+3,这里可以自己定义var sheetCellValue = sheet.GetRow(i + 3).GetCell(j);// 5. 向单元格传值,以覆盖对应的单元格数据sheetCellValue.SetCellValue(sheetCellValue + "Update");}}// 6. 对 Workbook 的修改写入文件流,对文件进行相应操作ReadWorkbook.Write(fsWrite);}catch (Exception ex){throw ex;}finally{// 7. 关闭文件流:报不报错都关闭fsWrite.Close();}
}

1-5 删除 Sheet 表

① 通过Sheet名 获取对应的ISheet 下标;
② 通过Sheet下标移除 Sheet;
③ 对 Workbook 的修改写入文件流,对文件进行相应操作;
备注:当文件打开时,文件流会报错。为了不影响再次操作,一定要关闭文件流。

/// <summary>
/// 删除其中一个Sheet
/// Bug:删除后,无Sheet表存在BUG
/// </summary>
/// <param name="SheetName"></param>
/// <param name="FilePath"></param>
/// <returns></returns>
public bool RemoveOneSheet(string SheetName, string FilePath)
{var Result = false;// 创建文件流FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);try{// 1. 通过Sheet名字查找Sheet下标var sheetIndex = ReadWorkbook.GetSheetIndex(SheetName);if (sheetIndex >= 0){// 2. 通过Sheet下标移除 SheetReadWorkbook.RemoveSheetAt(sheetIndex);// 3. 对 Workbook 的修改写入文件流,对文件进行相应操作ReadWorkbook.Write(fsWrite);Result = true;}return Result;}catch (Exception ex){throw ex;}finally{// 4. 关闭文件流:报不报错都关闭fsWrite.Close();}
}

1-6 清空 Sheet 表某一行数据

只清空数据,但是这一行在 Excel 扔存在:

① 通过Sheet名 获取对应的ISheet ;
② 定位到要删除的指定行;
③ 清空行数据;
④ 对 Workbook 的修改写入文件流,对文件进行相应操作;
备注:当文件打开时,文件流会报错。为了不影响再次操作,一定要关闭文件流。

/// <summary>
/// 清空 Sheet指定行数据
/// </summary>
/// <param name="Row"></param>
/// <param name="SheetName"></param>
/// <param name="FilePath"></param>
/// <returns></returns>
public bool EmptySheetRow(int RowNum, string SheetName, string FilePath)
{var Result = false;FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);try{1. 通过Sheet名 获取对应的 ISheet ISheet sheet_Table = ReadWorkbook.GetSheet(SheetName);if (sheet_Table != null){// 2. 定位到要删除的指定行IRow row = sheet_Table.GetRow(RowNum - 1);if (row != null){// 3. 清空行数据sheet_Table.RemoveRow(row);// 4. 对 Workbook 的修改写入文件流,对文件进行相应操作;ReadWorkbook.Write(fsWrite);Result = true;}}else{new Exception("This the Sheet does not exist");}return Result;}catch (Exception ex){throw ex;}finally{fsWrite.Close();}
}

1-7 删除 Sheet 表某一行

Sheet 不提供 直接删除行的数据,这里利用上下移动的方法,删除指定行:
删除行

① 通过Sheet名 获取对应的ISheet ;
② 确定移动行数:moveNum = EndNum - StartNum ;
③ 向上移动moveNum 行。其中
④ 对 Workbook 的修改写入文件流,对文件进行相应操作;
备注:当文件打开时,文件流会报错。为了不影响再次操作,一定要关闭文件流。

/// <summary>
/// 删除 Sheet指定行数据
/// </summary>
/// <param name="StartNum">起始行</param>
/// <param name="EndNum">终止行</param>
/// <param name="SheetName"></param>
/// <param name="FilePath"></param>
/// <returns></returns>
public bool RemoveSheetRow(int StartNum, int EndNum, string SheetName, string FilePath)
{var Result = false;FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);try{// 1. 通过Sheet名 获取对应的ISheet ISheet sheetTable = ReadWorkbook.GetSheet(SheetName);if (sheetTable == null){new Exception("This the Sheet does not exist");}// 2. 确定移动行数:保证EndNum >= StartNumint moveNum = EndNum - StartNum;// 3. 向上移动moveNum 行for (int i = 0; i <= moveNum; i++){// 向上移动:第EndNum+1到第sheetTable.LastRowNum+1行向上(-n)移动n行,-n只能为-1sheetTable.ShiftRows(EndNum, sheetTable.LastRowNum, -1);// 循环一次则向上移动一次,移动后需要开始移动的行数-1,则需要EndNum -1。不理解的话参考上方图片EndNum -= 1;}//向打开的这个xls文件中写入数据ReadWorkbook.Write(fsWrite);Result = true;return Result;}catch (Exception ex){throw ex;}finally{fsWrite.Close();}
}

二、导入 Excel 数据

2-1 创建 WorkBook

① 查看 Excel 扩展名是 “.xls”,还是".xlsx";
② 打开文件流,读取 Excel 文件;
③ 通过 Excel 扩展名,实例化一个空的 IWorkbook 表格 :“.xls” 创建“HSSFWorkbook”;“.xlsx” 创建“XSSFWorkbook”;


/// <summary>
/// 写入IWorkbook
/// </summary>
public IWorkbook WriteWorkbook = null;/// <summary>
/// 获取写入WorkBook
/// </summary>
public void GetWriteWorkbook(string FilePath)
{// 获取扩展名string ExtensionName = System.IO.Path.GetExtension(FilePath);// 把xls写入workbook中 2003版本if (ExtensionName.Equals(".xls")){WriteWorkbook = new HSSFWorkbook();}// 把xlsx 写入workbook中 2007版本else if (ExtensionName.Equals(".xlsx")){WriteWorkbook = new XSSFWorkbook();}else{WriteWorkbook = null;}
}

2-2 写入 Excel 文档

① 在WriteWorkbook 上添加名为 SheetTest 的数据表;
② 定义行数 rowCount=6;
③ 定义列数 columnount =8;
④ 循环创建行;
⑤ 创建某行某列对应的单元格;
⑥ 向单元格添加值。
备注:当文件打开时,文件流会报错。为了不影响再次操作,一定要关闭文件流。

/// <summary>
/// Table 实体类数据转 表格数据
/// </summary>
/// <param name="FilePath"></param>
/// <returns></returns>
private void TableDataToCell(string FilePath)
{FileStream fsWrite = new FileStream(FilePath, FileMode.Create, FileAccess.Write);try{// 1. 在WriteWorkbook 上添加名为 SheetTest 的数据表ISheet sheet=WriteWorkbook.CreateSheet("SheetTest ");// 2. 定义行数var rowCount = 6;// 3. 定义列数int columnount = 8;for (int i = 0; i < rowCount; i++){// 4. 创建行IRow  row = sheet.CreateRow(i);for (int j = 0; j < columnount; j++){// 5. 创建某行某列对应的单元格ICell cell = row.CreateCell(j);// 6. 向单元格添加值cell.SetCellValue($"第{i}行 第{j}列");// 添加表格样式cell.CellStyle = ExpandFliePath.OtherRowStyle();}}//7. 将表单写入文件流WriteWorkbook.Write(fsWrite);}catch (Exception ex){throw ex;}finally{// 关闭文件流fsWrite.Close();}
}

三、单元格样式

定义样式,这里定义的样式比较简单。
单元格样式在创建或获取到单元格时 , cell.CellStyle =OtherRowStyle(); 可以获取该样式

/// <summary>
/// 样式
/// </summary>
/// <returns></returns>
public static ICellStyle OtherRowStyle()
{var workbook = WriteWorkbook;ICellStyle cellStyle = workbook.CreateCellStyle();IFont font = workbook.CreateFont();font.FontName = "微软雅黑";//font.FontHeightInPoints = 15;//// 设置字体加粗样式//font.IsBold = true;// 使用SetFont方法将字体样式添加到单元格样式中cellStyle.SetFont(font);// 单元格样式:水平对齐居中cellStyle.Alignment = HorizontalAlignment.Center;//边框cellStyle.BorderBottom = BorderStyle.Thin;cellStyle.BorderLeft = BorderStyle.Thin;cellStyle.BorderRight = BorderStyle.Thin;cellStyle.BorderTop = BorderStyle.Thin;// 自动换行cellStyle.WrapText = true;//// 背景色//cellStyle.FillForegroundColor = BlueGrey.Index;return cellStyle;
}
  相关解决方案