.NET NPOI導出Excel詳解

NPOI,顧名思義,就是POI的.NET版本。那POI又是什麼呢?POI是一套用Java寫成的庫,能夠幫助開發者在沒有安裝微軟Office的情況下讀寫Office的文件。

支持的文件格式包括xls, doc, ppt等。

官方網站:http://npoi.codeplex.com/

nuget直接獲取使用

一、NPOI生成Excel

複製代碼
            //創建工作薄
            var workbook = new HSSFWorkbook();
            //創建表
            var table = workbook.CreateSheet("joye.net");

            //模擬20行20列數據
            for (var i = 0; i < 20; i++)
            {
                var row = table.CreateRow(i);
                for (int j = 0; j < 20; j++)
                {
                    var cell = row.CreateCell(j);
                    cell.SetCellValue(j);
                }
            }
            //打開xls文件,如沒有則創建,如存在則在創建是不要打開該文件
            using (var fs = File.OpenWrite(@"c:/joye.net.xls"))
            {
                workbook.Write(fs);   //向打開的這個xls文件中寫入mySheet表並保存。
                Console.WriteLine("生成成功");
            }
複製代碼

二、NPOI讀取Excel

複製代碼
using (var fs = File.OpenRead(@"c:/joye.net.xls")) 
            {
                //把xls文件中的數據寫入workbook1中
                var workbook1 = new HSSFWorkbook(fs);
                for (var i = 0; i < workbook1.NumberOfSheets; i++)
                {
                    var sheet = workbook1.GetSheetAt(i);
                    for (var j = 0; j <= sheet.LastRowNum; j++)
                    {   
                        //讀取當前行數據
                        var row = sheet.GetRow(j);
                        if (row != null)
                        {
                            for (var k = 0; k <= row.LastCellNum; k++)
                            {   //當前表格
                                var cell = row.GetCell(k);
                                if (cell != null)
                                {
                                    Console.Write(cell.ToString() + "  ");
                                }
                            }
                        }
                        Console.WriteLine();
                    }
                }
            }
複製代碼

讀出的結果

 三、簡單學習

複製代碼
/// <summary>
        ///  組裝workbook.
        /// </summary>
        /// <param name="dt">dataTable資源</param>
        /// <param name="columnHeader">表頭</param>
        /// <returns></returns>
        public static HSSFWorkbook BuildWorkbook1(DataTable dt, string columnHeader = "")
        {
            var workbook = new HSSFWorkbook();
            ISheet sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName);

            #region 文件屬性信息
            {
                var dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                dsi.Company = "NPOI";
                workbook.DocumentSummaryInformation = dsi;

                SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                si.Author = "文件作者信息";
                si.ApplicationName = "創建程序信息";
                si.LastAuthor = "最後保存者信息";
                si.Comments = "作者信息";
                si.Title = "標題信息";
                si.Subject = "主題信息";
                si.CreateDateTime = DateTime.Now;
                workbook.SummaryInformation = si;
            }
            #endregion

            var dateStyle = workbook.CreateCellStyle();
            var format = workbook.CreateDataFormat();
            dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");

            //取得列寬
            var arrColWidth = new int[dt.Columns.Count];
            foreach (DataColumn item in dt.Columns)
            {
                arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
            }
            for (var i = 0; i < dt.Rows.Count; i++)
            {
                for (var j = 0; j < dt.Columns.Count; j++)
                {
                    int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length;
                    if (intTemp > arrColWidth[j])
                    {
                        arrColWidth[j] = intTemp;
                    }
                }
            }
            int rowIndex = 0;
            foreach (DataRow row in dt.Rows)
            {
                #region 表頭 列頭
                if (rowIndex == 65535 || rowIndex == 0)
                {
                    if (rowIndex != 0)
                    {
                        sheet = workbook.CreateSheet();
                    }

                    #region 表頭及樣式
                    {
                        var headerRow = sheet.CreateRow(0);
                        headerRow.HeightInPoints = 25;
                        headerRow.CreateCell(0).SetCellValue(columnHeader);
                        //CellStyle
                        ICellStyle headStyle = workbook.CreateCellStyle();
                        headStyle.Alignment = HorizontalAlignment.Center;// 左右居中    
                        headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 
                        // 設置單元格的背景顏色(單元格的樣式會覆蓋列或行的樣式)    
                        headStyle.FillForegroundColor = (short)11;
                        //定義font
                        IFont font = workbook.CreateFont();
                        font.FontHeightInPoints = 20;
                        font.Boldweight = 700;
                        headStyle.SetFont(font);
                        headerRow.GetCell(0).CellStyle = headStyle;
                        sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dt.Columns.Count - 1));
                    }
                    #endregion


                    #region 列頭及樣式
                    {
                        var headerRow = sheet.CreateRow(1);
                        //CellStyle
                        ICellStyle headStyle = workbook.CreateCellStyle();
                        headStyle.Alignment = HorizontalAlignment.Center;// 左右居中    
                        headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 
                        //定義font
                        IFont font = workbook.CreateFont();
                        font.FontHeightInPoints = 10;
                        font.Boldweight = 700;
                        headStyle.SetFont(font);

                        foreach (DataColumn column in dt.Columns)
                        {
                            headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                            headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
                            sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);
                        }
                    }
                    #endregion
                    if (columnHeader != "")
                    {
                        //header row
                        IRow row0 = sheet.CreateRow(0);
                        for (int i = 0; i < dt.Columns.Count; i++)
                        {
                            ICell cell = row0.CreateCell(i, CellType.String);
                            cell.SetCellValue(dt.Columns[i].ColumnName);
                        }
                    }

                    rowIndex = 2;
                }
                #endregion


                #region 內容
                var dataRow = sheet.CreateRow(rowIndex);
                foreach (DataColumn column in dt.Columns)
                {
                    var newCell = dataRow.CreateCell(column.Ordinal);

                    string drValue = row[column].ToString();

                    switch (column.DataType.ToString())
                    {
                        case "System.String"://字符串類型
                            newCell.SetCellValue(drValue);
                            break;
                        case "System.DateTime"://日期類型
                            DateTime dateV;
                            DateTime.TryParse(drValue, out dateV);
                            newCell.SetCellValue(dateV);

                            newCell.CellStyle = dateStyle;//格式化顯示
                            break;
                        case "System.Boolean"://布爾型
                            bool boolV = false;
                            bool.TryParse(drValue, out boolV);
                            newCell.SetCellValue(boolV);
                            break;
                        case "System.Int16"://整型
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            int intV = 0;
                            int.TryParse(drValue, out intV);
                            newCell.SetCellValue(intV);
                            break;
                        case "System.Decimal"://浮點型
                        case "System.Double":
                            double doubV = 0;
                            double.TryParse(drValue, out doubV);
                            newCell.SetCellValue(doubV);
                            break;
                        case "System.DBNull"://空值處理
                            newCell.SetCellValue("");
                            break;
                        default:
                            newCell.SetCellValue("");
                            break;
                    }

                }
                #endregion

                rowIndex++;
            }
            //自動列寬
            for (int i = 0; i <= dt.Columns.Count; i++)
                sheet.AutoSizeColumn(i, true);

            return workbook;
        }
複製代碼
複製代碼
            var dt = new DataTable();
             //模擬20行20列數據
            for (var i = 0; i < 3; i++)
            {
                dt.Columns.Add(i.ToString());
            }
            for (var j = 0; j < 65537; j++)
            {
                dt.Rows.Add(new object[] { 0 ,1,2 });
            }
            var newBook = BuildWorkbook(dt);
            using (var fs = File.OpenWrite(@"c:/joye.net1.xls"))
            {
                newBook.Write(fs);
                Console.WriteLine("生成成功");
            }
複製代碼

四、NPOI導出Excel 65536問題

複製代碼
        public static HSSFWorkbook BuildWorkbook(DataTable dt)
        {
            var book = new HSSFWorkbook();  

            ISheet sheet = book.CreateSheet("Sheet1");
            //Data Rows
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                IRow drow = sheet.CreateRow(i);
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    ICell cell = drow.CreateCell(j, CellType.String);
                    cell.SetCellValue(dt.Rows[i][j].ToString());
                }
            }
            //自動列寬
            for (int i = 0; i <= dt.Columns.Count; i++)
                sheet.AutoSizeColumn(i, true);
            return book;
        }
複製代碼

NPOI導出Excel超過65536會報異常,原來是由於NPOI這個動態庫導致的,然後看了下版本,發現是1.2.5。然後百度了下,發現這個版本的NPOI只支持office2003,二office2003最多支持65536行

解決方式:

1、只是在插入數據的時候,加個判斷,如果數據條數大於65536時,就在創建一個sheet

複製代碼
        //65536判斷處理
        public static HSSFWorkbook BuildWorkbook(DataTable dt)
        {
            var book = new HSSFWorkbook();

            ISheet sheet1 = book.CreateSheet("Sheet1");
            ISheet sheet2 = book.CreateSheet("Sheet2");

            //填充數據
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (i < 65536)
                {
                    IRow drow = sheet1.CreateRow(i);
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        ICell cell = drow.CreateCell(j, CellType.String);
                        cell.SetCellValue(dt.Rows[i][j].ToString());
                    }
                }
                if (i >= 65536)
                {
                    IRow drow = sheet2.CreateRow(i - 65536);
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        ICell cell = drow.CreateCell(j, CellType.String);
                        cell.SetCellValue(dt.Rows[i][j].ToString());
                    }
                }

            }

            //自動列寬
            for (int i = 0; i <= dt.Columns.Count; i++)
            {
                sheet1.AutoSizeColumn(i, true);
                sheet2.AutoSizeColumn(i, true);
            }
            return book;
        }
複製代碼

2、考慮使用高版本Office,使用用對象支持高版本的NPOI

複製代碼
        //高版本
        public static XSSFWorkbook BuildWorkbook(DataTable dt)
        {
            var book = new XSSFWorkbook();
            ISheet sheet = book.CreateSheet("Sheet1");
            //Data Rows
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                IRow drow = sheet.CreateRow(i);
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    ICell cell = drow.CreateCell(j, CellType.String);
                    cell.SetCellValue(dt.Rows[i][j].ToString());
                }
            }
            //自動列寬
            for (int i = 0; i <= dt.Columns.Count; i++)
                sheet.AutoSizeColumn(i, true);

            return book;
        }
複製代碼

五、web開發中導出Excel

複製代碼
        public static void ExportExcel(DataTable dt, string fileName = "")
        {
            //生成Excel
            IWorkbook book = BuildWorkbook(dt);

            //web 下載
            if (fileName == "")
                fileName = string.Format("{0:yyyyMMddHHmmssffff}", DateTime.Now);
            fileName = fileName.Trim();
            string ext = Path.GetExtension(fileName);

            if (ext.ToLower() == ".xls" || ext.ToLower() == ".xlsx")
                fileName = fileName.Replace(ext, string.Empty);

            HttpResponse httpResponse = HttpContext.Current.Response;
            httpResponse.Clear();
            httpResponse.Buffer = true;
            httpResponse.Charset = Encoding.UTF8.BodyName;
            httpResponse.AppendHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");
            httpResponse.ContentEncoding = Encoding.UTF8;
            httpResponse.ContentType = "application/vnd.ms-excel; charset=UTF-8";
            book.Write(httpResponse.OutputStream);
            httpResponse.End();
        }
複製代碼

 

基於.xls模板生成Excel文件有時間再看

代碼下載:https://yunpan.cn/cRBVnTCSchz7k (提取碼:779e) 

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