背景

框架:RuoYi-Net   Vue2 + Net6     

框架自带的导入模板下载功能。生成的模板,表头为字段名。对于用户来说不友好。因此,需要改进下,修改为中文表头,增加用户体验。

 java版本的前后端分离框架里,有实现我们想要的功能。参考java版本,对net版本的方法进行优化。

添加Excel 特性

在Infrastructure.Attribute 下新建ExcelAttribute.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Infrastructure.Attribute
{
    /// <summary>
    /// Excel注释
    /// </summary>
    public class ExcelAttribute : System.Attribute
    {
       
        public string Name { get; set; }

       
        public string readConverterExp { get; set; }
    }
}

实体加Excel特性

添加引用using Infrastructure.Attribute;  实体添加Excel 特性

模板列转换为中文名

1.ExcelHelper 添加转换方法

 添加一个静态方法,传入字段名,返回特性里的Name值

   /// <summary>
        /// 获取类里面字段别名
        /// </summary>
        /// <param name="columnname">字段名称</param>
        /// <returns></returns>
        public static string GetColumnAlias(string columnname)
        {
            string alias = "";

            PropertyInfo info = typeof(T).GetProperty(columnname);
            if (info != null)
            {
                ExcelAttribute excel = info.GetCustomAttribute<ExcelAttribute>();
                if (excel != null && !string.IsNullOrEmpty(excel.Name))
                {
                    alias = excel.Name;
                }
            }

            return alias;
        }

2.下载导入模板 调用转换方法

BaseController.DownloadImportTemplate

        /// <summary>
        /// 下载导入模板
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="stream"></param>
        /// <param name="fileName">下载文件名</param>
        /// <returns></returns>
        protected string DownloadImportTemplate<T>(List<T> list, Stream stream, string fileName) where T : class, new()
        {
            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.Style.ShrinkToFit = true;
                //全部字段导出
                worksheet.Cells.LoadFromCollection(list, true, OfficeOpenXml.Table.TableStyles.Light13);
                //替换别名
                foreach (var cell in worksheet.Cells)
                {
                    string cellname = cell.Text;
                   
                    string alias = ExcelHelper<T>.GetColumnAlias(cellname);
                     
                    if (!string.IsNullOrEmpty(alias))
                    {
                        cell.Value = alias;
                        
                    }
                }
                package.SaveAs(stream);
            }

            return sFileName;
        }

3.调试起来,重新下载用户的导入模板。可以看到对应的列已经显示为特性里配置的Name

 单元格值格式化(即匹配数据字典value值)

1.先在ExcelHelper 添加格式化的方法

        /// <summary>
        /// 匹配表达式的值
        /// </summary>
        /// <param name="ConverterExp">数据字典字符串</param>
        /// <param name="columnvalue">单元格的值</param>
        /// <returns></returns>
        public static string ConverterExpMap(string ConverterExp, string cellvalue)
        {
            string result = cellvalue;
            try
            { 
                string[] arr = ConverterExp.Split(',');
                for (int i = arr.Length - 1; i >= 0; i--)
                {
                    string[] explist = arr[i].Split('=');
                    //匹配到的话 就用新的值
                    if (explist[1].Trim().Equals(cellvalue))
                    {
                        result = explist[0];
                    }

                }
                return result;
            }
            catch (Exception)
            {
                return cellvalue;
            } 
        }
       

 2.修改MapPropertyInfo方法

原方法是按照列名(即字段名)匹配到实体。这里加上按照Excel特性里的Name属性进行匹配。

这样不影响框架里原有的导入功能。

  /// <summary>
        /// 查找Excel列名对应的实体属性
        /// </summary>
        /// <param name="columnName"></param>
        /// <returns></returns>
        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;
            }
            //excel特性的Name 匹配
            foreach (PropertyInfo item in propertyList)
            {
                if (item.GetCustomAttribute<ExcelAttribute>() == null)
                {
                    continue;
                }
                if (item.GetCustomAttribute<ExcelAttribute>().Name == columnName)
                {
                    return item;
                }
            }
            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;
        }

3.修改导入方法

dictHeader字典里存放的是表头列名及第几列。列名可能是中文名 也可能是英文名。因此,在获取单元格这里,列的位置需要分两种情况来获取。

 取到单元格后,当字段类型为字符串时,添加单元格值的转换。

  1. 取出字段的readConverterExp
  2. 调用转换方法得到值

 4.接下来,进行测试。模板里填写数据

 

 

 处理完成后,可以看到,实体的Sex属性值为0

Logo

快速构建 Web 应用程序

更多推荐