C#的Excel匯入、匯出_C#教程

來源:互聯網
上載者:User

本篇主要介紹C#的Excel匯入、匯出,供大家參考,具體內容如下

一. 介紹
1.1 第三方類庫:NPOI

說明:NPOI是POI項目的.NET 版本,可用於Excel、Word的讀寫操作。

優點:不用裝Office環境。

下載地址:http://npoi.codeplex.com/releases 

1.2 Excel結構介紹

活頁簿(Workbook):每個Excel檔案可理解為一個活頁簿。

工作表(Sheet):一個活頁簿(Workbook)可以包含多個工作表。

行(row):一個工作表(Sheet)可以包含多個行。

二. Excel匯入
2.1 操作流程

2.2 NPOI作業碼

說明:把Excel檔案轉換為List<T>

步驟:

①讀取Excel檔案並以此初始化一個活頁簿(Workbook);

②從活頁簿上擷取一個工作表(Sheet);預設為工作薄的第一個工作表;

③遍曆工作表所有的行(row);預設從第二行開始遍曆,第一行(序號0)為儲存格頭部;

④遍曆行的每一個儲存格(cell),根據一定的規律賦值給對象的屬性。

代碼:

/// <summary>/// 從Excel2003取資料並記錄到List集合裡/// </summary>/// <param name="cellHeard">單元頭的Key和Value:{ { "UserName", "姓名" }, { "Age", "年齡" } };</param>/// <param name="filePath">儲存檔案絕對路徑</param>/// <param name="errorMsg">錯誤資訊</param>/// <returns>轉換好的List對象集合</returns>private static List<T> Excel2003ToEntityList<T>(Dictionary<string, string> cellHeard, string filePath, out StringBuilder errorMsg) where T : new(){  errorMsg = new StringBuilder(); // 錯誤資訊,Excel轉換到實體物件時,會有格式的錯誤資訊  List<T> enlist = new List<T>(); // 轉換後的集合  List<string> keys = cellHeard.Keys.ToList(); // 要賦值的實體物件屬性名稱  try  {    using (FileStream fs = File.OpenRead(filePath))    {      HSSFWorkbook workbook = new HSSFWorkbook(fs);      HSSFSheet sheet = (HSSFSheet)workbook.GetSheetAt(0); // 擷取此檔案第一個Sheet頁      for (int i = 1; i <= sheet.LastRowNum; i++) // 從1開始,第0行為單元頭      {        // 1.判斷當前行是否空行,若空行就不在進行讀取下一行操作,結束Excel讀取操作        if (sheet.GetRow(i) == null)        {          break;        }         T en = new T();        string errStr = ""; // 當前行轉換時,是否有錯誤資訊,格式為:第1行資料轉換異常:XXX列;        for (int j = 0; j < keys.Count; j++)        {          // 2.若屬性頭的名稱包含'.',就表示是子類裡的屬性,那麼就要遍曆子類,eg:UserEn.TrueName          if (keys[j].IndexOf(".") >= 0)          {            // 2.1解析子類屬性            string[] properotyArray = keys[j].Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);            string subClassName = properotyArray[0]; // '.'前面的為子類的名稱            string subClassProperotyName = properotyArray[1]; // '.'後面的為子類的屬性名稱            System.Reflection.PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 擷取子類的類型            if (subClassInfo != null)            {              // 2.1.1 擷取子類的執行個體              var subClassEn = en.GetType().GetProperty(subClassName).GetValue(en, null);              // 2.1.2 根據屬性名稱擷取子類裡的屬性資訊              System.Reflection.PropertyInfo properotyInfo = subClassInfo.PropertyType.GetProperty(subClassProperotyName);              if (properotyInfo != null)              {                try                {                  // Excel儲存格的值轉換為對象屬性的值,若類型不對,記錄出錯資訊                  properotyInfo.SetValue(subClassEn, GetExcelCellToProperty(properotyInfo.PropertyType, sheet.GetRow(i).GetCell(j)), null);                }                catch (Exception e)                {                  if (errStr.Length == 0)                  {                    errStr = "第" + i + "行資料轉換異常:";                  }                  errStr += cellHeard[keys[j]] + "列;";                }                               }            }          }          else          {            // 3.給指定的屬性賦值            System.Reflection.PropertyInfo properotyInfo = en.GetType().GetProperty(keys[j]);            if (properotyInfo != null)            {              try              {                // Excel儲存格的值轉換為對象屬性的值,若類型不對,記錄出錯資訊                properotyInfo.SetValue(en, GetExcelCellToProperty(properotyInfo.PropertyType, sheet.GetRow(i).GetCell(j)), null);              }              catch (Exception e)              {                if (errStr.Length == 0)                {                  errStr = "第" + i + "行資料轉換異常:";                }                errStr += cellHeard[keys[j]] + "列;";              }            }          }        }        // 若有錯誤資訊,就添加到錯誤資訊裡        if (errStr.Length > 0)        {          errorMsg.AppendLine(errStr);        }        enlist.Add(en);      }    }    return enlist;  }  catch (Exception ex)  {    throw ex;  }} 

2.3 C#邏輯作業碼

說明:對Excel轉換後的List<T>進行後續操作;如:檢測有效性、持久化儲存等等

步驟:

①調用2.2代碼,把Excel檔案轉換為List<T>。

②對List<T>進行有效性檢測:必填項是否為空白、是否有重複記錄等等。

③對List<T>進行持久化儲存操作。如:儲存到資料庫。

④返回操作結果。

代碼:

public void ImportExcel(HttpContext context){  StringBuilder errorMsg = new StringBuilder(); // 錯誤資訊  try  {     #region 1.擷取Excel檔案並轉換為一個List集合     // 1.1存放Excel檔案到本機伺服器    HttpPostedFile filePost = context.Request.Files["filed"]; // 擷取上傳的檔案    string filePath = ExcelHelper.SaveExcelFile(filePost); // 儲存檔案並擷取檔案路徑     // 儲存格抬頭    // key:實體物件屬性名稱,可通過反射擷取值    // value:屬性對應的中文註解    Dictionary<string, string> cellheader = new Dictionary<string, string> {      { "Name", "姓名" },      { "Age", "年齡" },      { "GenderName", "性別" },      { "TranscriptsEn.ChineseScores", "語文成績" },      { "TranscriptsEn.MathScores", "數學成績" },    };     // 1.2解析檔案,存放到一個List集合裡    List<UserEntity> enlist = ExcelHelper.ExcelToEntityList<UserEntity>(cellheader, filePath, out errorMsg);     #endregion     #region 2.對List集合進行有效性校正     #region 2.1檢測必填項是否必填     for (int i = 0; i < enlist.Count; i++)    {      UserEntity en = enlist[i];      string errorMsgStr = "第" + (i + 1) + "行資料檢測異常:";      bool isHaveNoInputValue = false; // 是否含有未輸入項      if (string.IsNullOrEmpty(en.Name))      {        errorMsgStr += "姓名列不可為空;";        isHaveNoInputValue = true;      }      if (isHaveNoInputValue) // 若必填項有值未填      {        en.IsExcelVaildateOK = false;        errorMsg.AppendLine(errorMsgStr);      }    }     #endregion     #region 2.2檢測Excel中是否有重複對象     for (int i = 0; i < enlist.Count; i++)    {      UserEntity enA = enlist[i];      if (enA.IsExcelVaildateOK == false) // 上面驗證不通過,不進行此步驗證      {        continue;      }       for (int j = i + 1; j < enlist.Count; j++)      {        UserEntity enB = enlist[j];        // 判斷必填列是否全部重複        if (enA.Name == enB.Name)        {          enA.IsExcelVaildateOK = false;          enB.IsExcelVaildateOK = false;          errorMsg.AppendLine("第" + (i + 1) + "行與第" + (j + 1) + "行的必填列重複了");        }      }    }     #endregion     // TODO:其他檢測     #endregion     // 3.TODO:對List集合持久化儲存操作。如:儲存到資料庫         // 4.返回操作結果    bool isSuccess = false;    if (errorMsg.Length == 0)    {      isSuccess = true; // 若錯誤資訊成都為空白,表示無錯誤資訊    }    var rs = new { success = isSuccess, msg = errorMsg.ToString(), data = enlist };    System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();    context.Response.ContentType = "text/plain";    context.Response.Write(js.Serialize(rs)); // 返回Json格式的內容  }  catch (Exception ex)  {     throw ex;  }}  

3. Excel匯出
3.1 匯出流程

3.2 NPOI作業碼

說明:把List<T>轉換為Excel

步驟:

①建立一個活頁簿(Workbook);

②在活頁簿上建立一個工作表(Sheet);

③在工作表上建立第一行(row),第一行為列頭,依次寫入cellHeard的值(做為列名)。

④迴圈遍曆List<T>集合,每迴圈一遍建立一個行(row),然後根據cellHeard的鍵(屬性名稱)依次從List<T>中的實體物件取值存放到儲存格內。

代碼:

/// <summary>/// 實體類集合匯出到Excle2003/// </summary>/// <param name="cellHeard">單元頭的Key和Value:{ { "UserName", "姓名" }, { "Age", "年齡" } };</param>/// <param name="enList">資料來源</param>/// <param name="sheetName">工作表名稱</param>/// <returns>檔案的下載地址</returns>public static string EntityListToExcel2003(Dictionary<string, string> cellHeard, IList enList, string sheetName){  try  {    string fileName = sheetName + "-" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".xls"; // 檔案名稱    string urlPath = "UpFiles/ExcelFiles/" + fileName; // 檔案下載的URL地址,供給前台下載    string filePath = HttpContext.Current.Server.MapPath("\\" + urlPath); // 檔案路徑     // 1.檢測是否存在檔案夾,若不存在就建立個檔案夾    string directoryName = Path.GetDirectoryName(filePath);    if (!Directory.Exists(directoryName))    {      Directory.CreateDirectory(directoryName);    }     // 2.解析儲存格頭部,設定單元頭的中文名稱    HSSFWorkbook workbook = new HSSFWorkbook(); // 活頁簿    ISheet sheet = workbook.CreateSheet(sheetName); // 工作表    IRow row = sheet.CreateRow(0);    List<string> keys = cellHeard.Keys.ToList();    for (int i = 0; i < keys.Count; i++)    {      row.CreateCell(i).SetCellValue(cellHeard[keys[i]]); // 列名為Key的值    }     // 3.List對象的值賦值到Excel的儲存格裡    int rowIndex = 1; // 從第二行開始賦值(第一行已設定為單元頭)    foreach (var en in enList)    {      IRow rowTmp = sheet.CreateRow(rowIndex);      for (int i = 0; i < keys.Count; i++) // 根據指定的屬性名稱,擷取對象指定屬性的值      {        string cellValue = ""; // 儲存格的值        object properotyValue = null; // 屬性的值        System.Reflection.PropertyInfo properotyInfo = null; // 屬性的資訊         // 3.1 若屬性頭的名稱包含'.',就表示是子類裡的屬性,那麼就要遍曆子類,eg:UserEn.UserName        if (keys[i].IndexOf(".") >= 0)        {          // 3.1.1 解析子類屬性(這裡只解析1層子類,多層子類未處理)          string[] properotyArray = keys[i].Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);          string subClassName = properotyArray[0]; // '.'前面的為子類的名稱          string subClassProperotyName = properotyArray[1]; // '.'後面的為子類的屬性名稱          System.Reflection.PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 擷取子類的類型          if (subClassInfo != null)          {            // 3.1.2 擷取子類的執行個體            var subClassEn = en.GetType().GetProperty(subClassName).GetValue(en, null);            // 3.1.3 根據屬性名稱擷取子類裡的屬性類型            properotyInfo = subClassInfo.PropertyType.GetProperty(subClassProperotyName);            if (properotyInfo != null)            {              properotyValue = properotyInfo.GetValue(subClassEn, null); // 擷取子類屬性的值            }          }        }        else        {          // 3.2 若不是子類的屬性,直接根據屬性名稱擷取對象對應的屬性          properotyInfo = en.GetType().GetProperty(keys[i]);          if (properotyInfo != null)          {            properotyValue = properotyInfo.GetValue(en, null);          }        }         // 3.3 屬性值經過轉換賦值給儲存格值        if (properotyValue != null)        {          cellValue = properotyValue.ToString();          // 3.3.1 對時間初始值賦值為空白          if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")          {            cellValue = "";          }        }         // 3.4 填充到Excel的儲存格裡        rowTmp.CreateCell(i).SetCellValue(cellValue);      }      rowIndex++;    }     // 4.組建檔案    FileStream file = new FileStream(filePath, FileMode.Create);    workbook.Write(file);    file.Close();     // 5.返回下載路徑    return urlPath;  }  catch (Exception ex)  {    throw ex;  }} 

3.3 C#邏輯作業碼

說明:對Excel轉換後的List<T>進行後續操作;如:檢測有效性、持久化儲存等等

步驟:

①擷取List<T>集合。

②調用3.2,將List<T>轉換為Excel檔案。

③伺服器儲存Excel檔案並返回下載連結。

代碼:

public void ExportExcel(HttpContext context){  try  {    // 1.擷取資料集合    List<UserEntity> enlist = new List<UserEntity>() {      new UserEntity{Name="劉一",Age=22,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=80,MathScores=90}},      new UserEntity{Name="陳二",Age=23,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=81,MathScores=91} },      new UserEntity{Name="張三",Age=24,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=82,MathScores=92} },      new UserEntity{Name="李四",Age=25,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=83,MathScores=93} },      new UserEntity{Name="王五",Age=26,Gender="Male",TranscriptsEn=new TranscriptsEntity{ChineseScores=84,MathScores=94} },    };     // 2.設定儲存格抬頭    // key:實體物件屬性名稱,可通過反射擷取值    // value:Excel列的名稱    Dictionary<string, string> cellheader = new Dictionary<string, string> {      { "Name", "姓名" },      { "Age", "年齡" },      { "GenderName", "性別" },      { "TranscriptsEn.ChineseScores", "語文成績" },      { "TranscriptsEn.MathScores", "數學成績" },    };     // 3.進行Excel轉換操作,並返迴轉換的檔案下載連結    string urlPath = ExcelHelper.EntityListToExcel2003(cellheader, enlist, "學產生績");    System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();    context.Response.ContentType = "text/plain";    context.Response.Write(js.Serialize(urlPath)); // 返回Json格式的內容  }  catch (Exception ex)  {    throw ex;  }} 

3.4 程式碼分析

核心代碼主要是cellheader與List<T>之間的映射關係:

四. 源碼下載
4.1 運行圖

源碼下載:http://xiazai.jb51.net/201605/yuanma/C

以上就是本文的全部內容,希望能夠對大家的學習有所協助。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.