365 lines
13 KiB
C#
365 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.HPSF;
|
|
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);
|
|
}
|
|
|
|
|
|
FileStream fileOut = new FileStream("resultTemplate", FileMode.Create, FileAccess.ReadWrite);
|
|
workbook.Write(fileOut);
|
|
|
|
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, tplPath, translateData, config);
|
|
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
|
return (memoryStream, fileName);
|
|
|
|
//var wb = new HSSFWorkbook(memoryStream);
|
|
|
|
//var sheet = wb.GetSheetAt(0);
|
|
|
|
|
|
#endregion
|
|
}
|
|
|
|
} |