diff --git a/src/Magicodes.ExporterAndImporter.Excel/ExcelImporter.cs b/src/Magicodes.ExporterAndImporter.Excel/ExcelImporter.cs
index d9049c61..fd10c792 100644
--- a/src/Magicodes.ExporterAndImporter.Excel/ExcelImporter.cs
+++ b/src/Magicodes.ExporterAndImporter.Excel/ExcelImporter.cs
@@ -15,6 +15,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Reflection;
using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Core.Models;
@@ -36,9 +37,39 @@ public class ExcelImporter : IExcelImporter
/// 文件名必须填写! - fileName
public Task GenerateTemplate(string fileName) where T : class, new()
{
- using (var importer = new ImportHelper())
+ var isMultipleSheetType = false;
+ var tableType = typeof(T);
+ List sheetPropertyList = new List();
+ var sheetProperties = tableType.GetProperties();
+
+ for (var i = 0; i < sheetProperties.Length; i++)
{
- return importer.GenerateTemplate(fileName);
+ var sheetProperty = sheetProperties[i];
+ var importerAttribute =
+ (sheetProperty.GetCustomAttributes(typeof(ExcelImporterAttribute), true) as ExcelImporterAttribute[])?.FirstOrDefault();
+ if (importerAttribute == null)
+ {
+ continue;
+ }
+ if (!string.IsNullOrEmpty(importerAttribute.SheetName))
+ {
+ isMultipleSheetType = true;
+ sheetPropertyList.Add(sheetProperty);
+ }
+ }
+
+ if (isMultipleSheetType)
+ {
+ using (var importer = new ImportMultipleSheetHelper(sheetPropertyList))
+ {
+ return importer.GenerateTemplate(fileName);
+ }
+ }
+ {
+ using (var importer = new ImportHelper())
+ {
+ return importer.GenerateTemplate(fileName);
+ }
}
}
@@ -49,9 +80,40 @@ public class ExcelImporter : IExcelImporter
/// 二进制字节
public Task GenerateTemplateBytes() where T : class, new()
{
- using (var importer = new ImportHelper())
+ var isMultipleSheetType = false;
+ var tableType = typeof(T);
+ List sheetPropertyList = new List();
+ var sheetProperties = tableType.GetProperties();
+
+ for (var i = 0; i < sheetProperties.Length; i++)
+ {
+ var sheetProperty = sheetProperties[i];
+ var importerAttribute =
+ (sheetProperty.GetCustomAttributes(typeof(ExcelImporterAttribute), true) as ExcelImporterAttribute[])?.FirstOrDefault();
+ if (importerAttribute == null)
+ {
+ continue;
+ }
+ if (!string.IsNullOrEmpty(importerAttribute.SheetName))
+ {
+ isMultipleSheetType = true;
+ sheetPropertyList.Add(sheetProperty);
+ }
+ }
+
+ if (isMultipleSheetType)
{
- return importer.GenerateTemplateByte();
+ using (var importer = new ImportMultipleSheetHelper(sheetPropertyList))
+ {
+ return importer.GenerateTemplateByte();
+ }
+ }
+ else
+ {
+ using (var importer = new ImportHelper())
+ {
+ return importer.GenerateTemplateByte();
+ }
}
}
@@ -216,5 +278,33 @@ public async Task>> ImportSameSheets
+ /// 判断Dto类型是否为多Sheet类
+ ///
+ /// Dto类型
+ ///
+ private bool DtoTypeIsMultipleSheet()
+ {
+ var tableType = typeof(T);
+ var sheetProperties = tableType.GetProperties();
+
+ for (var i = 0; i < sheetProperties.Length; i++)
+ {
+ var sheetProperty = sheetProperties[i];
+ var importerAttribute =
+ (sheetProperty.GetCustomAttributes(typeof(ExcelImporterAttribute), true) as ExcelImporterAttribute[])?.FirstOrDefault();
+ if (importerAttribute == null)
+ {
+ continue;
+ }
+ if (!string.IsNullOrEmpty(importerAttribute.SheetName))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/src/Magicodes.ExporterAndImporter.Excel/Utility/ImportMultipleSheetHelper.cs b/src/Magicodes.ExporterAndImporter.Excel/Utility/ImportMultipleSheetHelper.cs
index e1cf1405..f5fe1a09 100644
--- a/src/Magicodes.ExporterAndImporter.Excel/Utility/ImportMultipleSheetHelper.cs
+++ b/src/Magicodes.ExporterAndImporter.Excel/Utility/ImportMultipleSheetHelper.cs
@@ -29,6 +29,9 @@ public class ImportMultipleSheetHelper : IDisposable
private ExcelPackage _excelPackage;
+ private List _sheetPropertyList;
+
+
private ImportMultipleSheetHelper()
{
@@ -45,6 +48,15 @@ public ImportMultipleSheetHelper(string filePath)
_excelStream = new FileStream(FilePath, FileMode.Open);
}
+ ///
+ /// Sheet属性信息列表
+ ///
+ ///
+ public ImportMultipleSheetHelper(List sheetPropertyList)
+ {
+ _sheetPropertyList = sheetPropertyList;
+ }
+
///
/// 导入全局设置
///
@@ -464,53 +476,137 @@ protected virtual bool ParseImporterHeader()
}
///
- /// 构建Excel模板
+ /// 解析头部
///
- protected virtual void StructureExcel(ExcelPackage excelPackage)
+ ///
+ /// 导入实体没有定义ImporterHeader属性
+ protected virtual bool ParseImporterHeader(Type sheetType)
{
- var worksheet =
- excelPackage.Workbook.Worksheets.Add(_importDataType.GetDisplayName() ??
- ExcelImporterSettings.SheetName ?? "导入数据");
- if (!ParseImporterHeader()) return;
+ ImporterHeaderInfos = new List();
+ var objProperties = sheetType.GetProperties();
+ if (objProperties.Length == 0) return false;
- //设置列头
- for (var i = 0; i < ImporterHeaderInfos.Count; i++)
+ foreach (var propertyInfo in objProperties)
{
- //忽略
- if (ImporterHeaderInfos[i].Header.IsIgnore) continue;
-
- worksheet.Cells[ExcelImporterSettings.HeaderRowIndex, i + 1].Value =
- ImporterHeaderInfos[i].Header.Name;
- if (!string.IsNullOrWhiteSpace(ImporterHeaderInfos[i].Header.Description))
- worksheet.Cells[ExcelImporterSettings.HeaderRowIndex, i + 1].AddComment(
- ImporterHeaderInfos[i].Header.Description,
- ImporterHeaderInfos[i].Header.Author);
- //如果必填,则列头标红sd
- if (ImporterHeaderInfos[i].IsRequired)
- worksheet.Cells[ExcelImporterSettings.HeaderRowIndex, i + 1].Style.Font.Color.SetColor(Color.Red);
-
- if (ImporterHeaderInfos[i].MappingValues.Count > 0)
+ //TODO:简化并重构
+ //如果不设置,则自动使用默认定义
+ var importerHeaderAttribute =
+ (propertyInfo.GetCustomAttributes(typeof(ImporterHeaderAttribute), true) as
+ ImporterHeaderAttribute[])?.FirstOrDefault() ?? new ImporterHeaderAttribute
+ {
+ Name = propertyInfo.GetDisplayName() ?? propertyInfo.Name
+ };
+
+ if (string.IsNullOrWhiteSpace(importerHeaderAttribute.Name))
+ importerHeaderAttribute.Name = propertyInfo.GetDisplayName() ?? propertyInfo.Name;
+
+ //忽略字段处理
+ if (importerHeaderAttribute.IsIgnore) continue;
+
+ var colHeader = new ImporterHeaderInfo
+ {
+ IsRequired = propertyInfo.IsRequired(),
+ PropertyName = propertyInfo.Name,
+ Header = importerHeaderAttribute
+ };
+ ImporterHeaderInfos.Add(colHeader);
+
+ #region 处理值映射
+
+ var mappings = propertyInfo.GetAttributes().ToList();
+ foreach (var mappingAttribute in mappings.Where(mappingAttribute =>
+ !colHeader.MappingValues.ContainsKey(mappingAttribute.Text)))
+ colHeader.MappingValues.Add(mappingAttribute.Text, mappingAttribute.Value);
+
+ //如果存在自定义映射,则不会生成默认映射
+ if (mappings.Any()) continue;
+
+ //为bool类型生成默认映射
+ switch (propertyInfo.PropertyType.GetCSharpTypeName())
{
- //针对枚举类型和Bool类型添加数据约束
- var range = ExcelCellBase.GetAddress(ExcelImporterSettings.HeaderRowIndex + 1, i + 1,
- ExcelPackage.MaxRows, i + 1);
- var dataValidations = worksheet.DataValidations.AddListValidation(range);
- foreach (var mappingValue in ImporterHeaderInfos[i].MappingValues)
- dataValidations.Formula.Values.Add(mappingValue.Key);
+ case "Boolean":
+ case "Nullable":
+ {
+ if (!colHeader.MappingValues.ContainsKey("是")) colHeader.MappingValues.Add("是", true);
+ if (!colHeader.MappingValues.ContainsKey("否")) colHeader.MappingValues.Add("否", false);
+ break;
+ }
}
+
+ var type = propertyInfo.PropertyType;
+ var isNullable = type.IsNullable();
+ if (isNullable) type = type.GetNullableUnderlyingType();
+ //为枚举类型生成默认映射
+ if (type.IsEnum)
+ {
+ var values = type.GetEnumTextAndValues();
+ foreach (var value in values.Where(value => !colHeader.MappingValues.ContainsKey(value.Key)))
+ colHeader.MappingValues.Add(value.Key, value.Value);
+
+ if (isNullable)
+ if (!colHeader.MappingValues.ContainsKey(string.Empty))
+ colHeader.MappingValues.Add(string.Empty, null);
+ }
+
+ #endregion
}
- worksheet.Cells.AutoFitColumns();
- worksheet.Cells.Style.WrapText = true;
- worksheet.Cells[worksheet.Dimension.Address].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
- worksheet.Cells[worksheet.Dimension.Address].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
-
- worksheet.Cells[worksheet.Dimension.Address].Style.Border.Left.Style = ExcelBorderStyle.Thin;
- worksheet.Cells[worksheet.Dimension.Address].Style.Border.Right.Style = ExcelBorderStyle.Thin;
- worksheet.Cells[worksheet.Dimension.Address].Style.Border.Top.Style = ExcelBorderStyle.Thin;
- worksheet.Cells[worksheet.Dimension.Address].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
- worksheet.Cells[worksheet.Dimension.Address].Style.Fill.PatternType = ExcelFillStyle.Solid;
- worksheet.Cells[worksheet.Dimension.Address].Style.Fill.BackgroundColor.SetColor(Color.DarkSeaGreen);
+ return true;
+ }
+ ///
+ /// 构建Excel模板
+ ///
+ protected virtual void StructureExcel(ExcelPackage excelPackage)
+ {
+ foreach (var sheetProperty in _sheetPropertyList)
+ {
+ var sheetType= sheetProperty.PropertyType;
+ var importerAttribute =
+ (sheetProperty.GetCustomAttributes(typeof(ExcelImporterAttribute), true) as ExcelImporterAttribute[])?.FirstOrDefault();
+
+ var worksheet =
+ excelPackage.Workbook.Worksheets.Add(importerAttribute.SheetName);
+ if (!ParseImporterHeader(sheetType)) return;
+
+ //设置列头
+ for (var i = 0; i < ImporterHeaderInfos.Count; i++)
+ {
+ //忽略
+ if (ImporterHeaderInfos[i].Header.IsIgnore) continue;
+
+ worksheet.Cells[importerAttribute.HeaderRowIndex, i + 1].Value =
+ ImporterHeaderInfos[i].Header.Name;
+ if (!string.IsNullOrWhiteSpace(ImporterHeaderInfos[i].Header.Description))
+ worksheet.Cells[importerAttribute.HeaderRowIndex, i + 1].AddComment(
+ ImporterHeaderInfos[i].Header.Description,
+ ImporterHeaderInfos[i].Header.Author);
+ //如果必填,则列头标红
+ if (ImporterHeaderInfos[i].IsRequired)
+ worksheet.Cells[importerAttribute.HeaderRowIndex, i + 1].Style.Font.Color.SetColor(Color.Red);
+
+ if (ImporterHeaderInfos[i].MappingValues.Count > 0)
+ {
+ //针对枚举类型和Bool类型添加数据约束
+ var range = ExcelCellBase.GetAddress(importerAttribute.HeaderRowIndex + 1, i + 1,
+ ExcelPackage.MaxRows, i + 1);
+ var dataValidations = worksheet.DataValidations.AddListValidation(range);
+ foreach (var mappingValue in ImporterHeaderInfos[i].MappingValues)
+ dataValidations.Formula.Values.Add(mappingValue.Key);
+ }
+ }
+
+ worksheet.Cells.AutoFitColumns();
+ worksheet.Cells.Style.WrapText = true;
+ worksheet.Cells[worksheet.Dimension.Address].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
+ worksheet.Cells[worksheet.Dimension.Address].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
+
+ worksheet.Cells[worksheet.Dimension.Address].Style.Border.Left.Style = ExcelBorderStyle.Thin;
+ worksheet.Cells[worksheet.Dimension.Address].Style.Border.Right.Style = ExcelBorderStyle.Thin;
+ worksheet.Cells[worksheet.Dimension.Address].Style.Border.Top.Style = ExcelBorderStyle.Thin;
+ worksheet.Cells[worksheet.Dimension.Address].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
+ worksheet.Cells[worksheet.Dimension.Address].Style.Fill.PatternType = ExcelFillStyle.Solid;
+ worksheet.Cells[worksheet.Dimension.Address].Style.Fill.BackgroundColor.SetColor(Color.DarkSeaGreen);
+ }
}
///
diff --git a/src/Magicodes.ExporterAndImporter.Tests/ExcelImporterMultipleSheet_Tests.cs b/src/Magicodes.ExporterAndImporter.Tests/ExcelImporterMultipleSheet_Tests.cs
index 10679b8d..ab0f5282 100644
--- a/src/Magicodes.ExporterAndImporter.Tests/ExcelImporterMultipleSheet_Tests.cs
+++ b/src/Magicodes.ExporterAndImporter.Tests/ExcelImporterMultipleSheet_Tests.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -110,5 +111,26 @@ public async Task ClassStudentInfoImporter_SaveLabelingError_Test()
_testOutputHelper.WriteLine($"保存标注错误Excel文件已生成,路径:{labelingErrorExcelPath}");
}
}
+
+
+ [Fact(DisplayName = "多Sheet导出模板")]
+ public async Task MultipleSheetGenerateTemplate_Test()
+ {
+ var Importer = new ExcelImporter();
+ var bytes1 = await Importer.GenerateTemplateBytes();
+ var str1 = Convert.ToBase64String(bytes1);
+ _testOutputHelper.WriteLine($"已导出多Sheet的Excel模板,Base64:{str1}");
+ var tempaltePath2 = Path.Combine(Directory.GetCurrentDirectory(), "TestFiles", "Import", "学生基础数据及缴费流水号模板导出.xlsx");
+ await Importer.GenerateTemplate(tempaltePath2);
+
+ if (File.Exists(tempaltePath2))
+ {
+ _testOutputHelper.WriteLine($"已导出Excel模板,路径:{tempaltePath2}");
+ }
+ //一个Sheet导出
+ var bytes3 = await Importer.GenerateTemplateBytes();
+ var str3 = Convert.ToBase64String(bytes3);
+ _testOutputHelper.WriteLine($"已导出单个Sheet的Excel模板,Base64:{str3}");
+ }
}
}