|
|
@ -1,10 +1,12 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Concurrent; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.ComponentModel.DataAnnotations; |
|
|
|
using System.Data.SqlClient; |
|
|
|
using System.Diagnostics; |
|
|
|
using System.Globalization; |
|
|
|
using System.IO; |
|
|
|
using System.IO.Compression; |
|
|
|
using System.Linq; |
|
|
|
using System.Linq.Dynamic.Core; |
|
|
|
using System.Reflection; |
|
|
@ -14,6 +16,7 @@ using AutoMapper; |
|
|
|
using ClosedXML.Excel; |
|
|
|
using Dapper; |
|
|
|
using DocumentFormat.OpenXml; |
|
|
|
using DocumentFormat.OpenXml.Spreadsheet; |
|
|
|
using DocumentFormat.OpenXml.Wordprocessing; |
|
|
|
using EFCore.BulkExtensions; |
|
|
|
using LinqToDB.EntityFrameworkCore; |
|
|
@ -30,6 +33,8 @@ using Microsoft.EntityFrameworkCore; |
|
|
|
using Microsoft.Extensions.Configuration; |
|
|
|
using Microsoft.Extensions.DependencyInjection; |
|
|
|
using Microsoft.Extensions.Logging; |
|
|
|
using NPOI.SS.UserModel; |
|
|
|
using NPOI.XSSF.UserModel; |
|
|
|
using Omu.ValueInjecter; |
|
|
|
using Org.BouncyCastle.Asn1.Cmp; |
|
|
|
using RestSharp.Extensions; |
|
|
@ -245,6 +250,13 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
|
input.Sorting= input.Sorting.ToUpper().Replace("BillTime".ToUpper(), "ReceiveTime".ToUpper()) |
|
|
|
.Replace("Qty".ToUpper(), "SumQty".ToUpper()); |
|
|
|
} |
|
|
|
//var filterConditions = input.Filters.Where(p => p.Column == "SumQty");
|
|
|
|
//foreach (var itm in filterConditions)
|
|
|
|
//{
|
|
|
|
// if(itm)
|
|
|
|
// input.Filters.Add(new FilterCondition() { });
|
|
|
|
//}
|
|
|
|
|
|
|
|
var first = input.Filters.FirstOrDefault(p => p.Column == "BillTime"); |
|
|
|
if (first != null) |
|
|
|
{ |
|
|
@ -278,6 +290,17 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
|
var result = await _exportImporter.ExcelExporter(dtos).ConfigureAwait(false); |
|
|
|
result.ShouldNotBeNull(); |
|
|
|
await _excelImportService.SaveBlobAsync(new SaveExcelImportInputDto { Name = fileName, Content = result }).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// var content= ExtendExcel<VmiBalanceSumDetailDto>.WriteDataToExcelInParallel( "库存余额", dtos, 500000);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return fileName; |
|
|
|
} |
|
|
|
|
|
|
@ -2178,6 +2201,203 @@ namespace Win.Sfs.SettleAccount.Entities.BQ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 扩展方法类,用于为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 FileInfoGroup(string fileName, string grpup) |
|
|
|
{ |
|
|
|
FileName = fileName; |
|
|
|
Grpup = grpup; |
|
|
|
} |
|
|
|
|
|
|
|
public string FileName { get; set; } |
|
|
|
public string Grpup { get; set; } |
|
|
|
} |
|
|
|
|
|
|
|
public class ExtendExcel<T> where T : class, new() |
|
|
|
{ |
|
|
|
|
|
|
|
static ConcurrentBag<FileInfoGroup> excelFiles = new ConcurrentBag<FileInfoGroup>(); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="sheetName">页签名称</param>
|
|
|
|
/// <param name="data">数据</param>
|
|
|
|
/// <param name="chunkSize">缓存文件行数</param>
|
|
|
|
public static byte[] WriteDataToExcelInParallel(string sheetName, List<T> data, int chunkSize) |
|
|
|
{ |
|
|
|
Stopwatch sw = Stopwatch.StartNew(); |
|
|
|
var count = data.Count / 1000000 + ((data.Count % 1000000) > 0 ? 1 : 0); |
|
|
|
for (var i = 1; i <= count; i++) |
|
|
|
{ |
|
|
|
var datas = data.Skip((i - 1) * 1000000).Take(1000000).ToList(); |
|
|
|
var chunks = datas.ChunkBy(chunkSize); |
|
|
|
Parallel.ForEach(chunks, chunk => |
|
|
|
{ |
|
|
|
var fileName = $"{sheetName}_{i - 1}_{Guid.NewGuid()}.xlsx"; |
|
|
|
var fileinfogroup = new FileInfoGroup((fileName), $"{sheetName}_{i - 1}"); |
|
|
|
WriteDataToExcel(chunk.ToList(), fileName); |
|
|
|
excelFiles.Add(fileinfogroup); |
|
|
|
}); |
|
|
|
} |
|
|
|
string[] filePaths = excelFiles.Select(x => x.FileName).ToArray(); |
|
|
|
|
|
|
|
// 指定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)) |
|
|
|
{ |
|
|
|
foreach (var file in filePaths) |
|
|
|
{ |
|
|
|
archive.CreateEntryFromFile(file, Path.GetFileName(file)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
//}
|
|
|
|
} |
|
|
|
|
|
|
|
sw.Stop(); |
|
|
|
using (FileStream fileStream = new FileStream(zipPath, FileMode.Open)) |
|
|
|
{ |
|
|
|
return fileStream.GetAllBytes(); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void WriteDataToExcel(List<T> data, string fileName) |
|
|
|
{ |
|
|
|
IWorkbook workbook = new XSSFWorkbook(); |
|
|
|
ISheet sheet = workbook.CreateSheet("Sheet1"); |
|
|
|
var firist = data.FirstOrDefault(); |
|
|
|
var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty) |
|
|
|
.Where(o => o.GetAttributes<ExporterHeaderAttribute>().Any() || o.GetAttributes<DisplayAttribute>().Any()) |
|
|
|
.ToDictionary(o => o.GetAttribute<ExporterHeaderAttribute>()?.DisplayName ?? o.GetAttribute<DisplayAttribute>()?.Name, o => o); |
|
|
|
int columnCellIndex = 0; |
|
|
|
int rowIndex = 1; |
|
|
|
IRow headerRow = sheet.CreateRow(0); |
|
|
|
foreach (var property in properties) |
|
|
|
{ |
|
|
|
headerRow.CreateCell(columnCellIndex).SetCellValue(property.Key); |
|
|
|
columnCellIndex++; |
|
|
|
} |
|
|
|
foreach (var item in data) |
|
|
|
{ |
|
|
|
IRow row = sheet.CreateRow(rowIndex++); |
|
|
|
int cellIndex = 0; |
|
|
|
foreach (var property in item.GetType().GetProperties()) |
|
|
|
{ |
|
|
|
ICell cell = row.CreateCell(cellIndex++); |
|
|
|
cell.SetCellValue(property.GetValue(item)?.ToString()); |
|
|
|
} |
|
|
|
} |
|
|
|
using (FileStream fileStream = new FileStream(fileName, FileMode.Create)) |
|
|
|
{ |
|
|
|
workbook.Write(fileStream); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static void MergeExcelFiles(string[] filePaths, string outputFilePath, string sheetName) |
|
|
|
{ |
|
|
|
|
|
|
|
IWorkbook workbook = new XSSFWorkbook(); |
|
|
|
ISheet sheet = workbook.CreateSheet(sheetName); |
|
|
|
|
|
|
|
|
|
|
|
int rowIndex = 0; |
|
|
|
foreach (string filePath in filePaths) |
|
|
|
{ |
|
|
|
using (FileStream fileStream = new FileStream(filePath, FileMode.Open)) |
|
|
|
{ |
|
|
|
IWorkbook sourceWorkbook = new XSSFWorkbook(fileStream); |
|
|
|
ISheet sourceSheet = sourceWorkbook.GetSheetAt(0); |
|
|
|
|
|
|
|
int sourceRowCount = sourceSheet.LastRowNum; |
|
|
|
for (int i = 0; i <= sourceRowCount; i++) |
|
|
|
{ |
|
|
|
IRow sourceRow = sourceSheet.GetRow(i); |
|
|
|
if (sourceRow != null) |
|
|
|
{ |
|
|
|
IRow targetRow = sheet.CreateRow(rowIndex++); |
|
|
|
int cellCount = sourceRow.LastCellNum; |
|
|
|
for (int j = 0; j < cellCount; j++) |
|
|
|
{ |
|
|
|
ICell sourceCell = sourceRow.GetCell(j); |
|
|
|
if (sourceCell != null) |
|
|
|
{ |
|
|
|
ICell targetCell = targetRow.CreateCell(j); |
|
|
|
targetCell.SetCellValue(sourceCell.ToString()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (File.Exists(outputFilePath)) |
|
|
|
{ |
|
|
|
using (FileStream fileStream = new FileStream(outputFilePath, FileMode.Open, FileAccess.ReadWrite)) |
|
|
|
{ |
|
|
|
workbook.Write(fileStream); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
using (FileStream fileStream = new FileStream(outputFilePath, FileMode.Create)) |
|
|
|
{ |
|
|
|
workbook.Write(fileStream); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|