diff --git a/ZR.Admin.WebApi/Controllers/BaseController.cs b/ZR.Admin.WebApi/Controllers/BaseController.cs index b34e50e..6ee924d 100644 --- a/ZR.Admin.WebApi/Controllers/BaseController.cs +++ b/ZR.Admin.WebApi/Controllers/BaseController.cs @@ -1,7 +1,6 @@ using Infrastructure; using Infrastructure.Model; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -9,8 +8,6 @@ using OfficeOpenXml; using System; using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Reflection; using ZR.Admin.WebApi.Filters; namespace ZR.Admin.WebApi.Controllers @@ -134,5 +131,37 @@ namespace ZR.Admin.WebApi.Controllers return sFileName; } + + /// + /// 下载导入模板 + /// + /// + /// + /// + /// 下载文件名 + /// + protected string DownloadImportTemplate(List list, Stream stream, string fileName) + { + IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment)); + string sFileName = $"{fileName}模板.xlsx"; + string newFileName = Path.Combine(webHostEnvironment.WebRootPath, "importTemplate", sFileName); + //调试模式需要加上 + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + if (!Directory.Exists(newFileName)) + { + Directory.CreateDirectory(Path.GetDirectoryName(newFileName)); + } + using (ExcelPackage package = new(new FileInfo(newFileName))) + { + // 添加worksheet + ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(fileName); + + //全部字段导出 + worksheet.Cells.LoadFromCollection(list, true, OfficeOpenXml.Table.TableStyles.Light13); + package.SaveAs(stream); + } + + return sFileName; + } } } diff --git a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs index fd2242e..ff92959 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs @@ -1,6 +1,7 @@ using Infrastructure.Attribute; using Infrastructure.Enums; using Infrastructure.Model; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -8,7 +9,9 @@ using OfficeOpenXml; using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using ZR.Admin.WebApi.Filters; +using ZR.Common; using ZR.Model; using ZR.Model.System; using ZR.Service; @@ -170,43 +173,37 @@ namespace ZR.Admin.WebApi.Controllers.System return ToResponse(ToJson(result)); } - ///// - ///// 导入 ok - ///// - ///// 使用IFromFile必须使用name属性否则获取不到文件 - ///// - //[HttpPost("importData")] - //[Log(Title = "用户导入", BusinessType = BusinessType.IMPORT)] - //[ActionPermissionFilter(Permission = "system:user:import")] - //public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile) - //{ - // var mapper = new Mapper(formFile.OpenReadStream());// 从流获取 - // //读取的sheet信息 - // var rows = mapper.Take(0); - // foreach (var item in rows) - // { - // SysUser u = item.Value; - // } - // //TODO 业务逻辑 - // return SUCCESS(1); - //} + /// + /// 导入 + /// + /// 使用IFromFile必须使用name属性否则获取不到文件 + /// + [HttpPost("importData")] + [Log(Title = "用户导入", BusinessType = BusinessType.IMPORT)] + [ActionPermissionFilter(Permission = "system:user:import")] + public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile) + { + IEnumerable users = ExcelHelper.ImportData(formFile.OpenReadStream()); - ///// - ///// 用户模板 ok - ///// - ///// - //[HttpGet("importTemplate")] - //[Log(Title = "用户模板", BusinessType = BusinessType.EXPORT)] - //[ActionPermissionFilter(Permission = "system:user:export")] - //public IActionResult ImportTemplateExcel() - //{ - // List user = new List(); - // var mapper = new Mapper(); - // MemoryStream stream = new MemoryStream(); - // mapper.Save(stream, user, "sheel1", overwrite: true, xlsx: true); - // //Response.Headers.Append("content-disposition", "attachment;filename=sysUser.xlsx"); - // return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "sysUser.xlsx"); - //} + //TODO 业务逻辑,自行插入数据到db + return SUCCESS(users); + } + + /// + /// 用户导入模板下载 + /// + /// + [HttpGet("importTemplate")] + [Log(Title = "用户模板", BusinessType = BusinessType.EXPORT)] + [AllowAnonymous] + public IActionResult ImportTemplateExcel() + { + List user = new List(); + MemoryStream stream = new MemoryStream(); + + string sFileName = DownloadImportTemplate(user, stream, "用户列表"); + return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"{sFileName}"); + } /// /// 用户导出 diff --git a/ZR.Common/ExcelHelper.cs b/ZR.Common/ExcelHelper.cs new file mode 100644 index 0000000..d40a98a --- /dev/null +++ b/ZR.Common/ExcelHelper.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using OfficeOpenXml; +namespace ZR.Common +{ + public class ExcelHelper where T : new() + { + /// + /// 导入数据 + /// + /// + /// + public static IEnumerable ImportData(Stream stream) + { + using ExcelPackage package = new(stream); + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + ExcelWorksheet worksheet = package.Workbook.Worksheets[0];//读取第1个sheet + //获取表格的列数和行数 + + int colStart = worksheet.Dimension.Start.Column; + int colEnd = worksheet.Dimension.End.Column; + int rowStart = worksheet.Dimension.Start.Row; + int rowEnd = worksheet.Dimension.End.Row; + //int rowCount = worksheet.Dimension.Rows; + //int ColCount = worksheet.Dimension.Columns; + + List resultList = new(); + List propertyInfos = new();// new(typeof(T).GetProperties()); + Dictionary dictHeader = new(); + for (int i = colStart; i < colEnd; i++) + { + var name = worksheet.Cells[rowStart, i].Value.ToString(); + dictHeader[name] = i; + + PropertyInfo propertyInfo = MapPropertyInfo(name); + if (propertyInfo != null) + { + propertyInfos.Add(propertyInfo); + } + } + for (int row = rowStart + 1; row <= rowEnd; row++) + { + T result = new(); + + foreach (PropertyInfo p in propertyInfos) + { + try + { + ExcelRange cell = worksheet.Cells[row, dictHeader[p.Name]]; + if (cell.Value == null) + { + continue; + } + switch (p.PropertyType.Name.ToLower()) + { + case "string": + p.SetValue(result, cell.GetValue()); + break; + case "int16": + p.SetValue(result, cell.GetValue()); break; + case "int32": + p.SetValue(result, cell.GetValue()); break; + case "int64": + p.SetValue(result, cell.GetValue()); break; + case "decimal": + p.SetValue(result, cell.GetValue()); + break; + case "double": + p.SetValue(result, cell.GetValue()); break; + case "datetime": + p.SetValue(result, cell.GetValue()); break; + case "boolean": + p.SetValue(result, cell.GetValue()); break; + case "char": + p.SetValue(result, cell.GetValue()); break; + default: + break; + } + } + catch (KeyNotFoundException ex) + { + Console.WriteLine("未找到该列将继续循环," + ex.Message); + continue; + } + } + resultList.Add(result); + } + + return resultList; + } + + /// + /// 查找Excel列名对应的实体属性 + /// + /// + /// + public static PropertyInfo MapPropertyInfo(string columnName) + { + PropertyInfo[] propertyList = GetProperties(typeof(T)); + PropertyInfo propertyInfo = propertyList.Where(p => p.Name == columnName).FirstOrDefault(); + if (propertyInfo != null) + { + return propertyInfo; + } + else + { + foreach (PropertyInfo tempPropertyInfo in propertyList) + { + System.ComponentModel.DescriptionAttribute[] attributes = (System.ComponentModel.DescriptionAttribute[])tempPropertyInfo.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false); + if (attributes.Length > 0) + { + if (attributes[0].Description == columnName) + { + return tempPropertyInfo; + } + } + } + } + return null; + } + + /// + /// 得到类里面的属性集合 + /// + /// + /// + /// + public static PropertyInfo[] GetProperties(Type type, string[] columns = null) + { + PropertyInfo[] properties = null; + properties = type.GetProperties(); + + if (columns != null && columns.Length > 0) + { + // 按columns顺序返回属性 + var columnPropertyList = new List(); + foreach (var column in columns) + { + var columnProperty = properties.Where(p => p.Name == column).FirstOrDefault(); + if (columnProperty != null) + { + columnPropertyList.Add(columnProperty); + } + } + return columnPropertyList.ToArray(); + } + else + { + return properties; + } + } + } +} diff --git a/ZR.Vue/src/views/system/user/index.vue b/ZR.Vue/src/views/system/user/index.vue index 52b4239..30a4ea8 100644 --- a/ZR.Vue/src/views/system/user/index.vue +++ b/ZR.Vue/src/views/system/user/index.vue @@ -191,16 +191,13 @@ :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag> - - 将文件拖到此处,或 - 点击上传 - - - 是否更新已经存在的用户数据 - 下载模板 - - - 提示:仅允许导入“xls”或“xlsx”格式文件! + 将文件拖到此处,或点击上传 + + + 是否更新已经存在的用户数据 + + 仅允许导入xls、xlsx格式文件。 + 下载模板