C#使用NPOI庫操作Excel


C#使用NPOI庫操作Excel

https://www.cnblogs.com/restran/p/3889479.html

https://www.cnblogs.com/wanzhongjun/p/7151514.html

https://blog.csdn.net/WuLex/article/details/108914907

https://www.pianshen.com/article/9409729801/

1. 引用動態庫

ICSharpCode.SharpZipLib.dll

NPOI.dll

NPOI.OOXML.dll

NPOI.OpenXml4Net.dll

NPOI.OpenXmlFormats.dll

2. 頭文件

using NPOI;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
using System.Diagnostics;

3. 從Excel中讀取

excel表格有兩種后綴名 .xls 和 .xlsx。.xls是office2007以前版本的excel表的后綴名,而.xlsx是office2007以后的excel后綴。

一個excel文件表里有多個工作簿sheet,每一個工作簿中都可以存數據。

(1)打開.xlsx文件

//打開或創建excel文件並向里添加數據
//new HSSFWorkbook();	//這是用於后綴名是.xls的excel文件的操作
FileStream fs = File.OpenRead("C:\\Users\\Administrator\\Desktop\\table1.xlsx");	//關聯流打開文件
IWorkbook workbook = null;	
workbook = new XSSFWorkbook(fs);    //XSSF打開xlsx

(2)讀取sheet

ISheet sheet = null;
sheet = workbook.GetSheetAt(i);	//獲取第i個sheet

(3)讀取行

IRow row = null;
row = sheet.GetRow(i);	//獲取第i行
//行標從0開始計數
int  numsOfRows = sheet.LastRowNum + 1;	//sheet.LastRowNum為最后一行的index

(4)讀取某行的單元格內的數據(單元格內可存不同數據類型)

ICell cell = row.GetCell(i);	//獲取row行的第i列的數據
//單元格存儲的數據類型
public enum CellType
    {
        Unknown = -1,
        Numeric = 0,
        String = 1,
        Formula = 2,
        Blank = 3,
        Boolean = 4,
        Error = 5
    }

//NPOI庫中ICell定義
public interface ICell
    {
        ISheet Sheet { get; }
        CellRangeAddress ArrayFormulaRange { get; }
        IHyperlink Hyperlink { get; set; }
        IComment CellComment { get; set; }
        ICellStyle CellStyle { get; set; }
        bool BooleanCellValue { get; }	
        string StringCellValue { get; }	//若存儲的是string,可通過該屬性獲取string值
        byte ErrorCellValue { get; }
        IRichTextString RichStringCellValue { get; }
        DateTime DateCellValue { get; }	//獲取DateTime
        double NumericCellValue { get; }	
        string CellFormula { get; set; }
        CellType CachedFormulaResultType { get; }
        CellType CellType { get; }	//通過該屬性獲取存儲的數據的類型
        IRow Row { get; }
        bool IsMergedCell { get; }
        int RowIndex { get; }
        int ColumnIndex { get; }
        bool IsPartOfArrayFormulaGroup { get; }

        ICell CopyCellTo(int targetIndex);
        CellType GetCachedFormulaResultTypeEnum();
        void RemoveCellComment();
        void RemoveHyperlink();
        void SetAsActiveCell();
        void SetCellErrorValue(byte value);
        void SetCellFormula(string formula);
        void SetCellType(CellType cellType);
        void SetCellValue(bool value);
        void SetCellValue(string value);
        void SetCellValue(IRichTextString value);
        void SetCellValue(DateTime value);
        void SetCellValue(double value);
    }
  • 據此,可自定義一個根據數據類型獲取數據的函數:
//返回值是object,具體用變量來接的時候,要先強轉一下
/**
   在讀取文件時大都會判斷單元格類型,方式大同小異,只有日期類型不同。

  默認日期類型的單元格在NPOI都認為是數值類型(CellType.Numeric)

  在高版本中用HSSFDateUtil.IsCellDateFormatted(cell)  來判斷

  但在低版中沒有這個類,網上找到有NPOI.SS.UserModel.DateUtil.IsCellDateFormatted(cell),同樣的作用。
*/
public object GetCellValue(ICell cell)
        {
            object value = null;
            try
            {
                if (cell.CellType != CellType.Blank)
                {
                    switch (cell.CellType)
                    {
                        case CellType.Numeric:
                            //判斷單元格內數據是否是DateTime
                            if (DateUtil.IsCellDateFormatted(cell))
                            {
                                value = cell.DateCellValue;	//若是日期格式,則用DateCellValue獲取DateTime
                            }
                            else
                            {
                                // Numeric type
                                value = cell.NumericCellValue;
                            }
                            break;
                        case CellType.Boolean:
                            // Boolean type
                            value = cell.BooleanCellValue;
                            break;
                        case CellType.Formula:
                            value = cell.CellFormula;
                            break;
                        default:
                            // String type
                            value = cell.StringCellValue;
                            break;
                    }
                }
            }
            catch (Exception)
            {
                value = "";
            }

            return value;
        }

5. 寫Excel

(1)用流創建或讀取.xlsx文件(同時流關聯了文件)

FileStream filestream = new FileStream(@"C:\Users\25224\Desktop\table2.xlsx", FileMode.OpenOrCreate);	
//Excel表打開方式public enum FileMode    {        //        // 摘要:        //     指定操作系統應創建新文件。這需要 System.Security.Permissions.FileIOPermissionAccess.Write 權限。如果文件已存在,則將引發        //     System.IO.IOException異常。        CreateNew = 1,        //        // 摘要:        //     指定操作系統應創建新文件。如果文件已存在,它將被覆蓋。    	//這需要 System.Security.Permissions.FileIOPermissionAccess.Write        //     權限。FileMode.Create 等效於這樣的請求:如果文件不存在,則使用 System.IO.FileMode.CreateNew;否則使用 System.IO.FileMode.Truncate。如果該文件已存在但為隱藏文件,則將引發        //     System.UnauthorizedAccessException異常。        Create = 2,        //        // 摘要:        //     指定操作系統應打開現有文件。	    //打開文件的能力取決於 System.IO.FileAccess 枚舉所指定的值。如果文件不存在,引發一個 System.IO.FileNotFoundException        //     異常。        Open = 3,        //        // 摘要:        //     指定操作系統應打開文件(如果文件存在);否則,應創建新文件。    	//如果用 FileAccess.Read 打開文件,則需要 System.Security.Permissions.FileIOPermissionAccess.Read權限。如果文件訪問為        //     FileAccess.Write,則需要 System.Security.Permissions.FileIOPermissionAccess.Write權限。如果用        //     FileAccess.ReadWrite 打開文件,則同時需要 System.Security.Permissions.FileIOPermissionAccess.Read        //     和 System.Security.Permissions.FileIOPermissionAccess.Write權限。        OpenOrCreate = 4,        //        // 摘要:        //     指定操作系統應打開現有文件。該文件被打開時,將被截斷為零字節大小。這需要 System.Security.Permissions.FileIOPermissionAccess.Write        //     權限。嘗試從使用 FileMode.Truncate 打開的文件中進行讀取將導致 System.ArgumentException 異常。        Truncate = 5,        //        // 摘要:        //     若存在文件,則打開該文件並查找到文件尾,或者創建一個新文件。這需要 System.Security.Permissions.FileIOPermissionAccess.Append        //     權限。FileMode.Append 只能與 FileAccess.Write 一起使用。試圖查找文件尾之前的位置時會引發 System.IO.IOException        //     異常,並且任何試圖讀取的操作都會失敗並引發 System.NotSupportedException 異常。        Append = 6    }

(2)創建表和sheet

XSSFWorkbook wk = new XSSFWorkbook();	//創建表對象wkISheet isheet = wk.CreateSheet("Sheet1");	//在wk中創建sheet1

(3)設置列寬、行高

SetColumnWidth(isheet, 0, 20);	//colIndex=0SetColumnWidth(isheet, 1, 20);	//colIndex=1IRow row2 =null;row2 = isheet.CreateRow(j);row2.Height =2 * 256;

(4)向單元格中寫數據

 IRow row2 =null; ICell cell = null; row2 = isheet.CreateRow(j);	//創建index=j的行 cell = row2.CreateCell(0);		//在index=j的行中創建index=0的單元格 cell.SetCellValue("哈哈");		//給創建的單元格賦值string

(5)通過流將表中寫入的數據一次性寫入文件中

wk.Write(filestream);	//通過流filestream將表wk寫入文件filestream.Close();	//關閉文件流filestreamwk.Close();	//關閉Excel表對象wk

(6)追加數據,保留原有數據

向已存在的Excel追加數據,保留原有數據

/// <summary>        /// 向已存在的excel追加數據        /// </summary>        /// <param name="excelPath">已存在的excel路徑</param>        /// <param name="rowIndex">追加行索引</param>        /// <param name="cellData">追加列索引<列索引,單元格值></param>        public void addExcelData(string excelPath, int rowIndex, IDictionary<int, string> cellData)        {            FileStream fs = new FileStream(excelPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//讀取流            POIFSFileSystem ps = new POIFSFileSystem(fs);//需using NPOI.POIFS.FileSystem;            HSSFWorkbook workbook = new HSSFWorkbook(ps);            ISheet sheet = workbook.GetSheetAt(0);//獲取工作表            //設置列寬            SetColumnWidth(sheet, 0, 20);            SetColumnWidth(sheet, 1, 10);            IRow row = sheet.GetRow(rowIndex); //得到表頭            //設置行高            row.Height =2 * 256;            ICell cell = null;            ICellStyle style = null;            foreach (KeyValuePair<int, string> keyValue in cellData)            {                if (keyValue.Key == 1)                {                    cell = row.CreateCell(keyValue.Key);                    cell.SetCellValue(keyValue.Value);                                       style = workbook.CreateCellStyle();                    //設置左對齊                    style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.LEFT;                    //設置斜線                    style.BorderDiagonal = BorderDiagonal.BACKWARD;                    style.BorderDiagonalLineStyle = NPOI.SS.UserModel.BorderStyle.THIN;                    //設置換行(若要單元格內換行必須加下面一句)                    style.WrapText = true;                    cell.CellStyle = style;                }                else                {                    cell = row.CreateCell(keyValue.Key);                    cell.SetCellValue(keyValue.Value);                    //設置居中                    style = workbook.CreateCellStyle();                    style.VerticalAlignment = VerticalAlignment.CENTER;                    style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER;                    cell.CellStyle = style;                }            }            FileStream fout = new FileStream(excelPath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);//寫入流            fout.Flush();            workbook.Write(fout);//寫入文件            workbook = null;            fout.Close();        }

6. 日期格式

在Excel表中寫入時間數據時,設置單元格格式,自定義格式yyyy-MM-dd HH:mm:ss

(1)DateTime

.toString("yyyy-MM-dd HH:mm:ss.fff");	//mm-dd才顯示08-01,否則顯示8-1//fff個數表示小數點后顯示的位數,這里精確到小數點后3位

注意:一定要注意大小寫!!!M是月份,寫成了m就是分鍾數了!!

(2)DateTime轉String

DateTime轉string:https://www.cnblogs.com/JiYF/p/7831547.html

(3)String轉DateTime

string轉DateTime:https://www.cnblogs.com/Pickuper/articles/2058880.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM