.NET Core 使用NPOI讀取Excel返回泛型List集合

来源:https://www.cnblogs.com/itsvse/archive/2019/11/08/11821503.html

我是一名 ASP.NET 程式員,專註於 B/S 項目開發。累計文章閱讀量超過一千萬,我的博客主頁地址:https://www.itsvse.com/blog_xzz.html 網上有很多關於npoi讀取excel表格的例子,很多都是返回一個Datatable的對象,但是我需要的是一個list集合, ...


我是一名 ASP.NET 程式員,專註於 B/S 項目開發。累計文章閱讀量超過一千萬,我的博客主頁地址:https://www.itsvse.com/blog_xzz.html

 

網上有很多關於npoi讀取excel表格的例子,很多都是返回一個Datatable的對象,但是我需要的是一個list集合,這裡就需要把Datatable轉成自己需要的List集合,所以,我封裝了一個方法,傳入class對象就能返回相應的list對象。

首先先看效果圖,如下:

 

 

模板

一共有4列,有很多行,其中只有2行有數據,如下圖:

 

特性

首先,定義一個特性,意義是對象的屬性對應表格的哪一列,代碼如下:

public class ColumnAttribute: Attribute
    {
        public ColumnAttribute(int index)
        {
            Index = index;
        }
        public int Index { get; set; }
    }

  

對象模型

將表格數據讀取出來,轉換成相應的對象集合,在對象的屬性標註上面定義的特性,代碼如下:

public class TestModel
    {
        [Column(0)]
        public string Name { get; set; }
        [Column(1)]
        public string Url { get; set; }
        [Column(2)]
        public string Date { get; set; }
        [Column(3)]
        public string Remark { get; set; }
    }

  

封裝的方法

nuget安裝npoi:

Install-Package DotNetCore.NPOI -Version 1.2.2

代碼如下:

public class ExcelHelper
    {
        /// <summary>
        /// 讀取excel轉換成list集合
        /// </summary>
        /// <typeparam name="T">對象</typeparam>
        /// <param name="stream">文件流</param>
        /// <param name="startIndex">從第幾行開始讀取</param>
        /// <param name="sheetIndex">讀取第幾個sheet</param>
        /// <returns></returns>
        public static IList<T> GetList<T>(Stream stream, int startIndex, int sheetIndex = 0)
            where T : class
        {
            IList<T> ts = new List<T>();
            try
            {
                IWorkbook workbook = WorkbookFactory.Create(stream);
                var sheet = workbook.GetSheetAt(sheetIndex);
                if (sheet != null)
                {
                    IRow firstRow = sheet.GetRow(0);
                    //一行最後一個cell的編號 即總的列數
                    int cellCount = firstRow.LastCellNum;
                    //最後一列的標號
                    int rowCount = sheet.LastRowNum;
                    for (int i = startIndex; i <= rowCount; ++i)
                    {
                        //獲取行的數據
                        IRow row = sheet.GetRow(i);
                        if (row == null) continue; //沒有數據的行預設是null       
                        {
                            T model = Activator.CreateInstance<T>();
                            for (int j = row.FirstCellNum; j < cellCount; ++j)
                            {
                                if (row.GetCell(j) != null)
                                {
                                    var rowTemp = row.GetCell(j);
                                    string value = null;
                                    if (rowTemp.CellType == CellType.Numeric)
                                    {
                                        short format = rowTemp.CellStyle.DataFormat;
                                        if (format == 14 || format == 31 || format == 57 || format == 58 || format == 20)
                                            value = rowTemp.DateCellValue.ToString("yyyy-MM-dd");
                                        else
                                            value = rowTemp.NumericCellValue.ToString();
                                    }
                                    else
                                        value = rowTemp.ToString();
                                    //賦值
                                    foreach (System.Reflection.PropertyInfo item in typeof(T).GetProperties())
                                    {
                                        var column = item.GetCustomAttributes(true).First(x => x is ColumnAttribute) as ColumnAttribute;
                                        if (column.Index == j)
                                        {
                                            item.SetValue(model, value);
                                            break;
                                        }
                                    }
                                }
                            }
                            ts.Add(model);
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (stream != null) stream.Close();
            }
            return ts;
        }
    }

  

調用代碼:

static void Main(string[] args)
        {

            FileStream fs = new FileStream(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "/test.xlsx", FileMode.Open, FileAccess.Read);
            var temp = ExcelHelper.GetList<TestModel>(fs, 3);
            var json1 = Newtonsoft.Json.JsonConvert.SerializeObject(temp.Where(x => !string.IsNullOrWhiteSpace(x.Name)).ToList());
            Console.WriteLine(json1);
            Console.WriteLine("ok");
            Console.ReadKey();
        }

  最後,就出現了文章最開始的效果圖。

 

轉載於:https://down.itsvse.com/k/0tmhog.html


您的分享是我們最大的動力!

更多相關文章
  • 場景 DevExpress的TreeList怎樣設置數據源,從實例入手: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/102548490 滑鼠雙擊TreeList中的某一節點,在雙擊事件中怎樣獲取當前節點。 註: 博客主頁: h ...
  • 場景 在Winform中進行頁面設計時,常使用控制項的Dock屬性來進行佈局調整。但是由於設置屬性的順序問題,導致達不到想要的效果。 比如以下兩個控制項 下麵的控制項設置的Dock屬性是Bottom,即在頁面底部,那麼再設置上面的控制項的Dock屬性為Fill,理想效果是應該他們按當前佈局顯示在頁面上。但是 ...
  • 實現 該 敏感詞過濾 採用的是 DFA演算法,參考文章:https://blog.csdn.net/chenssy/article/details/26961957 具體 實現 步驟 如下: 第一步,構建 敏感詞庫(WordsLibrary) 類: using System.Collections.G ...
  • 還記得剛曾經因為導入導出不會做而發愁的自己嗎?我見過自己前同事因為一個導出改了好幾天,然後我們發現雖然有開源的庫但是用起來卻不得心應手,主要是因為百度使用方案的時候很多方案並不能解決問題。 尤其是嘗試新技術那些舊的操作還會有所改變,為了節約開發時間,我們把解決方案收入到一個個demo中,方便以後即拿 ...
  • using System; namespace ConsoleApp3 { class Program { static void Main(string[] args) { Console.Write("你要輸入多少項?"); int a = Convert.ToInt32(Console.Rea ...
一周排行
  • static void Main(string[] args) { string url = "https://go.microsoft.com/fwlink/?linkid=2108895&amp;clcid=0x409"; DownloadBigFile(new Uri(url), "ssms.... ...
  • 1. 使用ASP.NET Core 3.x 構建 RESTful API - 1.準備工作 什麼是REST 什麼是REST REST一詞最早是在2000年,由Roy Fielding在他的博士論文《Architectural Styles and the Design of Network-base ...
  • wpf 兩個自定義控制項 一個是IP控制項,一個滑動條。先看下效果圖 IPControl 1、實際工作中有時需要設置IP信息,就想著做一個ip控制項。效果沒有window自帶的好,需要通過tab切換。但也能滿足使用。廢話不多說直接上代碼 IPControl.xaml IPControl.xaml.cs 2 ...
  • 近期和幾位做嵌入式開發的朋友閑聊過程中,一位朋友抱怨到:這C#太難用了,我想在N個窗體(或者是N個用戶組件之間)傳遞值都搞不定,非得要定義一個全局變數來存儲,然後用定時器來刷新值,太Low了。我急切的回答道:這很簡單,不就是委托的事嘛。那你來一個示例啊:朋友道。此為這篇博客的起因,所以此篇博客對於有 ...
  • 在面對對象編程中,類的三大特性分別為封裝,繼承,多態。其中多態的具體實現,依賴於三個方法,也就是虛方法,抽象類和介面。 多態的具體作用是什麼呢?或者說多態的存在有什麼意義呢?多態的存在有效的降低了程式的耦合度,在使用的時候,不僅可以表現大家都有的共性,還能在必要的時候突出一些特殊的的個性。 那麼如何 ...
  • [toc] 前言 在之前已經提到過,公用類庫Util已經開源,目的一是為了簡化開發的工作量,畢竟有些常規的功能類庫重覆率還是挺高的,二是為了一起探討學習軟體開發,用的人越多問題也就會越多,解決的問題越多功能也就越完善, 倉庫地址: "April.Util_github" , "April.Util_ ...
  • 【ASP.NET Core學習】在ASP.NET Core 種使用Entity Framework Core介紹,包括如何添加Entity Framwork Core,創建模型和遷移到資料庫,查詢數據,保存數據,使用事務,處理併發衝突 ...
  • 環境:MacOS 10.13 MAMAP Prophp 7.0.33 + xdebugVisual Studio Code前言我所理解的 POP Chain:利用魔術方法並巧妙構造特殊屬性調用一系列函數或類方法以執行某種敏感操作的調用堆棧反序列化常用魔法函數前言我所理解的 POP Chain:利用魔 ...
  • 當創建隊列jobs、監聽器或訂閱伺服器以推送到隊列中時,您可能會開始認為,一旦分派,隊列工作器決定如何處理您的邏輯就完全由您自己決定了。 嗯……並不是說你不能從作業內部與隊列工作器交互,但是通常情況下,哪怕你做了,也是沒必要的。 這個神奇的騷操作的出現是因為“InteractsWithQueue”這 ...
  • 在說正題之前先解釋一下交換機模式是個籠統的稱呼,它不是一個單獨的模式(包括了訂閱模式,路由模式和主題模式),交換機模式是一個比較常用的模式,主要是為了實現數據的同步。 首先,說一下訂閱模式,就和字面上的意思差不多主要就是一個生產者,多個消費者,同一個消息被多個消費者獲取,先看一下官網的圖示 整體執行 ...
x