基於NPOI的Excel導入導出類庫


概述

支持多sheet導入導出。導出字段過濾,合並行。特性配置導入驗證,非空驗證,唯一驗證,錯誤標注等

用於基礎配置和普通報表的導入導出,對於復雜需求,比如公式,導出圖片等暫不支持

GitHub地址:

https://github.com/Mike-Zrw/ExcelHelper/tree/master

導出配置支持

  • HeaderStyleAttribute :列名樣式,(顏色,字體,大小,加粗,對齊)
  • StringFormatterAttribute :格式化時間
  • ColumnWidthAttribute: 列寬,默認自適應,可通過這個特性配置最小列寬和最大列寬
  • RowMergedAttribute: 合並行,需要配合ExportPrimaryKey使用
  • ExportTitle:導出標題,標題可選,可設置居中,顏色字體等。
  • SheetName sheetName不設置默認為sheet1,sheet2等
  • FilterColumn :導出指定列。可根據選中的列名或者屬性名導出指定的列

導入配置支持

  • ColumnRegexAttribute:正則判斷,正則表達式判斷單元格內容
  • ColumnRequiredAttribute:非空判斷,對於不可為空的類型即使沒有設置該特性,仍會進行非空判斷,所以如果一個可以為空的int類型,請設置字段類型為int?
  • ColumnUniqueAttribute:唯一判斷,若不加此特性,默認對所有列進行重復驗證,可選擇性的加在某幾列上組合驗證。通過ImportSheet NeedUniqueValidation可配置是否開啟重復驗證,UniqueValidationPrompt設置重復時的提示
  • ImportSheet.ValidateHandler : 業務邏輯判斷,業務邏輯判斷在所有判斷之后執行,可以通過IsValidated屬性判斷該行是否通過了其他驗證,SetError()用來追加單元格的錯誤提示
  • HeaderRowIndex:列名所在行
  • ImportBook.DataErrorForegroundColor: 錯誤前景色(紅)
  • ImportBook.RepeatedErrorForegroundColor: 重復前景色(黃)
  • ImportBook.DefaultForegroundColor: 默認前景色(白),在驗證未通過時,顏色處於錯誤或重復但驗證通過的單元格顏色將重置為默認前景色。(即第一次導入錯誤,修改之后第二次部分導入正確,則正確的顏色會便會默認前景色)

導入結果說明

  • ImportSuccess :是否導入成功
  • GetSummaryErrorMessage() : excel中的所有錯誤文字展示
  • GetNotDisplayErrorMessage(): 無法在excel中標注的錯誤信息,比如sheet格式不正確,excel格式不正確等
  • outPutStream: 錯誤的單元格添加樣式及標注輸出到文件流中。如果不需要輸出excel流,該參數可不傳。

導出示例

 		var students = new List<ExportStudent>();
        var grades = new List<ExportGrade>();
        var schools = new List<ExportSchool>();
        for (int i = 0; i < 100; i++)
        {
            students.Add(new ExportStudent
            {
                Name = i % 6 == 1 ? null : ($"name{i}"),
                Age = i,
                Phone = i % 8 == 1 ? "adsf123" : $"{1}{new Random().Next(100, 999)}{1}{new Random().Next(100, 999)}{2}{new Random().Next(0, 9)}{3}",
                Birthday = i % 13 == 1 ? default(DateTime?) : DateTime.Now.AddDays(i),
                Money = Math.Round(new Random(i).NextDouble(), 2),
                SchoolDate = DateTime.Now.AddDays(i + 1),
            });
            grades.Add(new ExportGrade { Code = $"編碼{i}", GradeName = $"{i}年級" });
            schools.Add(new ExportSchool { Name = $"{i}號學校", Address = $"學校地址{i}", Price = Math.Round(new Random().NextDouble(), 2) });
        }
        var exporter = new DefaultExcelExporter();

        var stream = new FileStream("D://export.xlsx", FileMode.Create, FileAccess.Write);
        //var stream = new MemoryStream();
        exporter.Export(new ExportBook()
        {
            Ext =ExtEnum.XLSX,
            Sheets = new List<ExportSheet> {
            new ExportSheet(){  SheetName="測試", Data=students},
            new ExportSheet(){   Data=grades},
            new ExportSheet(){   Data=schools,Title=new  ExportTitle("學校列表",true,18,default,Excel.Enums.HorizontalAlignEnum.Center),  FilterColumn=new List<string>(){ "學校名稱","price" } },
            }
        }, stream);

        stream.Dispose();
		
		public class ExportStudent : ExportModel
        {
            [ColumnNameAttribute("名字")]
            public string Name { get; set; }
            [ColumnNameAttribute("年齡")]
            public int Age { get; set; }

            [ColumnNameAttribute("生日")]
            [StringFormatter("yyyy-MM-dd HH:mm:ss")]
            public DateTime? Birthday { get; set; }

            [ColumnStyle(FontName = "華文彩雲")]
            [ColumnNameAttribute("入學時間")]
            [StringFormatter("yyyy-MM-dd")]
            public DateTime SchoolDate { get; set; }

            [ColumnStyle(FontColor = 211, IsBold = true)]
            [ColumnNameAttribute("零花錢")]
            public double Money { get; set; }

            [ColumnNameAttribute("電話")]
            public string Phone { get; set; }
        }

合並行導出示例

  public void ExportMergeRow()
    {
        var orders = new List<Order>();
        for (int i = 0; i < 100; i++)
        {
            var index = new Random(i).Next(i + 10, i + 13);
            var orderNumber = $"訂單{index}";
            orders.Add(new Order()
            {
                Buyer = $"下單人{index}",
                Price = Math.Round(new Random(i).NextDouble(), 2),
                BuyQty = new Random(i).Next(1, 10),
                ProductName = $"商品{i}",
                OrderNumber = orderNumber,
                OrderNum2 = orderNumber,
                ExportPrimaryKey = orderNumber
            });
        }
        var exporter = new DefaultExcelExporter();

        var stream = new FileStream("D://exportorder.xlsx", FileMode.Create, FileAccess.Write);
        exporter.Export(new ExportBook()
        {
            Ext = ExtEnum.XLSX,
            Sheets = new List<ExportSheet> { new ExportSheet() { SheetName = "訂單列表", Data = orders } }
        }, stream);

        stream.Dispose();
    }

導入示例

		var sheet1 = new ImportSheet<ImportStudent>
        {
            UniqueValidationPrompt = "零花錢不可重復",
            HeaderRowIndex = 0,
            SheetIndex = 0,
            ValidateHandler = (list) =>
            {
                foreach (ImportStudent model in list)
                {
                    if (model.IsValidated && model.Name == "name0")
                        model.SetError(nameof(model.Name), "名字不可為0");
                    if (model.IsValidated && model.Money < 0.5)
                        model.SetError(nameof(model.Money), "零花錢不可小於0.5");
                }
            }
        };
        var sheet2 = new ImportSheet<ImportGrade>
        {
            HeaderRowIndex = 0,
            SheetIndex = 1
        };
        var sheet3 = new ImportSheet<ImportSchool>
        {
            HeaderRowIndex = 1,
            SheetIndex = 2,
            ValidateHandler = (list) =>
            {

                foreach (var model in list)
                {
                    if (model.Price > 0.5)
                        model.SetError(nameof(model.Price), "學費不可大於0.5");
                }
            }
        };
        var import = new DefaultExcelImporter();
        using var inputStrem = new FileStream("D://export.xlsx", FileMode.OpenOrCreate, FileAccess.Read);
        using var outStrem = new FileStream("D://error.xlsx", FileMode.Create, FileAccess.Write);
        var bookmodel = new ImportBook();
        bookmodel.SetSheetModels(sheet1, sheet2, sheet3);
        var ret = import.ImportExcel(inputStrem, ExtEnum.XLSX, bookmodel, outStrem);
        var success = ret.ImportSuccess;
        var summaryErrorMsg = ret.GetSummaryErrorMessage();
        var notDisplayMsg = ret.GetNotDisplayErrorMessage();
        Output.WriteLine($"success:{success}");
        Output.WriteLine("summaryErrorMsg------------");
        Output.WriteLine(summaryErrorMsg);
        Output.WriteLine("notDisplayMsg------------");
        Output.WriteLine(notDisplayMsg);

		public class ImportStudent : ImportModel
	    {
	        [ColumnRequired("名字必填")]
	        [ColumnNameAttribute("名字")]
	        public string Name { get; set; }
	        [ColumnNameAttribute("年齡")]
	        public int Age { get; set; }
	
	        [ColumnRequired]
	        [ColumnNameAttribute("生日")]
	        public DateTime Birthday { get; set; }
	
	        [ColumnNameAttribute("入學時間")]
	        public DateTime SchoolDate { get; set; }
	
	        [ColumnUnique]
	        [ColumnNameAttribute("零花錢")]
	        public double Money { get; set; }
	
	        [ColumnNameAttribute("電話")]
	        [ColumnRegex(@"^[1]+[1-9]+\d{9}$", "電話格式不對")]
	        public string Phone { get; set; }
	    }

導出結果展示:

導入結果展示:



測試輸出


免責聲明!

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



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