1122 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			1122 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C#
		
	
	
using DocumentFormat.OpenXml.Spreadsheet;
 | 
						||
using DocumentFormat.OpenXml.Wordprocessing;
 | 
						||
using IRaCIS.Application.Contracts;
 | 
						||
using IRaCIS.Application.Interfaces;
 | 
						||
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
 | 
						||
using IRaCIS.Core.Application.Helper;
 | 
						||
using IRaCIS.Core.Domain.Share;
 | 
						||
using Microsoft.AspNetCore.Hosting;
 | 
						||
using Microsoft.AspNetCore.Mvc;
 | 
						||
using Microsoft.Extensions.Hosting;
 | 
						||
using MiniExcelLibs;
 | 
						||
using MiniExcelLibs.OpenXml;
 | 
						||
using NPOI.HSSF.UserModel;
 | 
						||
using NPOI.SS.Formula.Functions;
 | 
						||
using NPOI.SS.UserModel;
 | 
						||
using NPOI.XSSF.UserModel;
 | 
						||
using System.Collections;
 | 
						||
using System.Globalization;
 | 
						||
using Xceed.Document.NET;
 | 
						||
 | 
						||
namespace IRaCIS.Core.Application.Service;
 | 
						||
 | 
						||
public static class ExcelExportHelper
 | 
						||
{
 | 
						||
    //MiniExcel_Export
 | 
						||
    /// <summary>
 | 
						||
    /// 
 | 
						||
    /// </summary>
 | 
						||
    /// <param name="code"></param>
 | 
						||
    /// <param name="data"></param>
 | 
						||
    /// <param name="exportFileNamePrefix">文件名前缀</param>
 | 
						||
    /// <param name="_commonDocumentRepository"></param>
 | 
						||
    /// <param name="_hostEnvironment"></param>
 | 
						||
    /// <param name="_dictionaryService"></param>
 | 
						||
    /// <param name="translateType"></param>
 | 
						||
    /// <param name="criterionType"></param>
 | 
						||
    /// <returns></returns>
 | 
						||
    public static async Task<IActionResult> DataExportAsync(string code, ExcelExportInfo data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null)
 | 
						||
    {
 | 
						||
        var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
 | 
						||
 | 
						||
        //判断是否有字典翻译
 | 
						||
        object translateData = data;
 | 
						||
 | 
						||
        if (_dictionaryService != null && translateType != null)
 | 
						||
        {
 | 
						||
            //一个值 对应不同的字典翻译
 | 
						||
            var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
 | 
						||
                .SelectMany(c =>
 | 
						||
                c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false).Select(f => (DictionaryTranslateAttribute?)f).Where(t => t?.CriterionType == criterionType || t?.CriterionType == null)
 | 
						||
                .Select(k => new { c.Name, k.DicParentCode, k.IsTranslateDenpendOtherProperty, k.DependPropertyName, k.DependPropertyValueStr })
 | 
						||
                ).ToList();
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            //字典表查询出所有需要翻译的数据
 | 
						||
 | 
						||
            var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
 | 
						||
 | 
						||
 | 
						||
            var dic = data.ConvertToDictionary();
 | 
						||
 | 
						||
 | 
						||
            foreach (var key in dic.Keys)
 | 
						||
            {
 | 
						||
                //是数组 那么找到对应的属性 进行翻译
 | 
						||
                if (dic[key] != null && dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
 | 
						||
                {
 | 
						||
 | 
						||
                    var newObjList = new List<object>();
 | 
						||
                    var no = 1;
 | 
						||
 | 
						||
                    foreach (var item in dic[key] as IList)
 | 
						||
                    {
 | 
						||
                        var itemDic = item.ConvertToDictionary();
 | 
						||
 | 
						||
                        ////处理集合里面时间类型,根据当前语言将时间转变为字符串
 | 
						||
                        //foreach (var itemValuePair in itemDic)
 | 
						||
                        //{
 | 
						||
                        //    // 临床数据 1,1 会变成2024-01-01
 | 
						||
                        //    if (itemValuePair.Value?.ToString().Length > 8 && DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result))
 | 
						||
                        //    {
 | 
						||
                        //        itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result);
 | 
						||
                        //    }
 | 
						||
                        //}
 | 
						||
 | 
						||
 | 
						||
                        foreach (var needTranslateProperty in needTranslatePropertyList)
 | 
						||
                        {
 | 
						||
                            if (itemDic.Keys.Any(t => t == needTranslateProperty.Name))
 | 
						||
                            {
 | 
						||
                                //翻译的属性依赖其他属性
 | 
						||
                                if (needTranslateProperty.IsTranslateDenpendOtherProperty)
 | 
						||
                                {
 | 
						||
                                    if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
 | 
						||
                                    {
 | 
						||
                                        var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
 | 
						||
 | 
						||
                                        itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
 | 
						||
                                    }
 | 
						||
                                }
 | 
						||
                                //普通翻译 或者某一标准翻译
 | 
						||
                                else
 | 
						||
                                {
 | 
						||
                                    var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
 | 
						||
 | 
						||
 | 
						||
                                    itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
 | 
						||
                                }
 | 
						||
                            }
 | 
						||
                        }
 | 
						||
 | 
						||
                        itemDic.Add("No", no++);
 | 
						||
 | 
						||
 | 
						||
                        newObjList.Add(itemDic);
 | 
						||
                    }
 | 
						||
 | 
						||
                    dic[key] = newObjList;
 | 
						||
 | 
						||
                }
 | 
						||
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
            //data = dic;
 | 
						||
 | 
						||
            translateData = dic;
 | 
						||
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
 | 
						||
 | 
						||
 | 
						||
        //模板路径
 | 
						||
        var tplPath = physicalPath;
 | 
						||
 | 
						||
        #region 根据中英文  删除模板sheet
 | 
						||
 | 
						||
        // 打开模板文件
 | 
						||
        var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
 | 
						||
 | 
						||
        // 获取文件流
 | 
						||
        var templateStream = new MemoryStream();
 | 
						||
        templateFile.CopyTo(templateStream);
 | 
						||
        templateStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
        var workbook = new XSSFWorkbook(templateStream);
 | 
						||
 | 
						||
        int sheetCount = workbook.NumberOfSheets;
 | 
						||
 | 
						||
        if (sheetCount == 2)
 | 
						||
        {
 | 
						||
            if (isEn_US)
 | 
						||
            {
 | 
						||
                workbook.RemoveSheetAt(0);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                workbook.RemoveSheetAt(1);
 | 
						||
            }
 | 
						||
 | 
						||
            //中文替换项目术语
 | 
						||
            if (data.TrialObjectNameList?.Count > 0)
 | 
						||
            {
 | 
						||
                var replaceObjectList = data.TrialObjectNameList;
 | 
						||
 | 
						||
                var sheet = workbook.GetSheetAt(0);
 | 
						||
 | 
						||
                int rowCount = sheet.PhysicalNumberOfRows;
 | 
						||
 | 
						||
                for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
 | 
						||
                {
 | 
						||
                    var row = sheet.GetRow(rowIndex);
 | 
						||
 | 
						||
                    if (row != null)
 | 
						||
                    {
 | 
						||
 | 
						||
                        var colums = row.LastCellNum;
 | 
						||
 | 
						||
                        for (int colIndex = 0; colIndex < colums; colIndex++)
 | 
						||
                        {
 | 
						||
                            var cell = row.GetCell(colIndex);
 | 
						||
 | 
						||
                            // 只处理字符串类型的单元格
 | 
						||
                            if (cell != null)
 | 
						||
                            {
 | 
						||
                                var cellValue = cell.StringCellValue;
 | 
						||
 | 
						||
                                var find = replaceObjectList.FirstOrDefault(t => t.Name == cellValue);
 | 
						||
                                if (find != null)
 | 
						||
                                {
 | 
						||
                                    cell.SetCellValue(find.TrialName);
 | 
						||
                                }
 | 
						||
                            }
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
            using (var memoryStream2 = new MemoryStream())
 | 
						||
            {
 | 
						||
                workbook.Write(memoryStream2, true);
 | 
						||
 | 
						||
                memoryStream2.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
                templateStream = memoryStream2;
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        // 文件名称 从sheet里面取
 | 
						||
        //fileNmae = workbook.GetSheetName(0);
 | 
						||
        #endregion
 | 
						||
 | 
						||
        #region MiniExcel
 | 
						||
 | 
						||
        var memoryStream = new MemoryStream();
 | 
						||
 | 
						||
        var config = new OpenXmlConfiguration()
 | 
						||
        {
 | 
						||
            IgnoreTemplateParameterMissing = true,
 | 
						||
        };
 | 
						||
 | 
						||
        await MiniExcel.SaveAsByTemplateAsync(memoryStream, templateStream.ToArray(), translateData, config);
 | 
						||
 | 
						||
        memoryStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
 | 
						||
        return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
 | 
						||
        {
 | 
						||
            FileDownloadName = $"{(string.IsNullOrEmpty(exportFileNamePrefix) ? "" : exportFileNamePrefix + "_")}{Path.GetFileNameWithoutExtension(fileName)}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
 | 
						||
        };
 | 
						||
 | 
						||
        #endregion
 | 
						||
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public class DynamicColumnConfig
 | 
						||
    {
 | 
						||
        /// <summary>
 | 
						||
        /// 增加动态列开始索引  从0 开始算 
 | 
						||
        /// </summary>
 | 
						||
        public int AutoColumnStartIndex { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 动态列开始的行index 从0开始
 | 
						||
        /// </summary>
 | 
						||
        public int AutoColumnTitleRowIndex { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 模板列最后的索引
 | 
						||
        /// </summary>
 | 
						||
        public int TempalteLastColumnIndex { get; set; }
 | 
						||
 | 
						||
        public bool IsCDISCExport { get; set; } = false;
 | 
						||
 | 
						||
        //public List<string> CDISCList { get; set; } = new List<string>();
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 动态的列名  如果Id 重复,那么就按照名称填充,否则就按照Id 填充列数据
 | 
						||
        /// </summary>
 | 
						||
        public List<ColumItem> ColumnIdNameList { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 动态翻译的字典名
 | 
						||
        /// </summary>
 | 
						||
        public List<string> TranslateDicNameList { get; set; } = new List<string>();
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 动态取数据的集合名
 | 
						||
        /// </summary>
 | 
						||
        public string DynamicListName { get; set; }
 | 
						||
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 动态数据翻译的取字典的属性名
 | 
						||
        /// </summary>
 | 
						||
        public string DynamicItemDicName { get; set; }
 | 
						||
        /// <summary>
 | 
						||
        /// 取值的属性名
 | 
						||
        /// </summary>
 | 
						||
        public string DynamicItemValueName { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// Excel Title Name
 | 
						||
        /// </summary>
 | 
						||
        public string DynamicItemTitleName { get; set; }
 | 
						||
 | 
						||
        public string DynamicItemTitleId { get; set; }
 | 
						||
 | 
						||
        public List<int> RemoveColunmIndexList { get; set; } = new List<int>();
 | 
						||
 | 
						||
        public class ColumItem
 | 
						||
        {
 | 
						||
            public Guid Id { get; set; }
 | 
						||
            public string Name { get; set; }
 | 
						||
 | 
						||
            public string CDISCCode { get; set; }
 | 
						||
 | 
						||
            public override bool Equals(object obj)
 | 
						||
            {
 | 
						||
                if (obj is not ColumItem other) return false;
 | 
						||
                return Id == other.Id && Name == other.Name;
 | 
						||
            }
 | 
						||
 | 
						||
            public override int GetHashCode()
 | 
						||
            {
 | 
						||
                return HashCode.Combine(Id, Name);
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        public List<string> ColumnIdList => ColumnIdNameList == null ? new List<string>() : ColumnIdNameList.Select(t => t.Id.ToString()).ToList();
 | 
						||
        public List<string> ColumnNameList => ColumnIdNameList == null ? new List<string>() : ColumnIdNameList.Select(t => t.Name).ToList();
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    public static async Task<(MemoryStream, string)> DataExport_NpoiTestAsync(string code, ExcelExportInfo data, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null, DynamicColumnConfig? dynamicColumnConfig = null)
 | 
						||
    {
 | 
						||
        var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
 | 
						||
        //判断是否有字典翻译
 | 
						||
 | 
						||
        object translateData = data;
 | 
						||
 | 
						||
        Dictionary<string, object> translatedDic = default;
 | 
						||
 | 
						||
        if (_dictionaryService != null && translateType != null)
 | 
						||
        {
 | 
						||
 | 
						||
            //一个值 对应不同的字典翻译
 | 
						||
            var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
 | 
						||
                .SelectMany(c =>
 | 
						||
                c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false).Select(f => (DictionaryTranslateAttribute?)f).Where(t => t.CriterionType == criterionType || t.CriterionType == null)
 | 
						||
                .Select(k => new { c.Name, k.DicParentCode, k.IsTranslateDenpendOtherProperty, k.DependPropertyName, k.DependPropertyValueStr })
 | 
						||
                ).ToList();
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            //字典表查询出所有需要翻译的数据
 | 
						||
 | 
						||
            var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
 | 
						||
 | 
						||
            var dic = data.ConvertToDictionary();
 | 
						||
            //var dic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull())).IfNullThrowException();
 | 
						||
 | 
						||
            foreach (var key in dic.Keys)
 | 
						||
            {
 | 
						||
                //是数组 那么找到对应的属性 进行翻译
 | 
						||
                if (dic[key] != null && dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
 | 
						||
                //if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
 | 
						||
                {
 | 
						||
 | 
						||
                    var newObjList = new List<object>();
 | 
						||
                    var no = 1;
 | 
						||
                    foreach (var item in dic[key] as IList)
 | 
						||
                    //foreach (var item in dic[key] as JArray)
 | 
						||
                    {
 | 
						||
                        //var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
 | 
						||
                        var itemDic = item.ConvertToDictionary();
 | 
						||
 | 
						||
                        ////处理集合里面时间类型,根据当前语言将时间转变为字符串
 | 
						||
                        //foreach (var itemValuePair in itemDic)
 | 
						||
                        //{
 | 
						||
                        //    if (itemValuePair.Value?.ToString().Length > 8 && DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result))
 | 
						||
                        //    {
 | 
						||
                        //        itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result);
 | 
						||
                        //    }
 | 
						||
                        //}
 | 
						||
 | 
						||
                        foreach (var needTranslateProperty in needTranslatePropertyList)
 | 
						||
                        {
 | 
						||
                            if (itemDic.Keys.Any(t => t == needTranslateProperty.Name))
 | 
						||
                            {
 | 
						||
                                //翻译的属性依赖其他属性
 | 
						||
                                if (needTranslateProperty.IsTranslateDenpendOtherProperty)
 | 
						||
                                {
 | 
						||
                                    if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
 | 
						||
                                    {
 | 
						||
                                        var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
 | 
						||
 | 
						||
                                        itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
 | 
						||
                                    }
 | 
						||
                                }
 | 
						||
                                //普通翻译 或者某一标准翻译
 | 
						||
                                else
 | 
						||
                                {
 | 
						||
                                    var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
 | 
						||
 | 
						||
 | 
						||
                                    itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
 | 
						||
                                }
 | 
						||
                            }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                        }
 | 
						||
 | 
						||
                        itemDic.Add("No", no++);
 | 
						||
                        newObjList.Add(itemDic);
 | 
						||
                    }
 | 
						||
 | 
						||
                    dic[key] = newObjList;
 | 
						||
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
            //data = dic;
 | 
						||
            translateData = dic;
 | 
						||
            translatedDic = dic;
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
 | 
						||
 | 
						||
 | 
						||
        //模板路径
 | 
						||
        var tplPath = physicalPath;
 | 
						||
 | 
						||
        #region 根据中英文  删除模板sheet
 | 
						||
 | 
						||
        // 打开模板文件
 | 
						||
        var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
 | 
						||
 | 
						||
        // 获取文件流
 | 
						||
        var templateStream = new MemoryStream();
 | 
						||
        templateFile.CopyTo(templateStream);
 | 
						||
        templateStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
        var workbook = new XSSFWorkbook(templateStream);
 | 
						||
 | 
						||
        int sheetCount = workbook.NumberOfSheets;
 | 
						||
 | 
						||
        if (sheetCount == 2)
 | 
						||
        {
 | 
						||
            if (isEn_US)
 | 
						||
            {
 | 
						||
                workbook.RemoveSheetAt(0);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                workbook.RemoveSheetAt(1);
 | 
						||
            }
 | 
						||
 | 
						||
            #region 中文替换项目术语
 | 
						||
            if (data.TrialObjectNameList?.Count > 0)
 | 
						||
            {
 | 
						||
                var replaceObjectList = data.TrialObjectNameList;
 | 
						||
 | 
						||
                var sheet = workbook.GetSheetAt(0);
 | 
						||
 | 
						||
                int rowCount = sheet.PhysicalNumberOfRows;
 | 
						||
 | 
						||
                for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
 | 
						||
                {
 | 
						||
                    var row = sheet.GetRow(rowIndex);
 | 
						||
                    if (row != null)
 | 
						||
                    {
 | 
						||
 | 
						||
                        var colums = row.LastCellNum;
 | 
						||
 | 
						||
                        for (int colIndex = 0; colIndex < colums; colIndex++)
 | 
						||
                        {
 | 
						||
                            var cell = row.GetCell(colIndex);
 | 
						||
 | 
						||
                            // 只处理字符串类型的单元格
 | 
						||
                            if (cell != null)
 | 
						||
                            {
 | 
						||
                                var cellValue = cell.StringCellValue;
 | 
						||
 | 
						||
                                var find = replaceObjectList.FirstOrDefault(t => t.Name == cellValue);
 | 
						||
                                if (find != null)
 | 
						||
                                {
 | 
						||
                                    cell.SetCellValue(find.TrialName);
 | 
						||
                                }
 | 
						||
                            }
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                }
 | 
						||
            }
 | 
						||
            #endregion
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            if (dynamicColumnConfig != null)
 | 
						||
            {
 | 
						||
                //var isCdics = dynamicColumnConfig.CDISCList.Count > 0;
 | 
						||
 | 
						||
                var isCdics = dynamicColumnConfig.IsCDISCExport;
 | 
						||
 | 
						||
                var sheet = workbook.GetSheetAt(0);
 | 
						||
 | 
						||
                var cdicsRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex - 1);
 | 
						||
                var titelRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex);
 | 
						||
                var templateRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex + 1);
 | 
						||
 | 
						||
                //动态移除列的数量
 | 
						||
                var dynamicRemoveColunmCount = dynamicColumnConfig.RemoveColunmIndexList.Count();
 | 
						||
 | 
						||
                //在动态列开始前移除的数量
 | 
						||
                var beforeDynamicRemoveCount = dynamicColumnConfig.RemoveColunmIndexList.Where(t => t < dynamicColumnConfig.AutoColumnStartIndex).Count();
 | 
						||
 | 
						||
                //动态添加列的数量
 | 
						||
                var needAddCount = dynamicColumnConfig.ColumnIdNameList.Count;
 | 
						||
 | 
						||
                //原始表  最终索引
 | 
						||
                var originTotalEndIndex = dynamicColumnConfig.TempalteLastColumnIndex;
 | 
						||
 | 
						||
                //减去动态移除后原始结束索引
 | 
						||
                var originRemoveEndIndex = originTotalEndIndex - dynamicRemoveColunmCount;
 | 
						||
 | 
						||
                //最终表 动态列开始索引
 | 
						||
                var dynamicColunmStartIndex = dynamicColumnConfig.AutoColumnStartIndex - beforeDynamicRemoveCount;
 | 
						||
 | 
						||
                //最终表 动态列的终止索引
 | 
						||
                var dynamicColunmEndIndex = dynamicColunmStartIndex + needAddCount - 1;
 | 
						||
 | 
						||
                //最终表  最终索引
 | 
						||
                var totalColunmEndIndex = originTotalEndIndex + needAddCount - dynamicRemoveColunmCount;
 | 
						||
 | 
						||
 | 
						||
                //动态列后需要移动的数量
 | 
						||
                var backMoveCount = totalColunmEndIndex - dynamicColunmEndIndex;
 | 
						||
 | 
						||
                //删除需要动态删除的列  从大到小移除,否则索引会变
 | 
						||
                foreach (var removeIndex in dynamicColumnConfig.RemoveColunmIndexList.OrderByDescending(t => t))
 | 
						||
                {
 | 
						||
                    //将后面的列向前移动
 | 
						||
                    for (var i = 0; i < originTotalEndIndex - removeIndex; i++)
 | 
						||
                    {
 | 
						||
                        Console.WriteLine(titelRow.GetCell(removeIndex + i + 1).StringCellValue);
 | 
						||
                        titelRow.GetCell(removeIndex + i).SetCellValue(titelRow.GetCell(removeIndex + i + 1).StringCellValue);
 | 
						||
                        templateRow.GetCell(removeIndex + i).SetCellValue(templateRow.GetCell(removeIndex + i + 1).StringCellValue);
 | 
						||
 | 
						||
                        //后面的数据要清空
 | 
						||
                        titelRow.GetCell(removeIndex + i + 1).SetCellValue("");
 | 
						||
                        templateRow.GetCell(removeIndex + i + 1).SetCellValue("");
 | 
						||
 | 
						||
                    }
 | 
						||
 | 
						||
                }
 | 
						||
 | 
						||
                //创建新的列
 | 
						||
                for (int i = originRemoveEndIndex; i < originRemoveEndIndex + needAddCount; i++)
 | 
						||
                {
 | 
						||
 | 
						||
                    titelRow.CreateCell(i + 1);
 | 
						||
                    templateRow.CreateCell(i + 1);
 | 
						||
 | 
						||
                    if (isCdics)
 | 
						||
                    {
 | 
						||
                        cdicsRow.CreateCell(i + 1);
 | 
						||
                    }
 | 
						||
                }
 | 
						||
                //移动Title 和下面的模板标识
 | 
						||
 | 
						||
                var gap = totalColunmEndIndex - originRemoveEndIndex;
 | 
						||
 | 
						||
                for (int i = totalColunmEndIndex; i > dynamicColunmEndIndex; i--)
 | 
						||
                {
 | 
						||
 | 
						||
                    titelRow.GetCell(i).SetCellValue(titelRow.GetCell(i - gap).StringCellValue);
 | 
						||
 | 
						||
                    templateRow.GetCell(i).SetCellValue(templateRow.GetCell(i - gap).StringCellValue);
 | 
						||
 | 
						||
                    if (isCdics)
 | 
						||
                    {
 | 
						||
                        cdicsRow.GetCell(i).SetCellValue(cdicsRow.GetCell(i - gap).StringCellValue);
 | 
						||
                    }
 | 
						||
                }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                //设置动态Tilte
 | 
						||
 | 
						||
                for (int i = dynamicColunmStartIndex; i < dynamicColunmStartIndex + needAddCount; i++)
 | 
						||
                {
 | 
						||
 | 
						||
                    var name = dynamicColumnConfig.ColumnIdNameList[i - dynamicColunmStartIndex].Name;
 | 
						||
 | 
						||
                    titelRow.GetCell(i).SetCellValue(name);
 | 
						||
                    templateRow.GetCell(i).SetCellValue("");
 | 
						||
 | 
						||
                    if (isCdics)
 | 
						||
                    {
 | 
						||
                        var cdicsCode = dynamicColumnConfig.ColumnIdNameList[i - dynamicColunmStartIndex].CDISCCode;
 | 
						||
 | 
						||
                        cdicsRow.GetCell(i).SetCellValue(cdicsCode);
 | 
						||
                    }
 | 
						||
                }
 | 
						||
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
            using (var memoryStream2 = new MemoryStream())
 | 
						||
            {
 | 
						||
                workbook.Write(memoryStream2, true);
 | 
						||
 | 
						||
                memoryStream2.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
                templateStream = memoryStream2;
 | 
						||
            }
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        #endregion
 | 
						||
 | 
						||
        #region MiniExcel
 | 
						||
 | 
						||
        var memoryStream = new MemoryStream();
 | 
						||
 | 
						||
        var config = new OpenXmlConfiguration()
 | 
						||
        {
 | 
						||
            IgnoreTemplateParameterMissing = true,
 | 
						||
        };
 | 
						||
 | 
						||
        //await MiniExcel.SaveAsByTemplateAsync("testmini.xlsx", templateStream.ToArray(), translateData);
 | 
						||
 | 
						||
        await MiniExcel.SaveAsByTemplateAsync(memoryStream, templateStream.ToArray(), translateData, config);
 | 
						||
 | 
						||
 | 
						||
        memoryStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
        if (dynamicColumnConfig != null)
 | 
						||
        {
 | 
						||
            //Excel 列是按照名称填充 还是Id 填充
 | 
						||
            var isExcelAddDataWithName = dynamicColumnConfig.ColumnIdNameList.Select(t => t.Id).Distinct().Count() == 1;
 | 
						||
 | 
						||
            var dynamicTranslateDataList = await _dictionaryService.GetBasicDataSelect(dynamicColumnConfig.TranslateDicNameList.ToArray());
 | 
						||
 | 
						||
            // 使用NPOI  进行二次处理
 | 
						||
            var wb = new XSSFWorkbook(memoryStream);
 | 
						||
            var sheet = wb.GetSheetAt(0);
 | 
						||
 | 
						||
            var list = translatedDic["List"] as IList;
 | 
						||
 | 
						||
            foreach (var itemResult in list)
 | 
						||
            {
 | 
						||
                var index = list.IndexOf(itemResult);
 | 
						||
 | 
						||
                //从第四行开始处理动态列
 | 
						||
                var row = sheet.GetRow(index + dynamicColumnConfig.AutoColumnTitleRowIndex + 1);
 | 
						||
 | 
						||
                var itemDic = itemResult.ToDictionary();
 | 
						||
 | 
						||
                var itemList = itemDic[dynamicColumnConfig.DynamicListName] as IList;
 | 
						||
 | 
						||
                //这个数组是动态的,有的多,有的少,所以在此对比Title 一致才赋值
 | 
						||
                foreach (var itemObj in itemList)
 | 
						||
                {
 | 
						||
 | 
						||
                    var iteObjDic = itemObj.ToDictionary();
 | 
						||
 | 
						||
                    var itemDicName = iteObjDic.ContainsKey(dynamicColumnConfig.DynamicItemDicName) ? iteObjDic[dynamicColumnConfig.DynamicItemDicName]?.ToString() : "";
 | 
						||
                    var itemValue = iteObjDic[dynamicColumnConfig.DynamicItemValueName]?.ToString();
 | 
						||
 | 
						||
                    //var writeIndex = itemList.IndexOf(itemObj) + dynamicColumnConfig.AutoColumnStartIndex;
 | 
						||
 | 
						||
                    var writeIndex = 0;
 | 
						||
 | 
						||
                    if (isExcelAddDataWithName)
 | 
						||
                    {
 | 
						||
                        writeIndex = dynamicColumnConfig.ColumnNameList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleName].ToString()) + dynamicColumnConfig.AutoColumnStartIndex;
 | 
						||
                    }
 | 
						||
                    else
 | 
						||
                    {
 | 
						||
                        writeIndex = dynamicColumnConfig.ColumnIdList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleId].ToString()) + dynamicColumnConfig.AutoColumnStartIndex;
 | 
						||
                    }
 | 
						||
 | 
						||
 | 
						||
                    if (itemDicName.IsNotNullOrEmpty())
 | 
						||
                    {
 | 
						||
 | 
						||
                        var translatedItemData = dynamicTranslateDataList[itemDicName].Where(t => t.Code.ToLower() == itemValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
 | 
						||
 | 
						||
                        row.GetCell(writeIndex).SetCellValue(translatedItemData);
 | 
						||
                    }
 | 
						||
                    else
 | 
						||
                    {
 | 
						||
                        row.GetCell(writeIndex).SetCellValue(itemValue);
 | 
						||
 | 
						||
                    }
 | 
						||
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
            var memoryStream2 = new MemoryStream();
 | 
						||
            wb.Write(memoryStream2, true);
 | 
						||
            memoryStream2.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
            memoryStream = memoryStream2;
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        return (memoryStream, fileName);
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        #endregion
 | 
						||
    }
 | 
						||
 | 
						||
    /// <summary>
 | 
						||
    /// 暂时废弃--合并到上面
 | 
						||
    /// </summary>
 | 
						||
    /// <param name="code"></param>
 | 
						||
    /// <param name="data"></param>
 | 
						||
    /// <param name="_commonDocumentRepository"></param>
 | 
						||
    /// <param name="_hostEnvironment"></param>
 | 
						||
    /// <param name="_dictionaryService"></param>
 | 
						||
    /// <param name="translateType"></param>
 | 
						||
    /// <param name="criterionType"></param>
 | 
						||
    /// <param name="dynamicColumnConfig"></param>
 | 
						||
    /// <returns></returns>
 | 
						||
    public static async Task<(MemoryStream, string)> CDISC_DataExport_Async(string code, ExcelExportInfo data, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment, IDictionaryService? _dictionaryService = null, Type? translateType = null, CriterionType? criterionType = null, DynamicColumnConfig? dynamicColumnConfig = null)
 | 
						||
    {
 | 
						||
        var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
 | 
						||
        //判断是否有字典翻译
 | 
						||
 | 
						||
        object translateData = data;
 | 
						||
 | 
						||
        Dictionary<string, object> translatedDic = default;
 | 
						||
 | 
						||
        if (_dictionaryService != null && translateType != null)
 | 
						||
        {
 | 
						||
 | 
						||
            //一个值 对应不同的字典翻译
 | 
						||
            var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
 | 
						||
                .SelectMany(c =>
 | 
						||
                c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false).Select(f => (DictionaryTranslateAttribute?)f).Where(t => t.CriterionType == criterionType || t.CriterionType == null)
 | 
						||
                .Select(k => new { c.Name, k.DicParentCode, k.IsTranslateDenpendOtherProperty, k.DependPropertyName, k.DependPropertyValueStr })
 | 
						||
                ).ToList();
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            //字典表查询出所有需要翻译的数据
 | 
						||
 | 
						||
            var translateDataList = await _dictionaryService.GetBasicDataSelect(needTranslatePropertyList.Select(t => t.DicParentCode).Distinct().ToArray());
 | 
						||
 | 
						||
            var dic = data.ConvertToDictionary();
 | 
						||
            //var dic = (JsonConvert.DeserializeObject<IDictionary<string, object>>(data.ToJsonNotIgnoreNull())).IfNullThrowException();
 | 
						||
 | 
						||
            foreach (var key in dic.Keys)
 | 
						||
            {
 | 
						||
                //是数组 那么找到对应的属性 进行翻译
 | 
						||
                if (dic[key] != null && dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)))
 | 
						||
                //if (dic[key].GetType().IsAssignableFrom(typeof(JArray)))
 | 
						||
                {
 | 
						||
 | 
						||
                    var newObjList = new List<object>();
 | 
						||
                    var no = 1;
 | 
						||
                    foreach (var item in dic[key] as IList)
 | 
						||
                    //foreach (var item in dic[key] as JArray)
 | 
						||
                    {
 | 
						||
                        //var itemDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
 | 
						||
                        var itemDic = item.ConvertToDictionary();
 | 
						||
 | 
						||
                        foreach (var needTranslateProperty in needTranslatePropertyList)
 | 
						||
                        {
 | 
						||
                            if (itemDic.Keys.Any(t => t == needTranslateProperty.Name))
 | 
						||
                            {
 | 
						||
                                //翻译的属性依赖其他属性
 | 
						||
                                if (needTranslateProperty.IsTranslateDenpendOtherProperty)
 | 
						||
                                {
 | 
						||
                                    if (itemDic[needTranslateProperty.DependPropertyName]?.ToString().ToLower() == needTranslateProperty.DependPropertyValueStr.ToLower())
 | 
						||
                                    {
 | 
						||
                                        var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
 | 
						||
 | 
						||
                                        itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
 | 
						||
                                    }
 | 
						||
                                }
 | 
						||
                                //普通翻译 或者某一标准翻译
 | 
						||
                                else
 | 
						||
                                {
 | 
						||
                                    var beforeValue = itemDic[needTranslateProperty.Name]?.ToString();
 | 
						||
 | 
						||
 | 
						||
                                    itemDic[needTranslateProperty.Name] = translateDataList[needTranslateProperty.DicParentCode].Where(t => t.Code.ToLower() == beforeValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
 | 
						||
                                }
 | 
						||
                            }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                        }
 | 
						||
 | 
						||
                        itemDic.Add("No", no++);
 | 
						||
                        newObjList.Add(itemDic);
 | 
						||
                    }
 | 
						||
 | 
						||
                    dic[key] = newObjList;
 | 
						||
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
            //data = dic;
 | 
						||
            translateData = dic;
 | 
						||
            translatedDic = dic;
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
 | 
						||
 | 
						||
 | 
						||
        //模板路径
 | 
						||
        var tplPath = physicalPath;
 | 
						||
 | 
						||
        #region 根据中英文  删除模板sheet
 | 
						||
 | 
						||
        // 打开模板文件
 | 
						||
        var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
 | 
						||
 | 
						||
        // 获取文件流
 | 
						||
        var templateStream = new MemoryStream();
 | 
						||
        templateFile.CopyTo(templateStream);
 | 
						||
        templateStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
        var workbook = new XSSFWorkbook(templateStream);
 | 
						||
 | 
						||
        int sheetCount = workbook.NumberOfSheets;
 | 
						||
 | 
						||
        if (sheetCount == 2)
 | 
						||
        {
 | 
						||
            if (isEn_US)
 | 
						||
            {
 | 
						||
                workbook.RemoveSheetAt(0);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                workbook.RemoveSheetAt(1);
 | 
						||
            }
 | 
						||
 | 
						||
            if (dynamicColumnConfig != null)
 | 
						||
            {
 | 
						||
                var sheet = workbook.GetSheetAt(0);
 | 
						||
 | 
						||
 | 
						||
                var cdicsRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex - 1);
 | 
						||
                var titelRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex);
 | 
						||
                var templateRow = sheet.GetRow(dynamicColumnConfig.AutoColumnTitleRowIndex + 1);
 | 
						||
 | 
						||
                //动态移除列的数量
 | 
						||
                var dynamicRemoveColunmCount = dynamicColumnConfig.RemoveColunmIndexList.Count();
 | 
						||
 | 
						||
                //在动态列开始前移除的数量
 | 
						||
                var beforeDynamicRemoveCount = dynamicColumnConfig.RemoveColunmIndexList.Where(t => t < dynamicColumnConfig.AutoColumnStartIndex).Count();
 | 
						||
 | 
						||
                //动态添加列的数量
 | 
						||
                var needAddCount = dynamicColumnConfig.ColumnIdNameList.Count;
 | 
						||
 | 
						||
                //原始表  最终索引
 | 
						||
                var originTotalEndIndex = dynamicColumnConfig.TempalteLastColumnIndex;
 | 
						||
 | 
						||
                //减去动态移除后原始结束索引
 | 
						||
                var originRemoveEndIndex = originTotalEndIndex - dynamicRemoveColunmCount;
 | 
						||
 | 
						||
                //最终表 动态列开始索引
 | 
						||
                var dynamicColunmStartIndex = dynamicColumnConfig.AutoColumnStartIndex - beforeDynamicRemoveCount;
 | 
						||
 | 
						||
                //最终表 动态列的终止索引
 | 
						||
                var dynamicColunmEndIndex = dynamicColunmStartIndex + needAddCount - 1;
 | 
						||
 | 
						||
                //最终表  最终索引
 | 
						||
                var totalColunmEndIndex = originTotalEndIndex + needAddCount - dynamicRemoveColunmCount;
 | 
						||
 | 
						||
 | 
						||
                //动态列后需要移动的数量
 | 
						||
                var backMoveCount = totalColunmEndIndex - dynamicColunmEndIndex;
 | 
						||
 | 
						||
                //删除需要动态删除的列  从大到小移除,否则索引会变
 | 
						||
                foreach (var removeIndex in dynamicColumnConfig.RemoveColunmIndexList.OrderByDescending(t => t))
 | 
						||
                {
 | 
						||
                    //将后面的列向前移动
 | 
						||
                    for (var i = 0; i < originTotalEndIndex - removeIndex; i++)
 | 
						||
                    {
 | 
						||
                        Console.WriteLine(titelRow.GetCell(removeIndex + i + 1).StringCellValue);
 | 
						||
                        titelRow.GetCell(removeIndex + i).SetCellValue(titelRow.GetCell(removeIndex + i + 1).StringCellValue);
 | 
						||
                        templateRow.GetCell(removeIndex + i).SetCellValue(templateRow.GetCell(removeIndex + i + 1).StringCellValue);
 | 
						||
 | 
						||
                        //后面的数据要清空
 | 
						||
                        titelRow.GetCell(removeIndex + i + 1).SetCellValue("");
 | 
						||
                        templateRow.GetCell(removeIndex + i + 1).SetCellValue("");
 | 
						||
 | 
						||
                    }
 | 
						||
 | 
						||
                }
 | 
						||
 | 
						||
                //创建新的列
 | 
						||
                for (int i = originTotalEndIndex; i < originTotalEndIndex + needAddCount; i++)
 | 
						||
                {
 | 
						||
                    cdicsRow.CreateCell(i + 1);
 | 
						||
                    titelRow.CreateCell(i + 1);
 | 
						||
                    templateRow.CreateCell(i + 1);
 | 
						||
                }
 | 
						||
                //移动Title 和下面的模板标识
 | 
						||
 | 
						||
                var gap = totalColunmEndIndex - originRemoveEndIndex;
 | 
						||
 | 
						||
                for (int i = totalColunmEndIndex; i > dynamicColunmEndIndex; i--)
 | 
						||
                {
 | 
						||
 | 
						||
                    titelRow.GetCell(i).SetCellValue(titelRow.GetCell(i - gap).StringCellValue);
 | 
						||
 | 
						||
                    templateRow.GetCell(i).SetCellValue(templateRow.GetCell(i - gap).StringCellValue);
 | 
						||
                }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                //设置动态Tilte
 | 
						||
 | 
						||
                for (int i = dynamicColunmStartIndex; i < dynamicColunmStartIndex + needAddCount; i++)
 | 
						||
                {
 | 
						||
                    var name = dynamicColumnConfig.ColumnIdNameList[i - dynamicColunmStartIndex].Name;
 | 
						||
 | 
						||
                    var cdicsCode = dynamicColumnConfig.ColumnIdNameList[i - dynamicColunmStartIndex].CDISCCode;
 | 
						||
 | 
						||
                    cdicsRow.GetCell(i).SetCellValue(cdicsCode);
 | 
						||
                    titelRow.GetCell(i).SetCellValue(name);
 | 
						||
                    templateRow.GetCell(i).SetCellValue("");
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
            using (var memoryStream2 = new MemoryStream())
 | 
						||
            {
 | 
						||
                workbook.Write(memoryStream2, true);
 | 
						||
 | 
						||
                memoryStream2.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
                templateStream = memoryStream2;
 | 
						||
            }
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        #endregion
 | 
						||
 | 
						||
        #region MiniExcel
 | 
						||
 | 
						||
        var memoryStream = new MemoryStream();
 | 
						||
 | 
						||
        var config = new OpenXmlConfiguration()
 | 
						||
        {
 | 
						||
            IgnoreTemplateParameterMissing = true,
 | 
						||
        };
 | 
						||
 | 
						||
        await MiniExcel.SaveAsByTemplateAsync(memoryStream, templateStream.ToArray(), translateData, config);
 | 
						||
 | 
						||
        memoryStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
        if (dynamicColumnConfig != null)
 | 
						||
        {
 | 
						||
            var isExcelAddDataWithName = dynamicColumnConfig.ColumnIdNameList.Select(t => t.Id).Count() == 1;
 | 
						||
 | 
						||
            var dynamicTranslateDataList = await _dictionaryService.GetBasicDataSelect(dynamicColumnConfig.TranslateDicNameList.ToArray());
 | 
						||
 | 
						||
            // 使用NPOI  进行二次处理
 | 
						||
            var wb = new XSSFWorkbook(memoryStream);
 | 
						||
            var sheet = wb.GetSheetAt(0);
 | 
						||
 | 
						||
            var list = translatedDic["List"] as IList;
 | 
						||
 | 
						||
            foreach (var itemResult in list)
 | 
						||
            {
 | 
						||
                var index = list.IndexOf(itemResult);
 | 
						||
 | 
						||
                //从第四行开始处理动态列
 | 
						||
                var row = sheet.GetRow(index + dynamicColumnConfig.AutoColumnTitleRowIndex + 1);
 | 
						||
 | 
						||
                var itemDic = itemResult.ToDictionary();
 | 
						||
 | 
						||
                var itemList = itemDic[dynamicColumnConfig.DynamicListName] as IList;
 | 
						||
 | 
						||
                //这个数组是动态的,有的多,有的少,所以在此对比Title 一致才赋值
 | 
						||
                foreach (var itemObj in itemList)
 | 
						||
                {
 | 
						||
 | 
						||
                    var iteObjDic = itemObj.ToDictionary();
 | 
						||
 | 
						||
                    var itemDicName = iteObjDic[dynamicColumnConfig.DynamicItemDicName]?.ToString();
 | 
						||
                    var itemValue = iteObjDic[dynamicColumnConfig.DynamicItemValueName]?.ToString();
 | 
						||
 | 
						||
                    //var writeIndex = itemList.IndexOf(itemObj) + dynamicColumnConfig.AutoColumnStartIndex;
 | 
						||
 | 
						||
                    var writeIndex = 0;
 | 
						||
                    if (isExcelAddDataWithName)
 | 
						||
                    {
 | 
						||
                        writeIndex = dynamicColumnConfig.ColumnNameList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleName].ToString()) + dynamicColumnConfig.AutoColumnStartIndex;
 | 
						||
                    }
 | 
						||
                    else
 | 
						||
                    {
 | 
						||
                        writeIndex = dynamicColumnConfig.ColumnIdList.IndexOf(iteObjDic[dynamicColumnConfig.DynamicItemTitleId].ToString()) + dynamicColumnConfig.AutoColumnStartIndex;
 | 
						||
                    }
 | 
						||
 | 
						||
                    if (itemDicName.IsNotNullOrEmpty())
 | 
						||
                    {
 | 
						||
 | 
						||
                        var translatedItemData = dynamicTranslateDataList[itemDicName].Where(t => t.Code.ToLower() == itemValue?.ToLower()).Select(t => isEn_US ? t.Value : t.ValueCN).FirstOrDefault() ?? String.Empty;
 | 
						||
 | 
						||
                        row.GetCell(writeIndex).SetCellValue(translatedItemData);
 | 
						||
                    }
 | 
						||
                    else
 | 
						||
                    {
 | 
						||
                        row.GetCell(writeIndex).SetCellValue(itemValue);
 | 
						||
 | 
						||
                    }
 | 
						||
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
            var memoryStream2 = new MemoryStream();
 | 
						||
            wb.Write(memoryStream2, true);
 | 
						||
            memoryStream2.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
            memoryStream = memoryStream2;
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        return (memoryStream, fileName);
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        #endregion
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /// <summary>
 | 
						||
    /// 导出文件模板
 | 
						||
    /// </summary>
 | 
						||
    /// <param name="inDto"></param>
 | 
						||
    /// <returns></returns>
 | 
						||
    public static async Task<FileResult> ExportTemplateAsync(ExportTemplateServiceDto inDto)
 | 
						||
    {
 | 
						||
        var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(inDto.hostEnvironment, inDto.commonDocumentRepository, inDto.TemplateCode);
 | 
						||
 | 
						||
 | 
						||
        //模板路径
 | 
						||
        var tplPath = physicalPath;
 | 
						||
 | 
						||
        #region 根据中英文  删除模板sheet
 | 
						||
 | 
						||
        // 打开模板文件
 | 
						||
        var templateFile = new FileStream(tplPath, FileMode.Open, FileAccess.Read);
 | 
						||
 | 
						||
        // 获取文件流
 | 
						||
        var templateStream = new MemoryStream();
 | 
						||
        templateFile.CopyTo(templateStream);
 | 
						||
        templateStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
        var workbook = new XSSFWorkbook(templateStream);
 | 
						||
 | 
						||
        int sheetCount = workbook.NumberOfSheets;
 | 
						||
 | 
						||
        if (sheetCount == 2)
 | 
						||
        {
 | 
						||
            if (inDto.IsEnglish)
 | 
						||
            {
 | 
						||
                workbook.RemoveSheetAt(0);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                workbook.RemoveSheetAt(1);
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        #endregion
 | 
						||
 | 
						||
 | 
						||
        ISheet sheet = workbook.GetSheetAt(0); // 获取第一个工作表
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        for (int i = 0; i < sheet.LastRowNum + 1; i++)
 | 
						||
        {
 | 
						||
            IRow row = sheet.GetRow(i);
 | 
						||
            for (int j = 0; j < sheet.LastRowNum; j++)
 | 
						||
            {
 | 
						||
                ICell cell = row.GetCell(j);
 | 
						||
                foreach (var property in inDto.Data.GetType().GetProperties())
 | 
						||
                {
 | 
						||
                    var value = property.GetValue(inDto.Data);
 | 
						||
                    if (cell != null && cell.ToString() == "{{" + property.Name + "}}")
 | 
						||
                    {
 | 
						||
                        sheet.GetRow(i).GetCell(j).SetCellValue(value.ToString());
 | 
						||
                    }
 | 
						||
                }
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        var memoryStream2 = new MemoryStream();
 | 
						||
        workbook.Write(memoryStream2, true);
 | 
						||
 | 
						||
        memoryStream2.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
        templateStream = memoryStream2;
 | 
						||
 | 
						||
 | 
						||
        return new FileStreamResult(templateStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
 | 
						||
        {
 | 
						||
            FileDownloadName = $"{(string.IsNullOrEmpty(inDto.ExportFileName) ? "" : inDto.ExportFileName + "_")}{Path.GetFileNameWithoutExtension(fileName)}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
 | 
						||
        };
 | 
						||
    }
 | 
						||
 | 
						||
} |