Commit 659f7573 by ruyun.zhang@suvalue.com

Merge branch 'feature/在线浏览编辑Excel' into develop

parents 4467e5d3 4d573014
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Performance.DtoModels;
using Performance.Services;
using Performance.Services.OnlineExcel;
namespace Performance.Api.Controllers
{
[Route("api/online/excel")]
[ApiController]
public class OnlineExcelController : Controller
{
private readonly AllotService _allotService;
private readonly OnlineExcelService _excelService;
public OnlineExcelController(
AllotService allotService,
OnlineExcelService excelService)
{
_allotService = allotService;
_excelService = excelService;
}
[Route("sheet/name")]
[HttpGet]
[AllowAnonymous]
public ApiResponse SheetName(int allotId)
{
var allot = _allotService.GetAllot(allotId);
if (allot == null)
return new ApiResponse(ResponseType.Fail, "当前绩效信息无效", "当前绩效信息无效");
var sheetNames = _excelService.GetExcelSheetName(allot);
if (sheetNames == null || sheetNames.Count == 0)
return new ApiResponse(ResponseType.Fail, "未能找到有效[SHEET]", "未能找到有效[SHEET]");
return new ApiResponse(ResponseType.OK, sheetNames);
}
[Route("sheet/data")]
[HttpGet]
[AllowAnonymous]
public ApiResponse SheetName(int allotId, string sheetName)
{
var allot = _allotService.GetAllot(allotId);
if (allot == null)
return new ApiResponse(ResponseType.Fail, "当前绩效信息无效", "当前绩效信息无效");
var s = _excelService.ReadSheet(allot, sheetName);
return new ApiResponse(ResponseType.OK, "", JsonConvert.SerializeObject(s, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
}
[Route("sheet/chanage/{allotId}")]
[HttpPost]
[AllowAnonymous]
public ApiResponse WriteSheet(int allotId, [FromBody] EpChanage chanage)
{
var allot = _allotService.GetAllot(allotId);
if (allot == null)
return new ApiResponse(ResponseType.Fail, "当前绩效信息无效", "当前绩效信息无效");
_excelService.WriteSheet(allot, chanage);
return new ApiResponse(ResponseType.OK);
}
}
}
...@@ -2165,6 +2165,7 @@ ...@@ -2165,6 +2165,7 @@
<param name="query"></param> <param name="query"></param>
<returns></returns> <returns></returns>
</member> </member>
<<<<<<< HEAD
<member name="M:Performance.Api.BackgroundJob.Execute_Allot_Generate(Performance.Services.TaskService,Performance.EntityModels.bg_task)"> <member name="M:Performance.Api.BackgroundJob.Execute_Allot_Generate(Performance.Services.TaskService,Performance.EntityModels.bg_task)">
<summary> <summary>
生成测算表 生成测算表
...@@ -2200,11 +2201,14 @@ ...@@ -2200,11 +2201,14 @@
<param name="service"></param> <param name="service"></param>
<param name="tasks"></param> <param name="tasks"></param>
</member> </member>
=======
>>>>>>> 在线浏览编辑Excel
<member name="T:Performance.Api.ClearLoggerJob"> <member name="T:Performance.Api.ClearLoggerJob">
<summary> <summary>
删除历史日志 删除历史日志
</summary> </summary>
</member> </member>
<<<<<<< HEAD
<member name="T:Performance.Api.ExpirationLimitMiddleware"> <member name="T:Performance.Api.ExpirationLimitMiddleware">
<summary> <summary>
过期限制 过期限制
...@@ -2217,6 +2221,8 @@ ...@@ -2217,6 +2221,8 @@
<param name="builder"></param> <param name="builder"></param>
<returns></returns> <returns></returns>
</member> </member>
=======
>>>>>>> 在线浏览编辑Excel
<member name="M:Performance.Api.ClaimService.GetUserId"> <member name="M:Performance.Api.ClaimService.GetUserId">
<summary> <summary>
获取当前请求登录ID 获取当前请求登录ID
......
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Infrastructure
{
public static partial class UtilExtensions
{
/// <summary>
/// 时间戳计时开始时间
/// </summary>
private static DateTime timeStampStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
/// <summary>
/// DateTime转换为10位时间戳(单位:秒)
/// </summary>
/// <param name="dateTime"></param>
/// <returns></returns>
public static long ToTimeStamp(this DateTime dateTime)
{
return (long)(dateTime.ToUniversalTime() - timeStampStartTime).TotalSeconds;
}
/// <summary>
/// DateTime转换为13位时间戳(单位:毫秒)
/// </summary>
/// <param name="dateTime"> DateTime</param>
/// <returns>13位时间戳(单位:毫秒)</returns>
public static long ToLongTimeStamp(this DateTime dateTime)
{
return (long)(dateTime.ToUniversalTime() - timeStampStartTime).TotalMilliseconds;
}
/// <summary>
/// 10位时间戳(单位:秒)转换为DateTime
/// </summary>
/// <param name="timeStamp">10位时间戳(单位:秒)</param>
/// <returns>DateTime</returns>
public static DateTime ToDateTime(this long timeStamp)
{
return timeStampStartTime.AddSeconds(timeStamp).ToLocalTime();
}
/// <summary>
/// 13位时间戳(单位:毫秒)转换为DateTime
/// </summary>
/// <param name="longTimeStamp">13位时间戳(单位:毫秒)</param>
/// <returns>DateTime</returns>
public static DateTime ToDateTimeLongTimeStamp(this long longTimeStamp)
{
return timeStampStartTime.AddMilliseconds(longTimeStamp).ToLocalTime();
}
}
}
using System.Collections.Generic;
namespace Performance.Services.OnlineExcel
{
public class EpColumn
{
public int row { get; set; }
public int col { get; set; }
public string renderer { get; set; }
}
/// <summary>
/// 单元格Class
/// </summary>
public class EpCellClass
{
private List<string> _className;
public int row { get; set; }
public int col { get; set; }
public bool editor { get; set; }
public string className
{
get
{
if (_className == null)
return "";
return string.Join(" ", _className.ToArray());
}
}
public void AddClassName(string name)
{
if (_className == null)
_className = new List<string>();
_className.Add(name);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
namespace Performance.Services.OnlineExcel
{
public enum Operation
{
InsertRow = 1,
DeleteRow = 2,
InsertColumn = 3,
DeleteColumn = 4,
}
/// <summary>
/// 操作情况
/// </summary>
public class OperationRecord
{
public DateTime DateTime { get; set; }
public Operation Operation { get; set; }
public int From { get; set; }
public int Count { get; set; }
}
/// <summary>
/// 数据变更提交记录
/// </summary>
public class EpChanage
{
public string SheetName { get; set; }
public string Version { get; set; }
public OperationRecord[] OperationRecord { get; set; }
public List<dynamic> Data { get; set; }
}
}
\ No newline at end of file
namespace Performance.Services.OnlineExcel
{
/// <summary>
/// 边框(弃用 影响性能)
/// </summary>
public class EpCustomBorders
{
public int row { get; set; }
public int col { get; set; }
public Style left { get; set; }
public Style right { get; set; }
public Style top { get; set; }
public Style bottom { get; set; }
public class Style
{
public int width { get; set; }
public string color { get; set; }
}
}
}
\ No newline at end of file
namespace Performance.Services.OnlineExcel
{
/// <summary>
/// 单元格合并
/// </summary>
public class EpMerge
{
public int row { get; set; }
public int col { get; set; }
public int rowspan { get; set; }
public int colspan { get; set; }
}
}
\ No newline at end of file
using System.Collections.Generic;
namespace Performance.Services.OnlineExcel
{
/// <summary>
/// 加载Excel汇总信息
/// </summary>
public class EpSheet
{
public object renders { get; set; }
public object mergeCells { get; set; }
public object data { get; set; }
public object cell { get; set; }
public object colWidths { get; set; }
}
}
\ No newline at end of file
using Performance.DtoModels;
namespace Performance.Services.OnlineExcel
{
public partial class OnlineExcelService
{
public class ExcelSheetInfo
{
public string Name { get; set; }
public int Row { get; set; }
public int Column { get; set; }
public string Version { get; set; }
public string Message
{
get
{
if (Row * Column > 500 * 50)
return "数据量很大,加载需要较长时间";
else if (Row * Column > 100 * 50)
return "数据较多,可能需要较长加载时间";
return "";
}
}
public SheetType SheetType { get; internal set; }
public string ModuleName { get; internal set; }
}
}
}
\ No newline at end of file
using Newtonsoft.Json;
using OfficeOpenXml;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Performance.Services.OnlineExcel
{
public partial class OnlineExcelService
{
public static Dictionary<Operation, Action<ExcelWorksheet, int, int>> OperationMapps = new Dictionary<Operation, Action<ExcelWorksheet, int, int>>
{
{ Operation.InsertRow, (sheet,from,count) => sheet.InsertRow(from, count, from + 1) },
{ Operation.DeleteRow, (sheet,from,count) => sheet.DeleteRow(from, count) },
{ Operation.InsertColumn, (sheet,from,count) => sheet.InsertColumn(from, count, from + 1) },
{ Operation.DeleteColumn, (sheet,from,count) => sheet.DeleteColumn(from, count) },
};
private List<string> GetColumns()
{
var columns = new List<string> { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
List<string> newColumns = new List<string>(columns);
foreach (var column in columns)
{
foreach (var item in columns)
{
newColumns.Add($"{column}{item}");
}
}
return newColumns;
}
public void WriteSheet(per_allot allot, EpChanage chanage)
{
FileInfo file = new FileInfo(allot.Path);
if (file.LastWriteTimeUtc.ToTimeStamp().ToString() != chanage.Version)
throw new PerformanceException("您读取的文件已被其他人更改");
using (ExcelPackage package = new ExcelPackage(file))
{
foreach (var sheet in package.Workbook.Worksheets)
{
if (sheet.Name != chanage.SheetName) continue;
// 新增删除 行 列 信息
if (chanage.OperationRecord != null && chanage.OperationRecord.Length > 0)
{
foreach (var item in chanage.OperationRecord.Where(w => w.Count > 0).OrderBy(w => w.DateTime))
{
OperationMapps[item.Operation].Invoke(sheet, item.From, item.Count);
}
}
// 写入数据
var columns = GetColumns();
for (int row = 0; row < chanage.Data.Count; row++)
{
var tempData = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonConvert.SerializeObject(chanage.Data[row]));
foreach (var key in tempData.Keys)
{
var col = columns.IndexOf(key);
var cell = sheet.Cells[row + 1, col + 1];
if (!(cell.Value is ExcelErrorValue) && string.IsNullOrEmpty(cell.Formula))
cell.Value = tempData[key];
}
}
_cache.Remove($"SheetData-{chanage.SheetName}:{allot.Path}");
}
package.Save();
}
}
}
}
\ No newline at end of file
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
<PackageReference Include="FluentScheduler" Version="5.5.1" /> <PackageReference Include="FluentScheduler" Version="5.5.1" />
<PackageReference Include="GraphQL" Version="2.4.0" /> <PackageReference Include="GraphQL" Version="2.4.0" />
<PackageReference Include="MassTransit.AspNetCore" Version="7.2.4" /> <PackageReference Include="MassTransit.AspNetCore" Version="7.2.4" />
<PackageReference Include="Polly" Version="7.2.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment