NET使用NPOI組件導出Excel-入門示例及通用方法

1、Excel導入及導出問題產生:

 
  從接觸.net到如今一直在維護一個DataTable導出到Excel的類,時不時還會維護一個導入類。如下是時不時就會出現的問題:
 
導出問題:
 
  若是是asp.net,你得在服務器端裝Office,幾百M呢,還得及時更新它,以防漏洞,還得設定權限容許ASP.net訪問COM+,據說若是導出過程當中出問題可能致使服務器宕機。
 
  Excel會把只包含數字的列進行類型轉換,原本是文本型的,它非要把你轉成數值型的,像身份證後三位變成000,編號000123會變成123,夠智能吧,夠鬱悶吧。不過這些都仍是能夠變通解決的,在他們前邊加上一個字母,讓他們不僅包含數字。
 
  導出時,若是你的字段內容以"-"或"="開頭,Excel好像把它當成了公式什麼的,接下來就出錯,提示:相似,保存到Sheet1的問題
 
導入問題:
 
  Excel會根據你的 Excel文件前8行分析數據類型,若是正好你前8行某一列只是數字,那它會認爲你這一列就是數值型的,而後,身份證,手機,編號都轉吧變成相似這樣的1.42702E+17格式,日期列變成 包含日期和數字的,亂的很,能夠經過改註冊表讓Excel分析整個表,但若是整列都是數字,那這個問題仍是解決不了。
 
 
  以上問題,通常人初次作時確定得上網查查吧,一個問題接着另外一個問題,查到你鬱郁而死,還有不少問題沒解決,最終感受已經解決的不錯了,但還不能保證某一天還會出個什麼問題。
 

2、使用第三方開源組件導入及導出Excel的解決方案:

 
  偶然間發現了NPOI與MyXls,相見恨晚,害的我在Excel上浪費了那麼多時間,他們倆的好處是:就是.net的自定義類庫,能夠直接對Excel進行讀或寫,而不依賴Office 的 Excel,這無論對於ASP.net或Winform都很是有利,不用擔憂Excel進程的釋放問題,服務器安全,設置,導出,導入「Excel智能識別」,公式日期等問題,能夠說之前的Excel問題,全都不用管了,它們能夠很好的幫你解決,NPOI || MyXls == 研究幾年Excel。
 
  NPOI開源地址: http://npoi.codeplex.com/
 
  MyXls開源地址: http://sourceforge.net/projects/myxls/
 

3、下面來兩個簡單入門例子:

MyXls 快速入門例子:
複製代碼
 /// <summary>
 /// MyXls簡單Demo,快速入門代碼
 /// </summary>
 /// <param name="dtSource"></param>
 /// <param name="strFileName"></param>
 /// <remarks>MyXls認爲Excel的第一個單元格是:(1,1)</remarks>
 public static void ExportEasy(DataTable dtSource,  string strFileName)
 {
     XlsDocument xls = new XlsDocument();
     Worksheet sheet = xls.Workbook.Worksheets.Add("Sheet1");
 
     //填充表頭
     foreach (DataColumn col in dtSource.Columns)
     {
         sheet.Cells.Add(1, col.Ordinal + 1, col.ColumnName);
     }
 
     //填充內容
     for (int i = 0; i < dtSource.Rows.Count; i++)
     {
         for (int j = 0; j < dtSource.Columns.Count; j++)
         {
             sheet.Cells.Add(i + 2, j + 1, dtSource.Rows[i][j].ToString());
         }
     }
 
     //保存
     xls.FileName = strFileName;
     xls.Save();
 }
複製代碼

 

NPOI 快速入門例子:
複製代碼
/// <summary>
 /// NPOI簡單Demo,快速入門代碼
 /// </summary>
 /// <param name="dtSource"></param>
 /// <param name="strFileName"></param>
 /// <remarks>NPOI認爲Excel的第一個單元格是:(0,0)</remarks>
 public static void ExportEasy(DataTable dtSource, string strFileName)
 {
     HSSFWorkbook workbook = new HSSFWorkbook();
     HSSFSheet sheet = workbook.CreateSheet();
 
     //填充表頭
     HSSFRow dataRow = sheet.CreateRow(0);
     foreach (DataColumn column in dtSource.Columns)
     {
         dataRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
     }
 
 
     //填充內容
     for (int i = 0; i < dtSource.Rows.Count; i++)
     {
         dataRow = sheet.CreateRow(i + 1);
         for (int j = 0; j < dtSource.Columns.Count; j++)
         {
             dataRow.CreateCell(j).SetCellValue(dtSource.Rows[i][j].ToString());
         }
     }
 
 
     //保存
     using (MemoryStream ms = new MemoryStream())
     {
         using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
         {
             workbook.Write(fs);
         }
     }
     workbook.Dispose();
 }
複製代碼

4、接下來是封裝的能夠用在實際項目中的類,實現的功能有(僅NPOI):

 
  1. 支持web及winform從DataTable導出到Excel。
  2. 生成速度很快。
  3. 準確判斷數據類型,不會出現身份證轉數值等上面提到的一系列問題。
  4. 若是單頁條數大於65535時會新建工做表。
  5. 列寬自適應。
  6. 支持讀取Excel。
  7. 調用方便,只一調用一個靜態類就OK了。
  8. 由於測試期間發現MyXls導出速度要比NPOI慢3倍,而NPOI既能知足咱們的導出需求,又能很好的知足咱們的導入需求,因此只針對NPOI進行全方位功能實現及優化。

 

複製代碼
NPOI操做類 

 using System;
 using System.Data;
 using System.Configuration;
 using System.Web;
 using System.Web.Security;
 using System.Web.UI;
 using System.Web.UI.HtmlControls;
 using System.Web.UI.WebControls;
 using System.Web.UI.WebControls.WebParts;
 using System.IO;
 using System.Text;
 using NPOI;
 using NPOI.HPSF;
 using NPOI.HSSF;
 using NPOI.HSSF.UserModel;
 using NPOI.HSSF.Util;
 using NPOI.POIFS;
 using NPOI.Util;  
 namespace SNF.Utilities
 {
     public class NPOIHelper
     {
         /// <summary>
         /// DataTable導出到Excel文件
         /// </summary>
         /// <param name="dtSource">源DataTable</param>
         /// <param name="strHeaderText">表頭文本</param>
         /// <param name="strFileName">保存位置</param>
         public static void Export(DataTable dtSource, string strHeaderText, string strFileName)
         {
             using (MemoryStream ms = Export(dtSource, strHeaderText))
             {
                 using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
                 {
                     byte[] data = ms.ToArray();
                     fs.Write(data, 0, data.Length);
                     fs.Flush();
                 }
             }
         }
 
         /// <summary>
         /// DataTable導出到Excel的MemoryStream
         /// </summary>
         /// <param name="dtSource">源DataTable</param>
         /// <param name="strHeaderText">表頭文本</param>
         public static MemoryStream Export(DataTable dtSource, string strHeaderText)
         {
             HSSFWorkbook workbook = new HSSFWorkbook();
             HSSFSheet sheet = workbook.CreateSheet();
 
             #region 右擊文件 屬性信息
             {
                 DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                 dsi.Company = "NPOI";
                 workbook.DocumentSummaryInformation = dsi;
 
                 SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                 si.Author = "文件做者信息"; //填加xls文件做者信息
                 si.ApplicationName = "建立程序信息"; //填加xls文件建立程序信息
                 si.LastAuthor = "最後保存者信息"; //填加xls文件最後保存者信息
                 si.Comments = "做者信息"; //填加xls文件做者信息
                 si.Title = "標題信息"; //填加xls文件標題信息

                 si.Subject = "主題信息";//填加文件主題信息
                 si.CreateDateTime = DateTime.Now;
                 workbook.SummaryInformation = si;
             }
             #endregion
 
             HSSFCellStyle dateStyle = workbook.CreateCellStyle();
             HSSFDataFormat format = workbook.CreateDataFormat();
             dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");
 
             //取得列寬
             int[] arrColWidth = new int[dtSource.Columns.Count];
             foreach (DataColumn item in dtSource.Columns)
             {
                 arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
             }
             for (int i = 0; i < dtSource.Rows.Count; i++)
             {
                 for (int j = 0; j < dtSource.Columns.Count; j++)
                 {
                     int intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[i][j].ToString()).Length;
                     if (intTemp > arrColWidth[j])
                     {
                         arrColWidth[j] = intTemp;
                     }
                 }
             } 
             int rowIndex = 0; 
             foreach (DataRow row in dtSource.Rows)
             {
                 #region 新建表,填充表頭,填充列頭,樣式
                 if (rowIndex == 65535 || rowIndex == 0)
                 {
                     if (rowIndex != 0)
                     {
                         sheet = workbook.CreateSheet();
                     }
 
                     #region 表頭及樣式
                     {
                         HSSFRow headerRow = sheet.CreateRow(0);
                         headerRow.HeightInPoints = 25;
                         headerRow.CreateCell(0).SetCellValue(strHeaderText);
 
                         HSSFCellStyle headStyle = workbook.CreateCellStyle();
                         headStyle.Alignment = CellHorizontalAlignment.CENTER;
                         HSSFFont font = workbook.CreateFont();
                         font.FontHeightInPoints = 20;
                         font.Boldweight = 700;
                         headStyle.SetFont(font);
                         headerRow.GetCell(0).CellStyle = headStyle;
                         sheet.AddMergedRegion(new Region(0, 0, 0, dtSource.Columns.Count - 1));
                         headerRow.Dispose();
                     }
                     #endregion
 
 
                     #region 列頭及樣式
                     {
                         HSSFRow headerRow = sheet.CreateRow(1); 
                         HSSFCellStyle headStyle = workbook.CreateCellStyle();
                         headStyle.Alignment = CellHorizontalAlignment.CENTER;
                         HSSFFont font = workbook.CreateFont();
                         font.FontHeightInPoints = 10;
                         font.Boldweight = 700;
                         headStyle.SetFont(font); 
                         foreach (DataColumn column in dtSource.Columns)
                         {
                             headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                             headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
 
                             //設置列寬
                             sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256); 
                         }
                         headerRow.Dispose();
                     }
                     #endregion
 
                     rowIndex = 2;
                 }
                 #endregion
 
 
                 #region 填充內容
                 HSSFRow dataRow = sheet.CreateRow(rowIndex);
                 foreach (DataColumn column in dtSource.Columns)
                 {
                     HSSFCell 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++;
             } 
             using (MemoryStream ms = new MemoryStream())
             {
                 workbook.Write(ms);
                 ms.Flush();
                 ms.Position = 0;
 
                 sheet.Dispose();
                 //workbook.Dispose();//通常只用寫這一個就OK了,他會遍歷並釋放全部資源,但當前版本有問題因此只釋放sheet
                 return ms;
             } 
         }
 
         /// <summary>
         /// 用於Web導出
         /// </summary>
         /// <param name="dtSource">源DataTable</param>
         /// <param name="strHeaderText">表頭文本</param>
         /// <param name="strFileName">文件名</param>
         public static void ExportByWeb(DataTable dtSource, string strHeaderText, string strFileName)
         { 
             HttpContext curContext = HttpContext.Current;
 
             // 設置編碼和附件格式
             curContext.Response.ContentType = "application/vnd.ms-excel";
             curContext.Response.ContentEncoding = Encoding.UTF8;
             curContext.Response.Charset = "";
             curContext.Response.AppendHeader("Content-Disposition",
                 "attachment;filename=" + HttpUtility.UrlEncode(strFileName, Encoding.UTF8));
 
             curContext.Response.BinaryWrite(Export(dtSource, strHeaderText).GetBuffer());
             curContext.Response.End(); 
         } 
 
         /// <summary>讀取excel
         /// 默認第一行爲標頭
         /// </summary>
         /// <param name="strFileName">excel文檔路徑</param>
         /// <returns></returns>
         public static DataTable Import(string strFileName)
         {
             DataTable dt = new DataTable();
 
             HSSFWorkbook hssfworkbook;
             using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
             {
                 hssfworkbook = new HSSFWorkbook(file);
             }
             HSSFSheet sheet = hssfworkbook.GetSheetAt(0);
             System.Collections.IEnumerator rows = sheet.GetRowEnumerator();
 
             HSSFRow headerRow = sheet.GetRow(0);
             int cellCount = headerRow.LastCellNum;
 
             for (int j = 0; j < cellCount; j++)
             {
                 HSSFCell cell = headerRow.GetCell(j);
                 dt.Columns.Add(cell.ToString());
             }
 
             for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++)
             {
                 HSSFRow row = sheet.GetRow(i);
                 DataRow dataRow = dt.NewRow();
 
                 for (int j = row.FirstCellNum; j < cellCount; j++)
                 {
                     if (row.GetCell(j) != null)
                         dataRow[j] = row.GetCell(j).ToString();
                 }
 
                 dt.Rows.Add(dataRow);
             }
             return dt;
         }
     }
 }
複製代碼

 

5、NPOI操做類的調用方法  

   DataTable dt_Grade = Tools.Data.GetDataTable(strSQL);
   filename += "績效考覈結果分數統計表";
   PMS.Common.NPOIHelper.ExportByWeb(dt_Grade, filename, filename+".xls");html

6、效果展現  

 

7、NPOI類庫下載:

NPOI 下載地址: http://npoi.codeplex.com/releasesweb

官方學習網站 : http://tonyqus.sinaapp.com/spring

 

信息來源:http://www.cnblogs.com/yongfa365/archive/2010/05/10/NPOI-MyXls-DataTable-To-Excel-From-Excel.html安全

8、參考地址:

 
NPOI導出Excel表功能實現(多個工做簿): http://www.cnblogs.com/zhengjuzhuan/archive/2010/02/01/1661103.html
在 Server 端存取 Excel 檔案的利器:NPOI Library: http://msdn.microsoft.com/zh-tw/ee818993.aspx
 
 

9、總結:

 
  經過以上分析,咱們不難發現,用NPOI或MyXls代替是Excel是很明智的,在發文前,我看到NPOI及MyXls仍然在活躍的更新中。在使用過程當中發現這兩個組件極類似,之前看過文章說他們使用的內核是同樣的。還有NPOI是國人開發的,且有相關中文文檔,在不少地方有相關引用,下載量也很大。而且它支持Excel,看到MyXls相關問題基本上沒人回答,因此推薦使用NPOI。MyXls能夠直接Cell.Font.Bold操做,而NPOI得使用CellType多少感受有點麻煩。 

 

出處:https://www.cnblogs.com/spring_wang/p/3145689.html服務器

================================================================================= app

簡單使用NPOI讀取和生成Excel文件

NPOI的下載地址:http://npoi.codeplex.com/
NPOI的使用教程(中文):http://tonyqus.sinaapp.com/

這裏只是寫一些簡單的例子以便查閱。
讀取Excel文件:
//打開Excel文件
using (FileStream excelfs = new FileStream("c:\\workbook.xls", FileMode.Open, FileAccess.Read))
{
    //根據「文件流」來建立HSSFWorkbook,即整個excel的工做簿
    HSSFWorkbook workbook = new HSSFWorkbook(excelfs);
    //獲取excel的第一個sheet工做表
    HSSFSheet sheet = (HSSFSheet)workbook.GetSheetAt(0);
    //循環讀取全部行的內容
    for (int i = sheet.FirstRowNum; i <= sheet.LastRowNum; i++)
    {
        DataRow newRow = table.NewRow();
        //讀取excel的行
         HSSFRow row = (HSSFRow)sheet.GetRow(i);
        if (row != null)
        {
            if (row.GetCell(0) != null)
            {
                //複製整行數據
                  for (int j = row.FirstCellNum; j < row.Cells.Count; j++)
                {
                    newRow[j] = row.GetCell(j);
                }
                //添加到數據表中
                  table.Rows.Add(newRow);
            }
        }
    }
}

生成Excel文件:asp.net

//新建workbook工做簿
HSSFWorkbook workbook = new HSSFWorkbook();
//新建sheet工做表
HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet();
//設置默認列寬
sheet.DefaultColumnWidth = 15;
//填充工做表的內容
for (int i = 0; i < dataSource.Count; i++)
{
    //新建row數據行
    HSSFRow dataRow = (HSSFRow)sheet.CreateRow(i);
    //填充數據行的內容
    for (int j = 0; j < dataSource.ToArray().Count(); j++)
    {
        //新建cell單元格並填充內容
        dataRow.CreateCell(j).SetCellValue(dataSource[i][j].ToString());
    }
}
//保存文件
using (FileStream fs = new FileStream("c:\\workbook.xls", FileMode.Create, FileAccess.Write))
{
    workbook.Write(fs);
}

 

出處:https://www.cnblogs.com/xwgli/archive/2013/04/07/3006151.htmlpost

相關文章
相關標籤/搜索