C# 如何使用NPOI操作Excel以及讀取合並單元格等


C#操作Excel方法有很多,以前用的需要電腦安裝office才能用,但因為版權問題公司不允許安裝office。所以改用NPOI進行Excel操作,基本上一些簡單的Excel操作都沒有問題,讀寫合並單元格等都能實現。

NPOI 庫下載地址

命名空間:

using NPOI;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;

簡單的保存數據:

        public void ExcelTest(string path)
        {
            IWorkbook workbook = new HSSFWorkbook();//創建Workbook
            workbook.CreateSheet("sheet1");//創建sheet
            using (FileStream fs = File.Create(path))//path=mmm.xls;
            {
                ISheet sheet = workbook.GetSheetAt(0);//獲取sheet
                sheet.CreateRow(1).CreateCell(0).SetCellValue("nami");//創建第一行/創建第一單元格/設置第一單元格的內容[可以分開創建,但必須先創建行才能創建單元格不然報錯]
                sheet.GetRow(1).CreateCell(1).SetCellValue("robin");//獲取第一行/創建第二單元格/設置第二單元格的內容
                sheet.CreateRow(2).CreateCell(0).SetCellValue("saber");//創建第二行/創建第一單元格/設置第一單元格的內容
                sheet.GetRow(2).CreateCell(1).SetCellValue("luffy");//獲取第二行/創建第二單元格/設置第二單元格的內容
                sheet.GetRow(1).CreateCell(2).SetCellValue(5);
                sheet.GetRow(2).CreateCell(2).SetCellValue(2);
                //添加批注
                IDrawing draw = sheet.CreateDrawingPatriarch();
                IComment comment = draw.CreateCellComment(new HSSFClientAnchor(0, 0, 0, 0, 1, 2, 4, 4));//里面參數應該是指示批注的位置大小吧
                comment.String = new HSSFRichTextString("one-piece");//添加批注內容
                comment.Author = "夢琪小生";//添加批注作者
                sheet.GetRow(1).GetCell(1).CellComment = comment;//將之前設置的批注給定某個單元格
                //單元格格式設置
                ICellStyle cellStyle = workbook.CreateCellStyle();
                IDataFormat format = workbook.CreateDataFormat();
                cellStyle.DataFormat = format.GetFormat("0.00");
                sheet.GetRow(2).GetCell(2).CellStyle = cellStyle;
                //合並單元格
                sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, 2));
                sheet.CreateRow(0).CreateCell(0).SetCellValue("夢琪小生");
                ICellStyle titleStyle = workbook.CreateCellStyle();
                IFont titleFont = workbook.CreateFont();
                titleFont.FontHeightInPoints = 15;//設置字體大小
                titleFont.Color = HSSFColor.BLUE.index;//設置字體顏色
                titleStyle.SetFont(titleFont);
                titleStyle.Alignment = HorizontalAlignment.CENTER;//居中
                sheet.GetRow(0).GetCell(0).CellStyle = titleStyle;
                ICellStyle style = workbook.CreateCellStyle();
                style.BorderBottom = BorderStyle.THIN;
                style.BorderLeft = BorderStyle.THIN;
                style.BorderRight = BorderStyle.THIN;
                style.BorderTop = BorderStyle.THIN;
                sheet.GetRow(1).GetCell(1).CellStyle = style;
                //插入圖片
                HSSFClientAnchor anchor2 = new HSSFClientAnchor(0, 0, 0, 0, 0, 5, 6, 10);
                byte[] bytes = System.IO.File.ReadAllBytes(@"C:\Users\Administrator\Desktop\image\mqxs.png");
                int picID = workbook.AddPicture(bytes, PictureType.PNG);
                IPicture pic = patriarch.CreatePicture(anchor2, picID);
                pic.Resize();
                workbook.Write(fs);//保存文件
            }
        }

讀取Excel返回DataTable:

        /// <summary>
        /// 讀取Excel[.xls](返回DataTable)
        /// </summary>
        /// <param name="path">Excel路徑</param>
        /// <returns></returns>
        public static DataTable ReadExcel(string path)
        {
            try
            {
                DataTable dt = new DataTable();
                using (FileStream fs = new FileStream(path, FileMode.Open))
                {
                    IWorkbook workbook = new HSSFWorkbook(fs);
                    ISheet sheet = workbook.GetSheetAt(0);
                    int rfirst = sheet.FirstRowNum;
                    int rlast = sheet.LastRowNum;
                    IRow row = sheet.GetRow(rfirst);
                    int cfirst = row.FirstCellNum;
                    int clast = row.LastCellNum;
                    for (int i = cfirst; i < clast; i++)
                    {
                        if (row.GetCell(i) != null)
                            dt.Columns.Add(row.GetCell(i).StringCellValue, System.Type.GetType("System.String"));
                    }
                    row = null;
                    for (int i = rfirst + 1; i <= rlast; i++)
                    {
                        DataRow r = dt.NewRow();
                        IRow ir = sheet.GetRow(i);
                        for (int j = cfirst; j < clast; j++)
                        {
                            if (ir.GetCell(j) != null)
                            {
                                r[j] = ir.GetCell(j).ToString();
                            }
                        }
                        dt.Rows.Add(r);
                        ir = null;
                        r = null;
                    }
                    sheet = null;
                    workbook = null;
                }
                return dt;
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("Excel格式錯誤或者Excel正由另一進程在訪問");
                return null;
            }
        }

Ok,NPOI也用了一段時間了....

講一點經驗之談...關於NPOI的單元格樣式CellStyles個數是有限制的4000個,所以大家設置單元格樣式的時候盡量不要再for循環里面定義,可以在for循環外圍定義好使用...減少CellStyles個數,Ok,主要要講的是下面的那一條....

((HSSFSheet)sheet).SetEnclosedBorderOfRegion(new NPOI.SS.Util.CellRangeAddress(0, 50, 0, 100), BorderStyle.MEDIUM, HSSFColor.BLACK.index);

這句的功能是給合並后的單元格加外邊框。

比如這條語句的意思是將單元格0行0列到50行100列繪制一個整體的外邊框。用到是很好用...但是很占資源,不知道為什么就這么一句話會占好幾個CellStyles...而且速度較慢....

所以這個功能在數據量小的可以用,問題不大,速度基本影響也不大,但數據量一大...這個相對就會拖累速度了又太占資源.

小生我就在這邊吃過虧,就是這條語句導致CellStyles個數不夠用[當然不是一句就會有問題咯....因為很多地方合並單元格然后加外邊框...最終就悲劇了....]....小生覺得這是NPOI的缺陷...

 

NPOI操作Excel使用說明:

官網教程相當詳細,需進一步學習的請移步至官網學習  http://tonyqus.sinaapp.com/npoi2tutorial

 

2017/05/05補充:

C# Color轉NPOI顏色:

/// <summary>
        /// 獲取顏色值
        /// </summary>
        /// <param name="color">顏色RGB</param>
        /// <param name="workbook">Excel畫布</param>
        /// <returns></returns>
        public static short GetColorIndex(this HSSFWorkbook workbook,Color color)
        {
            HSSFPalette palette = workbook.GetCustomPalette();
            var v = palette.FindSimilarColor(color.R, color.G, color.B);
            if (v == null)
            {
                throw new Exception("Color is not in Palette");
            }
            else return v.GetIndex();
        }

 2018/4/8補充:

獲取合並單元格

 

        /// <summary>
        /// 獲取當前單元格所在的合並單元格的位置
        /// </summary>
        /// <param name="sheet">sheet表單</param>
        /// <param name="rowIndex">行索引 0開始</param>
        /// <param name="colIndex">列索引 0開始</param>
        /// <param name="start">合並單元格左上角坐標</param>
        /// <param name="end">合並單元格右下角坐標</param>
        /// <returns>返回false表示非合並單元格</returns>
        private static bool IsMergeCell(ISheet sheet, int rowIndex, int colIndex, out Point start, out Point end)
        {
            bool result = false;
            start = new Point(0, 0);
            end = new Point(0, 0);
            if ((rowIndex < 0) || (colIndex < 0)) return result;
            int regionsCount = sheet.NumMergedRegions;
            for (int i = 0; i < regionsCount; i++)
            {
                CellRangeAddress range = sheet.GetMergedRegion(i);
                //sheet.IsMergedRegion(range); 
                if (rowIndex >= range.FirstRow && rowIndex <= range.LastRow && colIndex >= range.FirstColumn && colIndex <= range.LastColumn)
                {
                    start = new Point(range.FirstRow, range.FirstColumn);
                    end = new Point(range.LastRow, range.LastColumn);
                    result = true;
                    break;
                }
            }
            return result;
        }

 

 

 

掃碼關注微信公眾號

 

微信公眾號

 

 


免責聲明!

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



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