360 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			360 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
using DocumentFormat.OpenXml.Drawing.Diagrams;
 | 
						|
using DocumentFormat.OpenXml.Spreadsheet;
 | 
						|
using DocumentFormat.OpenXml.Wordprocessing;
 | 
						|
using IRaCIS.Application.Contracts;
 | 
						|
using IRaCIS.Application.Interfaces;
 | 
						|
using IRaCIS.Core.Application.Helper;
 | 
						|
using IRaCIS.Core.Domain.Share;
 | 
						|
using Magicodes.ExporterAndImporter.Excel;
 | 
						|
using Microsoft.AspNetCore.Hosting;
 | 
						|
using Microsoft.AspNetCore.Mvc;
 | 
						|
using MiniExcelLibs;
 | 
						|
using MiniExcelLibs.OpenXml;
 | 
						|
using Newtonsoft.Json;
 | 
						|
using Newtonsoft.Json.Linq;
 | 
						|
using NPOI.HSSF.UserModel;
 | 
						|
using NPOI.XSSF.UserModel;
 | 
						|
using SkiaSharp;
 | 
						|
using System.Collections;
 | 
						|
using System.IO;
 | 
						|
 | 
						|
namespace IRaCIS.Core.Application.Service;
 | 
						|
 | 
						|
public static class ExcelExportHelper
 | 
						|
{
 | 
						|
    //MiniExcel_Export
 | 
						|
    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)
 | 
						|
    {
 | 
						|
 | 
						|
        //判断是否有字典翻译
 | 
						|
 | 
						|
        object translateData = data;
 | 
						|
 | 
						|
        if (_dictionaryService != null && translateType != null)
 | 
						|
        {
 | 
						|
 | 
						|
            ////只标注单个的时候
 | 
						|
            //var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
 | 
						|
            //    .Select(c => new { c.Name, DicParentCode = ((DictionaryTranslateAttribute?)c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false)[0])?.DicParentCode }).ToList();
 | 
						|
 | 
						|
 | 
						|
            //一个值 对应不同的字典翻译
 | 
						|
            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].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 = JsonConvert.DeserializeObject<IDictionary<string, object>>(item.ToJsonNotIgnoreNull());
 | 
						|
 | 
						|
                        var itemDic = item.ConvertToDictionary();
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                        foreach (var needTranslateProperty in needTranslatePropertyList)
 | 
						|
                        {
 | 
						|
                            //翻译的属性依赖其他属性
 | 
						|
                            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=>data.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 => data.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, fileNmae) = 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 (data.IsEn_US)
 | 
						|
            {
 | 
						|
                workbook.RemoveSheetAt(0);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                workbook.RemoveSheetAt(1);
 | 
						|
            }
 | 
						|
 | 
						|
            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 = $"{exportFileNamePrefix}_{fileNmae/*.Substring(0, fileNmae.LastIndexOf('.'))*/}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
 | 
						|
        };
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Magicodes  模板规则不一样
 | 
						|
 | 
						|
        ////创建Excel导出对象
 | 
						|
        //IExportFileByTemplate exporter = new ExcelExporter();
 | 
						|
 | 
						|
        ////根据模板导出
 | 
						|
        //var result = await exporter.ExportBytesByTemplate(exportInfo, tplPath);
 | 
						|
 | 
						|
 | 
						|
        //return new XlsxFileResult(bytes: result, fileDownloadName: $"{doc.Name}_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx");
 | 
						|
        #endregion
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    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)
 | 
						|
    {
 | 
						|
        //判断是否有字典翻译
 | 
						|
 | 
						|
        object translateData = data;
 | 
						|
 | 
						|
        if (_dictionaryService != null && translateType != null)
 | 
						|
        {
 | 
						|
 | 
						|
            ////只标注单个的时候
 | 
						|
            //var needTranslatePropertyList = translateType.GetProperties().Where(t => t.IsDefined(typeof(DictionaryTranslateAttribute), true))
 | 
						|
            //    .Select(c => new { c.Name, DicParentCode = ((DictionaryTranslateAttribute?)c.GetCustomAttributes(typeof(DictionaryTranslateAttribute), false)[0])?.DicParentCode }).ToList();
 | 
						|
 | 
						|
 | 
						|
            //一个值 对应不同的字典翻译
 | 
						|
            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].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 (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 => data.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 => data.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 (data.IsEn_US)
 | 
						|
            {
 | 
						|
                workbook.RemoveSheetAt(0);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                workbook.RemoveSheetAt(1);
 | 
						|
            }
 | 
						|
 | 
						|
            var memoryStream2 = new MemoryStream();
 | 
						|
            workbook.Write(memoryStream2,true);
 | 
						|
 | 
						|
            memoryStream2.Seek(0, SeekOrigin.Begin);
 | 
						|
 | 
						|
            templateStream = memoryStream2;
 | 
						|
        }
 | 
						|
 | 
						|
        // 文件名称 从sheet里面取
 | 
						|
        fileName = 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 (memoryStream, fileName);
 | 
						|
 | 
						|
        //var wb = new HSSFWorkbook(memoryStream);
 | 
						|
 | 
						|
        //var  sheet = wb.GetSheetAt(0);
 | 
						|
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
 | 
						|
} |