整理文件夹
This commit is contained in:
+63
@@ -0,0 +1,63 @@
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
|
||||
public class DictionaryTranslateAttribute : Attribute
|
||||
{
|
||||
|
||||
public string DicParentCode { get; set; }
|
||||
|
||||
public DicDataTypeEnum DataTypeEnum { get; set; }
|
||||
|
||||
public CriterionType? CriterionType { get; set; }
|
||||
|
||||
|
||||
//是否翻译依赖其他属性
|
||||
public bool IsTranslateDenpendOtherProperty => !string.IsNullOrWhiteSpace(DependPropertyName);
|
||||
|
||||
public string DependPropertyName { get; set; } = string.Empty;
|
||||
|
||||
public string DependPropertyValueStr { get; set; } = string.Empty;
|
||||
|
||||
// 普通翻译的字典
|
||||
public DictionaryTranslateAttribute(string dicParentCode)
|
||||
{
|
||||
DicParentCode = dicParentCode;
|
||||
|
||||
}
|
||||
|
||||
//针对不同的标准 翻译的字典不一样
|
||||
public DictionaryTranslateAttribute(string dicParentCode, CriterionType criterionType)
|
||||
{
|
||||
DicParentCode = dicParentCode;
|
||||
|
||||
CriterionType = criterionType;
|
||||
}
|
||||
|
||||
//针对业务某个属性的值 不一样 用的翻译字典不一样
|
||||
|
||||
public DictionaryTranslateAttribute(string dicParentCode, string dependPropertyName, string dependPropertyValueStr)
|
||||
{
|
||||
DicParentCode = dicParentCode;
|
||||
|
||||
DependPropertyName = dependPropertyName;
|
||||
|
||||
DependPropertyValueStr = dependPropertyValueStr;
|
||||
|
||||
}
|
||||
|
||||
public DictionaryTranslateAttribute(string dicParentCode, CriterionType criterionType, string dependPropertyName, string dependPropertyValueStr)
|
||||
{
|
||||
DicParentCode = dicParentCode;
|
||||
|
||||
DependPropertyName = dependPropertyName;
|
||||
|
||||
CriterionType = criterionType;
|
||||
|
||||
DependPropertyValueStr = dependPropertyValueStr;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,622 @@
|
||||
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;
|
||||
|
||||
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].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)
|
||||
{
|
||||
if (DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result))
|
||||
{
|
||||
itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 => 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);
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
|
||||
public int TempalteLastColumnIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 动态的列名
|
||||
/// </summary>
|
||||
public List<string> ColumnNameList { get; set; } = new List<string>();
|
||||
|
||||
/// <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; }
|
||||
|
||||
public List<int> RemoveColunmIndexList { get; set; } = new List<int>();
|
||||
}
|
||||
|
||||
|
||||
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].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 (DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result))
|
||||
{
|
||||
itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result);
|
||||
}
|
||||
}
|
||||
|
||||
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 => 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 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.ColumnNameList.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++)
|
||||
{
|
||||
titelRow.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.ColumnNameList[i - dynamicColunmStartIndex];
|
||||
|
||||
titelRow.GetCell(i).SetCellValue(name);
|
||||
}
|
||||
}
|
||||
|
||||
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 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;
|
||||
|
||||
foreach (var itemObj in itemList)
|
||||
{
|
||||
var writeIndex = itemList.IndexOf(itemObj) + dynamicColumnConfig.AutoColumnStartIndex;
|
||||
|
||||
var iteObjDic = itemObj.ToDictionary();
|
||||
|
||||
var itemDicName = iteObjDic[dynamicColumnConfig.DynamicItemDicName].ToString();
|
||||
var itemValue = iteObjDic[dynamicColumnConfig.DynamicItemValueName].ToString();
|
||||
|
||||
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"
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using RestSharp;
|
||||
using SharpCompress.Common;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper;
|
||||
|
||||
public class FileConvertHelper
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 镜像里面打入libreoffice 的方案
|
||||
/// </summary>
|
||||
/// <param name="inputWordFilePath"></param>
|
||||
/// <param name="outputPdfDir"></param>
|
||||
static public void ConvertWordToPdf(string inputWordFilePath, string outputPdfDir)
|
||||
{
|
||||
// 设置 libreoffice 命令行参数
|
||||
string arguments = $"--headless --invisible --convert-to pdf \"{inputWordFilePath}\" --outdir \"{outputPdfDir}\"";
|
||||
|
||||
// 启动 libreoffice 进程
|
||||
using (Process process = new Process())
|
||||
{
|
||||
process.StartInfo.FileName = "libreoffice";
|
||||
process.StartInfo.Arguments = arguments;
|
||||
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.RedirectStandardError = true;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
|
||||
process.Start();
|
||||
|
||||
// 等待进程结束
|
||||
process.WaitForExit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 返回文件字节数组
|
||||
/// File.WriteAllBytes(outputFilePath, response.RawBytes); 直接将字节数组写入到本地某个路径
|
||||
/// var stream = new MemoryStream(response.RawBytes); 直接变为内存流,给其他程序用也可以
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
static public async Task<byte[]> ThirdStirling_PDFWordToPdfAsync(string filePath)
|
||||
{
|
||||
|
||||
var apiUrl = GetApiUrl();
|
||||
|
||||
var client = new RestClient(apiUrl);
|
||||
|
||||
var request = new RestRequest(apiUrl, Method.Post);
|
||||
|
||||
request.AddHeader("accept", "*/*");
|
||||
|
||||
// 直接上传文件,无需生成字节数组
|
||||
request.AddFile("fileInput", filePath);
|
||||
|
||||
return await GetPDFByteArrayAsync(client, request);
|
||||
}
|
||||
|
||||
static public async Task<byte[]> ThirdStirling_PDFWordToPdfAsync(byte[] fileBytes, string fileName)
|
||||
{
|
||||
|
||||
var apiUrl = GetApiUrl();
|
||||
var client = new RestClient(apiUrl);
|
||||
|
||||
var request = new RestRequest(apiUrl, Method.Post);
|
||||
|
||||
request.AddHeader("accept", "*/*");
|
||||
|
||||
// 添加文件流到请求
|
||||
request.AddFile("fileInput", fileBytes, fileName);
|
||||
|
||||
return await GetPDFByteArrayAsync(client, request);
|
||||
}
|
||||
|
||||
static private async Task<byte[]> GetPDFByteArrayAsync(RestClient client, RestRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
|
||||
// 发送请求并获取响应
|
||||
var response = await client.ExecuteAsync(request);
|
||||
|
||||
// 检查请求是否成功
|
||||
if (response.IsSuccessful)
|
||||
{
|
||||
return response.RawBytes ?? new byte[] { };
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"上传失败,错误代码: {response.StatusCode}, 错误消息: {response.ErrorMessage}");
|
||||
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("发生异常: " + ex.Message);
|
||||
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
}
|
||||
|
||||
static private string GetApiUrl()
|
||||
{
|
||||
|
||||
var enviromentName = Environment.GetEnvironmentVariables()["ASPNETCORE_ENVIRONMENT"]?.ToString();
|
||||
|
||||
var configuration = new ConfigurationBuilder().AddJsonFile($"appsettings.{enviromentName}.json", false, false).Build();
|
||||
|
||||
// 手动绑定配置
|
||||
var appSettings = new ServiceVerifyConfigOption();
|
||||
configuration.GetSection("BasicSystemConfig").Bind(appSettings);
|
||||
|
||||
return appSettings.ThirdPdfUrl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper;
|
||||
|
||||
public static class FileStoreHelper
|
||||
{
|
||||
|
||||
//处理文件名 压缩包,或者目录类的 会带上相对路径
|
||||
public static (string TrustedFileNameForFileStorage, string RealName) GetStoreFileName(string fileName, bool isChangeToPdfFormat = false)
|
||||
{
|
||||
|
||||
//带目录层级,需要后端处理前端的路径
|
||||
if (fileName.Contains("\\"))
|
||||
{
|
||||
fileName = fileName.Split("\\").Last();
|
||||
}
|
||||
|
||||
if (fileName.Contains("/"))
|
||||
{
|
||||
fileName = fileName.Split("/").Last();
|
||||
}
|
||||
|
||||
var matchResult = Regex.Match(fileName, @"[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}");
|
||||
|
||||
//如果有guid
|
||||
if (matchResult.Success)
|
||||
{
|
||||
fileName = fileName.Replace($"{matchResult.Value}", "");
|
||||
}
|
||||
|
||||
|
||||
var trustedFileNameForFileStorage = string.Empty;
|
||||
|
||||
if (isChangeToPdfFormat == false)
|
||||
{
|
||||
trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileName;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
trustedFileNameForFileStorage = Guid.NewGuid().ToString() + Path.GetFileNameWithoutExtension(fileName) + ".pdf";
|
||||
}
|
||||
|
||||
return (trustedFileNameForFileStorage, fileName);
|
||||
}
|
||||
|
||||
//API vue 部署目录
|
||||
public static string GetIRaCISRootPath(IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
string parentDirectory = Path.GetFullPath(Path.Combine(_hostEnvironment.ContentRootPath, ".."));
|
||||
|
||||
return parentDirectory;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//获取环境存储根目录
|
||||
public static string GetIRaCISRootDataFolder(IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
var rootPath = GetIRaCISRootPath(_hostEnvironment);
|
||||
|
||||
var rootFolder = Path.Combine(rootPath, StaticData.Folder.IRaCISDataFolder);
|
||||
|
||||
return rootFolder;
|
||||
}
|
||||
|
||||
//根据相对路径 获取具体文件物理地址
|
||||
public static string GetPhysicalFilePath(IWebHostEnvironment _hostEnvironment, string relativePath)
|
||||
{
|
||||
var rootPath = GetIRaCISRootPath(_hostEnvironment);
|
||||
|
||||
var physicalFilePath = Path.Combine(rootPath, relativePath.TrimStart('/'));
|
||||
|
||||
return physicalFilePath;
|
||||
}
|
||||
|
||||
|
||||
#region 修改后留存
|
||||
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetSystemFileUploadPath(IWebHostEnvironment _hostEnvironment, string templateFolderName, string fileName)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, templateFolderName);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{templateFolderName}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetOtherFileUploadPath(IWebHostEnvironment _hostEnvironment, string templateFolderName, string fileName)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.OtherDataFolder, templateFolderName);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.OtherDataFolder}/{templateFolderName}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
//通过编码获取通用文档具体物理路径
|
||||
|
||||
public static async Task<(string PhysicalPath, string FileName)> GetCommonDocPhysicalFilePathAsync(IWebHostEnvironment _hostEnvironment, IRepository<CommonDocument> _commonDocumentRepository, string code)
|
||||
{
|
||||
var doc = await _commonDocumentRepository.FirstOrDefaultAsync(t => t.Code == code);
|
||||
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name != StaticData.CultureInfo.zh_CN;
|
||||
if (doc == null)
|
||||
{
|
||||
//---数据库没有找到对应的数据模板文件,请联系系统运维人员。
|
||||
throw new BusinessValidationFailedException(I18n.T("FileStore_TemplateFileNotFound"));
|
||||
}
|
||||
|
||||
var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, doc.Path);
|
||||
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
{
|
||||
//---数据模板文件存储路径上未找对应文件,请联系系统运维人员。
|
||||
throw new BusinessValidationFailedException(I18n.T("FileStore_TemplateFileStoragePathInvalid"));
|
||||
}
|
||||
|
||||
return (filePath, isEn_US ? doc.Name.Trim('/') : doc.NameCN.Trim('/'));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 写文件导到磁盘
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
/// <param name="path">文件保存路径</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<int> WriteFileAsync(System.IO.Stream stream, string path)
|
||||
{
|
||||
const int FILE_WRITE_SIZE = 84975;//写出缓冲区大小
|
||||
int writeCount = 0;
|
||||
using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write, FILE_WRITE_SIZE, true))
|
||||
{
|
||||
byte[] byteArr = new byte[FILE_WRITE_SIZE];
|
||||
int readCount = 0;
|
||||
while ((readCount = await stream.ReadAsync(byteArr, 0, byteArr.Length)) > 0)
|
||||
{
|
||||
await fileStream.WriteAsync(byteArr, 0, readCount);
|
||||
writeCount += readCount;
|
||||
}
|
||||
}
|
||||
return writeCount;
|
||||
}
|
||||
|
||||
|
||||
// 获取通用文档存放路径(excel模板 )
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetCommonDocPath(IWebHostEnvironment _hostEnvironment, string fileName)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.SystemDataFolder, StaticData.Folder.DataTemplate);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.SystemDataFolder}/{StaticData.Folder.DataTemplate}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
// 获取 入组确认 PD 进展发送邮件Word|PDF 存放路径
|
||||
|
||||
public static (string PhysicalPath, string RelativePath, string FileRealName) GetSubjectEnrollConfirmOrPDEmailPath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid trialSiteId, Guid subjectId, bool isChangeToPdfFormat = false)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
string uploadFolderPath = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), trialSiteId.ToString(), subjectId.ToString());
|
||||
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName, isChangeToPdfFormat);
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{trialSiteId}/{subjectId}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath, fileRealName);
|
||||
}
|
||||
|
||||
|
||||
public static string GetSubjectVisitDicomFolderPhysicalPath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
return Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder);
|
||||
}
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetDicomInstanceFilePath(IWebHostEnvironment _hostEnvironment, Guid trialId, Guid subjectId, Guid subjectVisitId, Guid studyId, Guid instanceId)
|
||||
{
|
||||
#region 切换存储前
|
||||
//var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
#endregion
|
||||
var rootPath = Path.Combine(FileStoreHelper.GetBestStoreDisk(_hostEnvironment), StaticData.Folder.IRaCISDataFolder);
|
||||
|
||||
|
||||
|
||||
//加入访视层级 和Data
|
||||
var path = Path.Combine(rootPath, StaticData.Folder.TrialDataFolder, trialId.ToString(),
|
||||
subjectId.ToString(), subjectVisitId.ToString(), StaticData.Folder.DicomFolder, studyId.ToString());
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
var physicalPath = Path.Combine(path, instanceId.ToString());
|
||||
|
||||
var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}";
|
||||
|
||||
//var physicalPath = Path.Combine(path, instanceId.ToString() + ".dcm");
|
||||
|
||||
//var relativePath = $"/{StaticData.Folder.IRaCISDataFolder}/{StaticData.Folder.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.Folder.DicomFolder}/{studyId}/{instanceId}.dcm";
|
||||
|
||||
return (physicalPath, relativePath);
|
||||
}
|
||||
|
||||
public static string GetBestStoreDisk(IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
|
||||
var json = File.ReadAllText(Path.Combine(_hostEnvironment.ContentRootPath, "appsettings.json"));
|
||||
|
||||
JObject jsonObject = (JObject.Parse(json, new JsonLoadSettings() { CommentHandling = CommentHandling.Load })).IfNullThrowException();
|
||||
|
||||
int switchingRatio = 80;
|
||||
|
||||
try
|
||||
{
|
||||
switchingRatio = (int)jsonObject["IRaCISImageStore"]["SwitchingRatio"];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
//---解析Json文件配置出现问题
|
||||
throw new BusinessValidationFailedException(I18n.T("SysMon_JsonConfig") + e.Message);
|
||||
}
|
||||
|
||||
//默认存储的路径
|
||||
var defaultStoreRootFolder = FileStoreHelper.GetIRaCISRootPath(_hostEnvironment);
|
||||
|
||||
|
||||
DriveInfo defaultDrive = new DriveInfo(Path.GetPathRoot(defaultStoreRootFolder));
|
||||
|
||||
var drives = DriveInfo.GetDrives().Where(t => !t.Name.Contains("C") && !t.Name.Contains("c"))
|
||||
.Where(d => d.DriveType == DriveType.Fixed && d.IsReady)
|
||||
//剩余空间最多的
|
||||
.OrderByDescending(d => d.AvailableFreeSpace)
|
||||
|
||||
//存储空间相同,则按照按照总空间从大到小排序
|
||||
.ThenByDescending(d => d.TotalSize - d.TotalFreeSpace);
|
||||
|
||||
var bestDrive = drives.FirstOrDefault();
|
||||
var bestStoreRootFolder = string.Empty;
|
||||
|
||||
//仅仅只有C 盘
|
||||
if (bestDrive == null || ((double)(defaultDrive.TotalSize - defaultDrive.TotalFreeSpace) / defaultDrive.TotalSize) * 100 < switchingRatio)
|
||||
{
|
||||
bestStoreRootFolder = defaultStoreRootFolder;
|
||||
}
|
||||
else
|
||||
{
|
||||
bestStoreRootFolder = Path.Combine(bestDrive?.RootDirectory.FullName, _hostEnvironment.EnvironmentName);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(bestStoreRootFolder))
|
||||
{
|
||||
Directory.CreateDirectory(bestStoreRootFolder);
|
||||
}
|
||||
|
||||
return bestStoreRootFolder;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using NPOI.XWPF.UserModel;
|
||||
using System.Globalization;
|
||||
using Xceed.Document.NET;
|
||||
using Xceed.Words.NET;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper;
|
||||
|
||||
/// <summary>
|
||||
/// 利用DocX 库 处理word国际化模板
|
||||
/// </summary>
|
||||
public static class WordTempleteHelper
|
||||
{
|
||||
public static void DocX_GetInternationalTempleteStream(string filePath, Stream memoryStream)
|
||||
{
|
||||
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
using (DocX document = DocX.Load(filePath))
|
||||
{
|
||||
// 查找书签
|
||||
var bookmarkEn_Start = document.Bookmarks.FirstOrDefault(b => b.Name == StaticData.CultureInfo.en_US_bookMark);
|
||||
|
||||
if (bookmarkEn_Start != null)
|
||||
{
|
||||
// 获取书签的起始位置
|
||||
//int bookmarkCNStartPos = bookmarkCn_Start.Paragraph.StartIndex;
|
||||
|
||||
var bookmarkENStartPos = bookmarkEn_Start.Paragraph.StartIndex;
|
||||
|
||||
// 创建一个要删除段落的列表
|
||||
List<Paragraph> paragraphsToRemove = new List<Paragraph>();
|
||||
|
||||
foreach (var item in document.Paragraphs)
|
||||
{
|
||||
//中文模板在前,英文在后,英文模板,就删除英文之前的,中文模板就删除英文之后的
|
||||
|
||||
if (isEn_US ? item.EndIndex < bookmarkENStartPos : item.StartIndex >= bookmarkENStartPos)
|
||||
{
|
||||
paragraphsToRemove.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var paragraph in paragraphsToRemove)
|
||||
{
|
||||
document.RemoveParagraph(paragraph);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 保存修改
|
||||
document.SaveAs(memoryStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void Npoi_GetInternationalTempleteStream(string filePath, Stream memoryStream)
|
||||
{
|
||||
|
||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
XWPFDocument doc = new XWPFDocument(fs);
|
||||
|
||||
// 查找包含指定书签的段落及其索引
|
||||
var bookmarkParagraph = doc.Paragraphs
|
||||
.FirstOrDefault(p => p.GetCTP().GetBookmarkStartList().Any(b => b.name == StaticData.CultureInfo.en_US_bookMark));
|
||||
|
||||
if (bookmarkParagraph != null)
|
||||
{
|
||||
int bookmarkIndex = doc.Paragraphs.IndexOf(bookmarkParagraph);
|
||||
|
||||
if (isEn_US)
|
||||
{
|
||||
// 从书签所在段落开始,删除之前的所有段落
|
||||
for (int i = bookmarkIndex - 1; i >= 0; i--)
|
||||
{
|
||||
doc.RemoveBodyElement(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 删除书签之后的所有段落
|
||||
for (int i = doc.Paragraphs.Count - 1; i >= bookmarkIndex; i--)
|
||||
{
|
||||
doc.RemoveBodyElement(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
doc.Write(memoryStream);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user