Npoi對Excel進行讀寫操作Demo (.NetCore 3.1)

轉載來源:https://blog.csdn.net/M1234uy/article/details/107695252

 

前言

Npoi 可以在沒有安裝Office 的情況寫 對 Word 或 Excel 文檔進行讀寫操作。

npoi 是一個開源的C#讀寫Excel、Word等微軟OLE2組件文檔的項目。本文主要講對 Excel 文檔進行讀寫操作。

一、讀取 Excel

1-1 讀取 Excel 文件

流程圖
在這裏插入圖片描述

代碼

/// <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-2-1 獲取所有 Sheet

通過 For 循環 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));
    }
}

1-2-2 獲取單個Sheet

通過 Sheet名 獲取Sheet有兩種方法:
1. 通過 SheetName 獲取 Sheet。

// 1. 通過Sheet 名獲取 Sheet
int sheetIndex =ReadWorkbook.GetSheet("SheetName")
  • 1
  • 2

2. 通過 SheetName 獲取 Sheet數組對應的 下標。 再通過Sheet下標獲取Sheet。

// 2.a通過Sheet 名獲取 Sheet數組對應的下標;
int sheetIndex =ReadWorkbook.GetSheetIndex("SheetName")
// 2.b 通過 Sheet下標獲取 對應的 Sheet 數據
Isheet  sheet =ReadWorkbook.GetSheetAt(sheetIndex )

1-3 讀取 Sheet 數據

流程圖

流程圖

代碼

/// <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();
        }
    }
}

二、修改 Excel

2-1 修改單元格數據

流程圖
在這裏插入圖片描述
代碼

/// <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();
    }
}

 

2-2 修改指定行數據

流程圖
流程圖

代碼

/// <summary>
/// 修改 Field Sheet
/// </summary>
/// <param name="SheetName"></param>
/// <returns></returns>
private void UpdateSheet(string SheetName, string FilePath,int RowCount)
{
    // 創建文件流
    FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);
    try
    {
    	// 1. 通過Sheet名 獲取對應的ISeet--其中 ReadWorkbook 爲讀取Excel文檔時獲取
        var sheet = ReadWorkbook.GetSheet(SheetName);
        // 2. 獲取行對應的列數
        int column = sheet.GetRow(RowCount).LastCellNum;
        for (int j = 0; j < column ; j++)
        {
            // 3. 獲取某行某列對應的單元格數據
            // 其中前三行設計爲表頭,故i+3,這裏可以自己定義
            var sheetCellValue = sheet.GetRow(RowCount).GetCell(j);
            // 4. 向單元格傳值,以覆蓋對應的單元格數據
            sheetCellValue.SetCellValue(sheetCellValue + "Update");
        }
        // 5. 對 Workbook 的修改寫入文件流,對文件進行相應操作
        ReadWorkbook.Write(fsWrite);
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
    	// 7. 關閉文件流:報不報錯都關閉
        fsWrite.Close();
    }
}

 

三、刪除 Excel

3-1 刪除 Sheet 表

流程圖在這裏插入圖片描述

代碼

/// <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下標移除 Sheet
            ReadWorkbook.RemoveSheetAt(sheetIndex);
            // 3. 對 Workbook 的修改寫入文件流,對文件進行相應操作
            ReadWorkbook.Write(fsWrite);
            Result = true;
        }
        return Result;
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
    	// 4. 關閉文件流:報不報錯都關閉
        fsWrite.Close();
    }
}

【注意】:若Excel 表格刪除後 沒有Sheet表格,打開Excel時會出現錯誤。

【參考解決思路】:刪除指定Sheet表格後,判斷Excel中是否存在Sheet表,若存在則寫入Excel表格;反之,刪除該Excel文件。(僅供參考)

3-2 清空 Sheet 表指定行數據

只清空數據,不刪除改行( 該方法存在BUG,暫時無法使用。)

流程圖
流程圖
代碼

/// <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();
    }
}

3-3 刪除 Sheet 表指定行

Sheet 不提供 直接刪除行的數據,這裏利用上下移動的方法,刪除指定行。

向上移動行過程
刪除行過程
流程圖
在這裏插入圖片描述

代碼

/// <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 >= StartNum
        int moveNum = EndNum - StartNum;
        // 3. 向上移動moveNum 行
        for (int i = 0; i <= moveNum; i++)
        {
        	// 向上移動:第EndNum+1到第sheetTable.LastRowNum+1行向上(-n)移動n行,-n只能爲-1
            sheetTable.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

4-1 創建 WorkBook

流程圖
在這裏插入圖片描述

代碼

/// <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;
    }
}

4-2 寫入 Excel 文件

流程圖
流程圖
代碼

/// <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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章