|
@ -10,7 +10,9 @@ using System.IO.Compression; |
|
|
using System.Linq; |
|
|
using System.Linq; |
|
|
using System.Linq.Dynamic.Core; |
|
|
using System.Linq.Dynamic.Core; |
|
|
using System.Reflection; |
|
|
using System.Reflection; |
|
|
|
|
|
using System.Security.AccessControl; |
|
|
using System.Text.Json; |
|
|
using System.Text.Json; |
|
|
|
|
|
using System.Threading; |
|
|
using System.Threading.Tasks; |
|
|
using System.Threading.Tasks; |
|
|
using AutoMapper; |
|
|
using AutoMapper; |
|
|
using ClosedXML.Excel; |
|
|
using ClosedXML.Excel; |
|
@ -33,6 +35,8 @@ using Microsoft.EntityFrameworkCore; |
|
|
using Microsoft.Extensions.Configuration; |
|
|
using Microsoft.Extensions.Configuration; |
|
|
using Microsoft.Extensions.DependencyInjection; |
|
|
using Microsoft.Extensions.DependencyInjection; |
|
|
using Microsoft.Extensions.Logging; |
|
|
using Microsoft.Extensions.Logging; |
|
|
|
|
|
using Minio; |
|
|
|
|
|
using NPOI.POIFS.Crypt; |
|
|
using NPOI.SS.UserModel; |
|
|
using NPOI.SS.UserModel; |
|
|
using NPOI.XSSF.UserModel; |
|
|
using NPOI.XSSF.UserModel; |
|
|
using Omu.ValueInjecter; |
|
|
using Omu.ValueInjecter; |
|
@ -130,6 +134,7 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
this._hubContext = hubContext; |
|
|
this._hubContext = hubContext; |
|
|
this._currentUser = currentUser; |
|
|
this._currentUser = currentUser; |
|
|
this._logger = logger; |
|
|
this._logger = logger; |
|
|
|
|
|
_cfg = cfg; |
|
|
_service = service; |
|
|
_service = service; |
|
|
LinqToDBForEFTools.Initialize(); |
|
|
LinqToDBForEFTools.Initialize(); |
|
|
_excelImportService = excelImportService; |
|
|
_excelImportService = excelImportService; |
|
@ -298,23 +303,28 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
var entities = await _vmiBalanceSumDetailRepository.GetListByFilterAsync(input.Filters, input.Sorting, int.MaxValue, input.SkipCount, true).ConfigureAwait(false); |
|
|
var entities = await _vmiBalanceSumDetailRepository.GetListByFilterAsync(input.Filters, input.Sorting, int.MaxValue, input.SkipCount, true).ConfigureAwait(false); |
|
|
var dtos = _maper.Map<List<VmiBalanceSumDetail>, List<VmiBalanceSumDetailDto>>(entities); |
|
|
var dtos = _maper.Map<List<VmiBalanceSumDetail>, List<VmiBalanceSumDetailDto>>(entities); |
|
|
dtos = dtos.OrderByDescending(p => p.BillTime).ToList(); |
|
|
dtos = dtos.OrderByDescending(p => p.BillTime).ToList(); |
|
|
var fileName = $"库存余额_{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.xlsx"; |
|
|
var fileName = $"库存余额_{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.zip"; |
|
|
ExportImporter _exportImporter = new ExportImporter(); |
|
|
//ExportImporter _exportImporter = new ExportImporter();
|
|
|
var result = await _exportImporter.ExcelExporter(dtos).ConfigureAwait(false); |
|
|
//var result = await _exportImporter.ExcelExporter(dtos).ConfigureAwait(false);
|
|
|
result.ShouldNotBeNull(); |
|
|
//result.ShouldNotBeNull();
|
|
|
await _excelImportService.SaveBlobAsync(new SaveExcelImportInputDto { Name = fileName, Content = result }).ConfigureAwait(false); |
|
|
//await _excelImportService.SaveBlobAsync(new SaveExcelImportInputDto { Name = fileName, Content = result }).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
|
|
ExtendExcel<VmiBalanceSumDetailDto>.BucketName = _cfg.GetValue("MinIO:BucketName", "default"); |
|
|
|
|
|
|
|
|
|
|
|
ExtendExcel<VmiBalanceSumDetailDto>.AccessKey = _cfg.GetValue("MinIO:AccessKey" , "g0GKnhRGEQHI0uiGBYre"); |
|
|
|
|
|
|
|
|
|
|
|
ExtendExcel<VmiBalanceSumDetailDto>.SecretKey = _cfg.GetValue("MinIO:SecretKey" , "iKGlLz6UBzci3xrERw5Zz1gI77enT5u9agFemHPv"); |
|
|
|
|
|
|
|
|
// var content= ExtendExcel<VmiBalanceSumDetailDto>.WriteDataToExcelInParallel( "库存余额", dtos, 500000);
|
|
|
ExtendExcel<VmiBalanceSumDetailDto>.EndPoint = _cfg.GetValue("MinIO:EndPoint" , "localhost:10684"); |
|
|
|
|
|
|
|
|
|
|
|
return await ExtendExcel<VmiBalanceSumDetailDto>.WriteDataToExcelInParallel("库存余额", dtos, 500000).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return fileName; |
|
|
|
|
|
|
|
|
// return fileName;
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
@ -1965,8 +1975,8 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
} |
|
|
} |
|
|
if (propertyType.IsEnum) |
|
|
if (propertyType.IsEnum) |
|
|
{//枚举
|
|
|
{//枚举
|
|
|
var enumValue = Enum.GetNames(propertyType) |
|
|
var enumValue = System.Enum.GetNames(propertyType) |
|
|
.Select(o => new KeyValuePair<string, Enum>(o, (Enum)Enum.Parse(propertyType, o))) |
|
|
.Select(o => new KeyValuePair<string, System.Enum>(o, (System.Enum)System.Enum.Parse(propertyType, o))) |
|
|
.Where(o => o.Value.GetDisplayName() == value.ToString()) |
|
|
.Where(o => o.Value.GetDisplayName() == value.ToString()) |
|
|
.Select(o => o.Value) |
|
|
.Select(o => o.Value) |
|
|
.FirstOrDefault(); |
|
|
.FirstOrDefault(); |
|
@ -2064,7 +2074,7 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
} |
|
|
} |
|
|
else if (propertyType.IsEnum) |
|
|
else if (propertyType.IsEnum) |
|
|
{ |
|
|
{ |
|
|
cell.Value = (Enum.Parse(propertyType, value) as Enum)?.GetDisplayName(); |
|
|
cell.Value = (System.Enum.Parse(propertyType, value) as System.Enum)?.GetDisplayName(); |
|
|
} |
|
|
} |
|
|
else if (propertyType == typeof(DateTime)) |
|
|
else if (propertyType == typeof(DateTime)) |
|
|
{ |
|
|
{ |
|
@ -2215,20 +2225,7 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 扩展方法类,用于为IEnumerable类型添加额外功能
|
|
|
// 扩展方法类,用于为IEnumerable类型添加额外功能
|
|
|
public static class EnumerableExtensions |
|
|
|
|
|
{ |
|
|
|
|
|
// 扩展方法,将源序列按指定大小分割成多个子序列
|
|
|
|
|
|
public static IEnumerable<IEnumerable<T>> ChunkBy<T>(this IEnumerable<T> source, int chunkSize) |
|
|
|
|
|
{ |
|
|
|
|
|
// 使用Select方法为序列中的每个元素添加索引和值
|
|
|
|
|
|
return source |
|
|
|
|
|
.Select((x, i) => new { Index = i, Value = x }) |
|
|
|
|
|
// 根据索引除以块大小进行分组
|
|
|
|
|
|
.GroupBy(x => x.Index / chunkSize) |
|
|
|
|
|
// 从每个分组中选择值形成新的子序列
|
|
|
|
|
|
.Select(x => x.Select(v => v.Value)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class FileInfoGroup |
|
|
public class FileInfoGroup |
|
@ -2247,6 +2244,11 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
{ |
|
|
{ |
|
|
|
|
|
|
|
|
static ConcurrentBag<FileInfoGroup> excelFiles = new ConcurrentBag<FileInfoGroup>(); |
|
|
static ConcurrentBag<FileInfoGroup> excelFiles = new ConcurrentBag<FileInfoGroup>(); |
|
|
|
|
|
public static string EndPoint { get; set; } |
|
|
|
|
|
public static string AccessKey { get; set; } |
|
|
|
|
|
public static string SecretKey { get; set; } |
|
|
|
|
|
public static string BucketName { get; set; } |
|
|
|
|
|
public static bool WithSSL { get; set; } |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
///
|
|
|
///
|
|
@ -2254,7 +2256,7 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
/// <param name="sheetName">页签名称</param>
|
|
|
/// <param name="sheetName">页签名称</param>
|
|
|
/// <param name="data">数据</param>
|
|
|
/// <param name="data">数据</param>
|
|
|
/// <param name="chunkSize">缓存文件行数</param>
|
|
|
/// <param name="chunkSize">缓存文件行数</param>
|
|
|
public static byte[] WriteDataToExcelInParallel(string sheetName, List<T> data, int chunkSize) |
|
|
public static async Task<string> WriteDataToExcelInParallel(string sheetName, List<T> data, int chunkSize) |
|
|
{ |
|
|
{ |
|
|
Stopwatch sw = Stopwatch.StartNew(); |
|
|
Stopwatch sw = Stopwatch.StartNew(); |
|
|
var count = data.Count / 1000000 + ((data.Count % 1000000) > 0 ? 1 : 0); |
|
|
var count = data.Count / 1000000 + ((data.Count % 1000000) > 0 ? 1 : 0); |
|
@ -2262,7 +2264,7 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
{ |
|
|
{ |
|
|
var datas = data.Skip((i - 1) * 1000000).Take(1000000).ToList(); |
|
|
var datas = data.Skip((i - 1) * 1000000).Take(1000000).ToList(); |
|
|
var chunks = datas.ChunkBy(chunkSize); |
|
|
var chunks = datas.ChunkBy(chunkSize); |
|
|
Parallel.ForEach(chunks, chunk => |
|
|
Parallel.ForEach(chunks, async chunk => |
|
|
{ |
|
|
{ |
|
|
var fileName = $"{sheetName}_{i - 1}_{Guid.NewGuid()}.xlsx"; |
|
|
var fileName = $"{sheetName}_{i - 1}_{Guid.NewGuid()}.xlsx"; |
|
|
var fileinfogroup = new FileInfoGroup((fileName), $"{sheetName}_{i - 1}"); |
|
|
var fileinfogroup = new FileInfoGroup((fileName), $"{sheetName}_{i - 1}"); |
|
@ -2271,15 +2273,7 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
string[] filePaths = excelFiles.Select(x => x.FileName).ToArray(); |
|
|
string[] filePaths = excelFiles.Select(x => x.FileName).ToArray(); |
|
|
|
|
|
string zipPath = $"{sheetName}_{Guid.NewGuid()}.zip"; |
|
|
// 指定ZIP文件的输出路径
|
|
|
|
|
|
string zipPath = $"{Guid.NewGuid()}.zip"; |
|
|
|
|
|
|
|
|
|
|
|
// 使用ZipFile.CreateFromDirectory方法压缩文件
|
|
|
|
|
|
|
|
|
|
|
|
// ZipFile.CreateFromDirectory(string.Empty, zipPath, CompressionLevel.Fastest, false, null);
|
|
|
|
|
|
|
|
|
|
|
|
// 或者使用ZipFile.CreateFromDirectory方法压缩指定文件
|
|
|
|
|
|
using (var archive = ZipFile.Open(zipPath, ZipArchiveMode.Create)) |
|
|
using (var archive = ZipFile.Open(zipPath, ZipArchiveMode.Create)) |
|
|
{ |
|
|
{ |
|
|
foreach (var file in filePaths) |
|
|
foreach (var file in filePaths) |
|
@ -2290,24 +2284,38 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//for (var i = 0; i < count; i++)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < count; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
var filelist = excelFiles.Where(p => p.Grpup == $"{sheetName}_{i}").Select(p => p.FileName).ToList(); |
|
|
|
|
|
//MergeExcelFiles(filelist.ToArray(), $"{sheetName}.xlsx",filelist.First());
|
|
|
|
|
|
//foreach (var file in filelist)
|
|
|
|
|
|
//{
|
|
|
//{
|
|
|
// File.Delete(file);
|
|
|
// var filelist = excelFiles.Where(p => p.Grpup == $"{sheetName}_{i}").Select(p => p.FileName).ToList();
|
|
|
|
|
|
// //MergeExcelFiles(filelist.ToArray(), $"{sheetName}.xlsx",filelist.First());
|
|
|
|
|
|
// //foreach (var file in filelist)
|
|
|
|
|
|
// //{
|
|
|
|
|
|
// // File.Delete(file);
|
|
|
|
|
|
// //}
|
|
|
//}
|
|
|
//}
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sw.Stop(); |
|
|
sw.Stop(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using (FileStream fileStream = new FileStream(zipPath, FileMode.Open)) |
|
|
using (FileStream fileStream = new FileStream(zipPath, FileMode.Open)) |
|
|
{ |
|
|
{ |
|
|
return fileStream.GetAllBytes(); |
|
|
var minioClient = new MinioClient(EndPoint, AccessKey, SecretKey, ""); |
|
|
|
|
|
try |
|
|
|
|
|
{ |
|
|
|
|
|
await minioClient.PutObjectAsync(BucketName,zipPath, fileStream,fileStream.Length, "application/zip").ConfigureAwait(false); |
|
|
} |
|
|
} |
|
|
|
|
|
catch (Exception ex) |
|
|
|
|
|
{ |
|
|
|
|
|
// Console.WriteLine($"上传文件到 MinIO 时发生错误: {ex.Message}");
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
Thread.Sleep(10000); |
|
|
|
|
|
|
|
|
|
|
|
return zipPath; |
|
|
|
|
|
//using (FileStream fileStream = new FileStream(zipPath, FileMode.Open))
|
|
|
|
|
|
//{
|
|
|
|
|
|
// return fileStream.GetAllBytes();
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|