Commit da17812e by lcx

Merge branch 'newcollect&extracr' into v2020morge

# Conflicts:
#	performance/Performance.EntityModels/Entity/ex_script.cs
parents f2b97710 84bbf135
......@@ -1435,6 +1435,11 @@
数据开始行
</summary>
</member>
<member name="P:Performance.DtoModels.PerSheetPoint.DataFirstCellNum">
<summary>
数据开始列
</summary>
</member>
<member name="P:Performance.DtoModels.PerSheetPoint.TotalCellNum">
<summary>
汇总列
......
......@@ -25,6 +25,10 @@ public class PerSheetPoint
/// 数据开始行
/// </summary>
public int? DataFirstRowNum { get; set; }
/// <summary>
/// 数据开始列
/// </summary>
public int? DataFirstCellNum { get; set; }
public List<AccountingUnit> AccountingUnit { get; set; }
/// <summary>
......
......@@ -10,6 +10,7 @@
using Performance.DtoModels.AppSettings;
using Performance.Infrastructure;
using Performance.Services;
using Performance.Services.ExtractExcelService;
using System;
using System.Collections.Generic;
using System.IO;
......@@ -23,17 +24,20 @@ public class ExtractController : Controller
{
private readonly DFExtractService extractService;
private readonly HospitalService hospitalService;
private readonly ExtractService extractService1;
private readonly WebapiUrl url;
private readonly ILogger<ExtractController> logger;
private readonly IHostingEnvironment evn;
public ExtractController(DFExtractService extractService,
HospitalService hospitalService,
ExtractService extractService1,
IOptions<WebapiUrl> url,
ILogger<ExtractController> logger,
IHostingEnvironment evn)
{
this.extractService = extractService;
this.hospitalService = hospitalService;
this.extractService1 = extractService1;
this.url = url.Value;
this.logger = logger;
this.evn = evn;
......@@ -149,7 +153,8 @@ public void ExtractData([FromForm] IFormCollection form, int allotId, int hospit
#endregion
//string filePath = newExtractService.ExtractData(allotId, request.Email, hospitalId);
string filePath = extractService.ExtractData(allotId, email, hospitalId, "User" + userId, path); //抽取
//string filePath = extractService.ExtractData(allotId, email, hospitalId, "User" + userId, path); //抽取
string filePath = extractService1.Main(allotId, hospitalId, email, "User" + userId, path);
#region 保存文件到网站下
......
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class ExcelHeader
{
/// <summary>
/// Excel 列名
/// </summary>
public string ColumnName { get; set; }
/// <summary>
/// 护理组系数
/// </summary>
public decimal NurseFactor { get; set; }
/// <summary>
/// 医生组系数
/// </summary>
public decimal DoctorFactor { get; set; }
/// <summary>
/// 医技组系数
/// </summary>
public decimal TechnicianFactor { get; set; }
/// <summary>
/// 工作量系数
/// </summary>
public decimal WorkloadFactor { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
/// <summary>
/// 抽取结果(转换核算单元后)
/// </summary>
public class ExtractTransDto
{
/// <summary>
/// 医生姓名
/// </summary>
public string DoctorName { get; set; }
/// <summary>
/// 医生工号
/// </summary>
public string PersonnelNumber { get; set; }
/// <summary>
/// 科室
/// </summary>
public string Department { get; set; }
/// <summary>
/// 费用类别
/// </summary>
public string Category { get; set; }
/// <summary>
/// 费用
/// </summary>
public decimal? Value { get; set; }
/// <summary>
///
/// </summary>
public string SheetName { get; set; }
/// <summary>
/// 核算单元(门诊医生)
/// </summary>
public string OutDoctorAccounting { get; set; }
/// <summary>
/// 核算单元(门诊护理)
/// </summary>
public string OutNurseAccounting { get; set; }
/// <summary>
/// 核算单元(门诊医技)
/// </summary>
public string OutTechnicAccounting { get; set; }
/// <summary>
/// 核算单元(住院医生)
/// </summary>
public string InpatDoctorAccounting { get; set; }
/// <summary>
/// 核算单元(住院护理)
/// </summary>
public string InpatNurseAccounting { get; set; }
/// <summary>
/// 核算单元(住院医技)
/// </summary>
public string InpatTechnicAccounting { get; set; }
}
}
using NPOI.SS.Util;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class SpecialCellRange : CellRangeAddress
{
public SpecialCellRange(CellRangeAddress address)
: base(address.FirstRow, address.LastRow, address.FirstColumn, address.LastColumn)
{
}
public string Single { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class SpecialDto
{
/// <summary>
/// 科室
/// </summary>
public string Department { get; set; }
/// <summary>
/// 量化指标
/// </summary>
public string Target { get; set; }
/// <summary>
/// 量化指标绩效分值
/// </summary>
public decimal? TargetFactor { get; set; }
/// <summary>
/// 调节系数
/// </summary>
public decimal? AdjustFactor { get; set; }
/// <summary>
/// 数量
/// </summary>
public decimal? Quantity { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class SpecialUnitColumns
{
public const string Department = "科室";
public const string PeopleNumber = "人数";
public const string Target = "量化指标";
public const string Quantity = "数量";
public const string TargetFactor = "量化指标绩效分值";
public const string AdjustFactor = "调节系数";
}
}
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Performance.DtoModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Performance.Services.ExtractExcelService
{
public static class ExcelHelper
{
public static IRow GetOrCreate(this ISheet sheet, int index)
{
var row = sheet.GetRow(index);
if (row == null)
row = sheet.CreateRow(index);
return row;
}
public static ICell GetOrCreate(this IRow row, int index)
{
var cell = row.GetCell(index);
if (cell == null)
cell = row.CreateCell(index);
return cell;
}
public static void SetRowStyle(this IRow row, ICellStyle cellStyle)
{
List<ICell> cells = row.Cells;
foreach (var cell in cells)
{
cell.CellStyle = cellStyle;
}
}
public static void SetCellValue<T>(this ICell cell, object value, T defaultValue = default)
{
if (cell == null) return;
try
{
switch (typeof(T).ToString())
{
#region SetValue
case "System.String"://字符串类型
cell.SetCellValue(ConvertHelper.To<string>(value));
break;
case "System.DateTime"://日期类型
cell.SetCellValue(ConvertHelper.To<DateTime>(value).ToString("yyyy/M/d"));
break;
case "System.Boolean"://布尔型
cell.SetCellValue(ConvertHelper.To<bool>(value));
break;
case "System.Int16"://整型
case "System.Int32":
case "System.Int64":
case "System.Byte":
cell.SetCellValue(ConvertHelper.To<int>(value));
break;
case "System.Decimal"://浮点型
case "System.Double":
cell.SetCellValue(ConvertHelper.To<double>(value));
break;
case "System.DBNull"://空值处理
default:
cell.SetCellValue("");
break;
#endregion
}
}
catch
{
cell.SetCellValue("");
}
}
public static void SetCellOValue(this ICell cell, object value)
{
if (cell == null) return;
if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
{
cell.SetCellValue("");
return;
}
try
{
string stringV = value.ToString().Trim();
var type = value.GetType();
switch (type.ToString())
{
#region SetValue
case "System.String"://字符串类型
cell.SetCellValue(stringV);
break;
case "System.DateTime"://日期类型
DateTime dateV;
DateTime.TryParse(stringV, out dateV);
cell.SetCellValue(dateV.ToString("yyyy/M/d"));
break;
case "System.Boolean"://布尔型
bool boolV = false;
bool.TryParse(stringV, out boolV);
cell.SetCellValue(boolV);
break;
case "System.Int16"://整型
case "System.Int32":
case "System.Int64":
case "System.Byte":
int intV = 0;
int.TryParse(stringV, out intV);
cell.SetCellValue(intV);
break;
case "System.Decimal"://浮点型
case "System.Double":
double doubV = 0;
double.TryParse(stringV, out doubV);
cell.SetCellValue(doubV);
break;
case "System.DBNull"://空值处理
cell.SetCellValue("");
break;
default:
cell.SetCellValue("");
break;
#endregion
}
}
catch
{
cell.SetCellValue("");
}
}
public static T GetCellValue<T>(this ICell cell)
{
try
{
cell.SetCellType(CellType.String);
string value = cell.StringCellValue;
return ConvertHelper.To<T>(value);
}
catch
{
return default;
}
}
/// <summary>
/// 获取去除转义后的字符
/// </summary>
/// <param name="cell"></param>
/// <returns></returns>
public static string GetDecodeEscapes(this ICell cell)
{
try
{
if (cell == null) return "";
cell.SetCellType(CellType.String);
string value = cell.StringCellValue;
if (!string.IsNullOrEmpty(value))
value = value.Replace("\n", "").Replace(" ", "").Trim();
return value;
}
catch
{
return "";
}
}
public static string NoBlank(this string @string)
{
if (string.IsNullOrEmpty(@string))
return "";
return @string.Replace("\n", "").Replace(" ", "").Trim();
}
public static IWorkbook GetWorkbook(string filePath)
{
IWorkbook workbook = null;
if (string.IsNullOrEmpty(filePath)) return workbook;
var version = FileHelper.GetExtension(filePath) == ".xlsx" ? ExcelVersion.xlsx : ExcelVersion.xls;
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
workbook = (version == ExcelVersion.xlsx)
? (IWorkbook)(new XSSFWorkbook(fs))
: (IWorkbook)(new HSSFWorkbook(fs));
}
return workbook;
}
public static List<string> GetCellValues(this IRow row)
{
List<string> list = new List<string>();
if (row == null || row.Cells == null || !row.Cells.Any()) return list;
list = row.Cells.Select(t => t.GetDecodeEscapes()).ToList();
return list;
}
public static Dictionary<string, int> GetCellIndex(this IRow row, params string[] list)
{
Dictionary<string, int> pairs = new Dictionary<string, int>();
if (row == null || row.Cells == null || !row.Cells.Any()) return pairs;
if (list == null || !list.Any()) return pairs;
var columns = row.Cells.Select(t => t.GetDecodeEscapes()).Distinct().ToList();
foreach (string key in list)
{
if (!pairs.ContainsKey(key) && columns.Contains(key))
{
pairs.Add(key, columns.IndexOf(key));
}
}
return pairs;
}
}
}
using NPOI.HSSF.Util;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class ExcelStyle
{
private readonly IWorkbook workbook;
public ExcelStyle(IWorkbook workbook)
{
this.workbook = workbook ?? throw new ArgumentNullException(nameof(IWorkbook));
}
public ICellStyle GetEmptyCellStyle()
{
return workbook.CreateCellStyle();
}
public ICellStyle GetCellStyle()
{
ICellStyle cellStyle = workbook.CreateCellStyle();
SetFont(cellStyle);
SetBorder(cellStyle);
SetAlignment(cellStyle);
return cellStyle;
}
public void SetFont(ICellStyle cellStyle, short fontSize = 11, string fontName = "微软雅黑", short fontColor = HSSFColor.Black.Index)
{
//字体
IFont font = workbook.CreateFont();
font.FontHeightInPoints = fontSize;
font.FontName = fontName;
font.Color = fontColor;
cellStyle.SetFont(font);
}
public void SetBorder(ICellStyle cellStyle, BorderStyle borderStyle = BorderStyle.Thin, short borderColor = HSSFColor.Black.Index)
{
//边框
cellStyle.BorderBottom = borderStyle;
cellStyle.BorderLeft = borderStyle;
cellStyle.BorderRight = borderStyle;
cellStyle.BorderTop = borderStyle;
//边框颜色
cellStyle.BottomBorderColor = borderColor;
cellStyle.TopBorderColor = borderColor;
cellStyle.LeftBorderColor = borderColor;
cellStyle.RightBorderColor = borderColor;
}
public void SetAlignment(ICellStyle cellStyle, HorizontalAlignment horizontal = HorizontalAlignment.Center, VerticalAlignment vertical = VerticalAlignment.Center)
{
//水平居中
cellStyle.Alignment = horizontal;
//垂直居中
cellStyle.VerticalAlignment = vertical;
}
public void SetBackgroundColor(ICellStyle cellStyle, short foregroundColor)
{
cellStyle.FillForegroundColor = foregroundColor;
cellStyle.FillPattern = FillPattern.SolidForeground;
}
public ICellStyle SetBgkColorAndFormat(ICellStyle cellStyle, StyleType type = StyleType.默认, CellFormat format = CellFormat.默认)
{
SetBackgroundColor(cellStyle, type);
if (format != CellFormat.默认) SetDataFormat(cellStyle, format);
return cellStyle;
}
private void SetBackgroundColor(ICellStyle cellStyle, StyleType type)
{
switch (type)
{
case StyleType.列头:
cellStyle.FillForegroundColor = HSSFColor.Gold.Index;
cellStyle.FillPattern = FillPattern.SolidForeground;
break;
case StyleType.系数:
cellStyle.FillForegroundColor = HSSFColor.Green.Index;
cellStyle.FillPattern = FillPattern.SolidForeground;
break;
case StyleType.数据:
cellStyle.FillForegroundColor = HSSFColor.SkyBlue.Index;
cellStyle.FillPattern = FillPattern.SolidForeground;
break;
case StyleType.Remove:
cellStyle.FillForegroundColor = HSSFColor.Orange.Index;
cellStyle.FillPattern = FillPattern.SolidForeground;
break;
case StyleType.默认:
default:
cellStyle.FillForegroundColor = HSSFColor.White.Index;
cellStyle.FillPattern = FillPattern.SolidForeground;
break;
}
}
private void SetDataFormat(ICellStyle cellStyle, CellFormat format)
{
IDataFormat datastyle = workbook.CreateDataFormat();
switch (format)
{
case CellFormat.时间:
cellStyle.DataFormat = datastyle.GetFormat("yyyy/mm/dd");
break;
case CellFormat.数字:
cellStyle.DataFormat = datastyle.GetFormat("0");
break;
case CellFormat.数字2:
cellStyle.DataFormat = datastyle.GetFormat("0.00");
break;
case CellFormat.百分比:
cellStyle.DataFormat = datastyle.GetFormat("0%");
break;
case CellFormat.百分比2:
cellStyle.DataFormat = datastyle.GetFormat("0.00%");
break;
case CellFormat.默认:
default:
break;
}
}
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class ExtractHelper
{
public static string GetExtractFile(int hospitalId, ref string newFilePath, string allotFilePath = "")
{
string originalPath = string.IsNullOrEmpty(allotFilePath)
? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院绩效模板.xls")
: allotFilePath;
var (tempPath, filePath) = CopyOriginalFile(hospitalId, originalPath);
newFilePath = filePath;
return tempPath;
}
private static (string TempPath, string FilePath) CopyOriginalFile(int hospitalId, string originalPath)
{
var ext = FileHelper.GetExtension(originalPath);
var dpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", $"{hospitalId}", "autoextract");
FileHelper.CreateDirectory(dpath);
string tempPath = Path.Combine(dpath, $"Template{DateTime.Now.ToString("yyyyMMddHHmmssfff")}{ext}");
FileHelper.Copy(originalPath, tempPath);
string filePath = Path.Combine(dpath, $"绩效提取数据{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xls");
return (tempPath, filePath);
}
public static void CreateNotExistSheet(List<ex_module> modulesList, IWorkbook workbook)
{
SortedDictionary<string, int> pairs = new SortedDictionary<string, int>();
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
var sheetname = workbook.GetSheetAt(i).SheetName;
if (!pairs.Keys.Contains(sheetname))
pairs.Add(workbook.GetSheetAt(i).SheetName, i);
}
int sheetIndex = 0;
int newSheetCount = 0;
foreach (var module in modulesList.Where(t => t.SheetType == (int)SheetType.Income)?.OrderBy(t => t.ModuleName))
{
var sheet = workbook.GetSheet(module.ModuleName);
if (sheet == null)
{
string[] keyArray = new string[] { "开单", "执行" };
if (keyArray.Any(key => module.ModuleName.Contains(key)))
{
var item = pairs.Where(t => t.Key.StartsWith("1.")).OrderByDescending(t => t.Key).First();
if (sheetIndex == 0)
sheetIndex = item.Value + 1;
var copysheet = workbook.GetSheet(item.Key);
var newSheet = copysheet.CopySheet(module.ModuleName, true);
workbook.SetSheetOrder(newSheet.SheetName, sheetIndex);
sheetIndex++; newSheetCount++;
}
}
}
sheetIndex = 0;
foreach (var module in modulesList.Where(t => t.SheetType == (int)SheetType.Workload)?.OrderBy(t => t.ModuleName))
{
var sheet = workbook.GetSheet(module.ModuleName);
if (sheet == null)
{
string key = "工作量";
if (module.ModuleName.Contains(key))
{
var item = pairs.Where(t => t.Key.StartsWith("3.")).OrderByDescending(t => t.Key).First();
if (sheetIndex == 0)
sheetIndex = item.Value + newSheetCount + 1;
var copysheet = workbook.GetSheet(item.Key);
var newSheet = copysheet.CopySheet(module.ModuleName, true);
workbook.SetSheetOrder(newSheet.SheetName, sheetIndex);
sheetIndex++;
}
}
}
}
public static void ClearSheetPartialData(ISheet sheet, PerSheetPoint point, SheetType sheetType)
{
if (sheet == null)
return;
for (int i = point.DataFirstRowNum.Value; i < sheet.LastRowNum + 1; i++)
{
var row = sheet.GetRow(i);
if (row != null)
{
int dataFirstCellRowNum = point.DataFirstCellNum.Value;
//跳过核算单元和科室
for (int j = dataFirstCellRowNum; j < row.LastCellNum; j++)
{
var cell = row.GetCell(j);
if (cell != null && (cell.CellType != CellType.Formula || sheetType == SheetType.Income))
{
cell.RemoveCellComment();
row.RemoveCell(cell);
}
}
}
}
}
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class WriteDataHelper
{
public enum UnitType
{
护理组,
医生组,
医技组
}
public static void WriteSheetHeader(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<ExcelHeader> headers)
{
if (headers == null || !headers.Any()) return;
var columns = headers.Select(t => t).ToList();
// 收入支出系数
var nurseFactor = sheet.GetOrCreate(point.AccountingUnit.FirstOrDefault(t => t.UnitType == UnitType.护理组.ToString())?.FactorRow.Value ?? 0);
var doctorFactor = sheet.GetOrCreate(point.AccountingUnit.FirstOrDefault(t => t.UnitType == UnitType.医生组.ToString())?.FactorRow.Value ?? 0);
var technicianFactor = sheet.GetOrCreate(point.AccountingUnit.FirstOrDefault(t => t.UnitType == UnitType.医技组.ToString())?.FactorRow.Value ?? 0);
// 费用类型
var columnHeader = sheet.GetOrCreate(point.HeaderFirstRowNum.Value);
// 工作量系数
var workloadFactor = sheet.GetOrCreate(point.HeaderFirstRowNum.Value + 1);
// 去除excel中已存在的列
int headerFirstCellNum = point.DataFirstCellNum.Value;
if (columnHeader.LastCellNum > point.DataFirstCellNum)
{
for (int index = headerFirstCellNum; index < columnHeader.LastCellNum; index++)
{
var column = columnHeader.GetCell(index).GetDecodeEscapes();
if (string.IsNullOrEmpty(column)) continue;
columns.RemoveAll(t => t.ColumnName == column);
if (index > headerFirstCellNum)
headerFirstCellNum = index + 1;
}
}
if (columns == null || !columns.Any()) return;
var factorStyle = sheetType == SheetType.Workload
? style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.系数, CellFormat.数字)
: style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.系数, CellFormat.百分比);
var columnStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.列头);
// 补充excel中不存在的列
foreach (var item in columns)
{
var columnCell = columnHeader.GetOrCreate(headerFirstCellNum);
columnCell.SetCellValue(item.ColumnName);
columnCell.CellStyle = columnStyle;
if (sheetType == SheetType.Workload)
{
var workloadCell = workloadFactor.GetOrCreate(headerFirstCellNum);
workloadCell.SetCellValue<decimal>(item.WorkloadFactor);
workloadCell.CellStyle = factorStyle;
}
else
{
var doctorCell = doctorFactor.GetOrCreate(headerFirstCellNum);
doctorCell.SetCellValue<decimal>(item.DoctorFactor);
doctorCell.CellStyle = factorStyle;
var nurseCell = nurseFactor.GetOrCreate(headerFirstCellNum);
nurseCell.SetCellValue<decimal>(item.NurseFactor);
nurseCell.CellStyle = factorStyle;
var technicianCell = technicianFactor.GetOrCreate(headerFirstCellNum);
technicianCell.SetCellValue<decimal>(item.TechnicianFactor);
technicianCell.CellStyle = factorStyle;
}
headerFirstCellNum++;
}
}
#region ExtractData
public static void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<string> headers, List<ExtractTransDto> data)
{
var columnHeader = sheet.GetOrCreate(point.HeaderFirstRowNum.Value);
int dataFirstRowNum = point.DataFirstRowNum.Value;
WriteSheetDataExistent(sheet, columnHeader, point, sheetType, style, headers, data, ref dataFirstRowNum);
if (data == null || !data.Any(t => !string.IsNullOrEmpty(t.Department))) return;
WriteSheetDataNonexistent(sheet, columnHeader, point, sheetType, style, headers, data, dataFirstRowNum);
}
private static void WriteSheetDataExistent(ISheet sheet, IRow columnHeader, PerSheetPoint point, SheetType sheetType, ExcelStyle style,
List<string> headers, List<ExtractTransDto> data, ref int dataFirstRowNum)
{
if (sheet.LastRowNum <= dataFirstRowNum) return;
var cellStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.数据);
int dataFirstCellNum = point.DataFirstCellNum.Value;
for (int rowIndex = dataFirstRowNum; rowIndex < sheet.LastRowNum + 1; rowIndex++)
{
var row = sheet.GetRow(rowIndex);
if (row == null) continue;
string department = row.GetOrCreate(dataFirstCellNum - 1).GetDecodeEscapes();
if (string.IsNullOrEmpty(department)) continue;
var deptData = data.Where(t => t.Department == department);
if (deptData == null || !deptData.Any()) continue;
for (int cellIndex = dataFirstCellNum; cellIndex < columnHeader.LastCellNum; cellIndex++)
{
var column = columnHeader.GetOrCreate(cellIndex).GetDecodeEscapes();
var cell = row.GetOrCreate(cellIndex);
var value = deptData.FirstOrDefault(t => t.Category == column)?.Value;
var notWrite = !value.HasValue && !string.IsNullOrEmpty(cell.GetDecodeEscapes());
if (sheetType == SheetType.Income)
{
cell.SetCellValue<decimal>(value);
cell.CellStyle = cellStyle;
}
else if (cell.CellType != CellType.Formula && !notWrite)
{
cell.SetCellValue<decimal>(value);
if (headers != null && headers.Contains(column))
{
cell.CellStyle = cellStyle;
}
}
}
data.RemoveAll(t => t.Department == department);
if (rowIndex > dataFirstRowNum) dataFirstRowNum = rowIndex + 1;
}
}
private static void WriteSheetDataNonexistent(ISheet sheet, IRow columnHeader, PerSheetPoint point, SheetType sheetType, ExcelStyle style,
List<string> headers, List<ExtractTransDto> data, int dataFirstRowNum)
{
var departments = data.Select(s => s.Department).Where(w => !string.IsNullOrEmpty(w)).Distinct().ToList();
var filed = sheet.SheetName.Contains("住院") ? fieldInpat : fieldOut;
if (sheet.SheetName.Contains("工作量"))
{
filed = sheet.SheetName.Contains("医生") ? fieldDoctor : fieldNurse;
}
var deptStyle = style.GetCellStyle();
var cellStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.数据);
foreach (string department in departments)
{
var deptData = data.Where(t => t.Department == department);
if (deptData == null || !deptData.Any()) continue;
var row = sheet.GetOrCreate(dataFirstRowNum);
for (int cellIndex = point.HeaderFirstCellNum.Value; cellIndex < columnHeader.LastCellNum; cellIndex++)
{
var column = columnHeader.GetCell(cellIndex).GetDecodeEscapes();
var cell = row.CreateCell(cellIndex);
if (filed.ContainsKey(column))
{
cell.SetCellOValue(filed[column]?.Invoke(deptData.First()));
cell.CellStyle = deptStyle;
}
else if (sheetType == SheetType.Income || (headers != null && headers.Contains(column)))
{
var value = deptData.FirstOrDefault(t => t.Category == column)?.Value;
cell.SetCellValue<decimal>(value);
cell.CellStyle = cellStyle;
}
}
dataFirstRowNum++;
}
}
public static string HasValue(params string[] list)
{
if (list == null || !list.Any()) return null;
return list.FirstOrDefault(t => !string.IsNullOrEmpty(t));
}
/// <summary> 住院核算单元 </summary>
private static readonly Dictionary<string, Func<ExtractTransDto, string>> fieldInpat = new Dictionary<string, Func<ExtractTransDto, string>>
{
{ "科室名称", (dto) => dto.Department },
{ "核算单元(医生组)", (dto) => new string []{ dto.InpatDoctorAccounting, dto.OutDoctorAccounting }.FirstOrDefault(t => !string.IsNullOrEmpty(t)) },
{ "核算单元(护理组)", (dto) => new string []{ dto.InpatNurseAccounting, dto.OutNurseAccounting }.FirstOrDefault(t => !string.IsNullOrEmpty(t)) },
{ "核算单元(医技组)", (dto) => new string []{ dto.InpatTechnicAccounting, dto.OutTechnicAccounting }.FirstOrDefault(t => !string.IsNullOrEmpty(t)) },
};
/// <summary> 门诊核算单元 </summary>
private static readonly Dictionary<string, Func<ExtractTransDto, string>> fieldOut = new Dictionary<string, Func<ExtractTransDto, string>>
{
{ "科室名称", (dto) => dto.Department },
{ "核算单元(医生组)", (dto) => new string []{ dto.OutDoctorAccounting, dto.InpatDoctorAccounting }.FirstOrDefault(t => !string.IsNullOrEmpty(t)) },
{ "核算单元(护理组)", (dto) => new string []{ dto.OutNurseAccounting, dto.InpatNurseAccounting }.FirstOrDefault(t => !string.IsNullOrEmpty(t)) },
{ "核算单元(医技组)", (dto) => new string []{ dto.OutTechnicAccounting, dto.InpatTechnicAccounting }.FirstOrDefault(t => !string.IsNullOrEmpty(t)) },
};
/// <summary> 医生工作量 </summary>
private static readonly Dictionary<string, Func<ExtractTransDto, string>> fieldDoctor = new Dictionary<string, Func<ExtractTransDto, string>>
{
{ "科室名称", (dto) => dto.Department },
{ "核算单元", (dto) =>
{
var obj = new string []{ dto.OutDoctorAccounting, dto.InpatDoctorAccounting, dto.OutTechnicAccounting, dto.InpatTechnicAccounting }
.FirstOrDefault(t => !string.IsNullOrEmpty(t));
return obj;
}
},
};
/// <summary> 护理工作量 </summary>
private static readonly Dictionary<string, Func<ExtractTransDto, string>> fieldNurse = new Dictionary<string, Func<ExtractTransDto, string>>
{
{ "科室名称", (dto) => dto.Department },
{ "核算单元", (dto) => new string []{ dto.OutNurseAccounting, dto.InpatNurseAccounting }.FirstOrDefault(t => !string.IsNullOrEmpty(t)) },
};
#endregion
#region CollectData
public static void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<string> headers, List<collect_data> data)
{
var columnHeader = sheet.GetOrCreate(point.HeaderFirstRowNum.Value);
int dataFirstRowNum = point.DataFirstRowNum.Value;
WriteCollectDataExistent(sheet, columnHeader, point, sheetType, style, headers, data, ref dataFirstRowNum);
if (data == null || !data.Any(t => !string.IsNullOrEmpty(t.Department))) return;
WriteCollectDataNonexistent(sheet, columnHeader, point, sheetType, style, headers, data, dataFirstRowNum);
}
private static void WriteCollectDataExistent(ISheet sheet, IRow columnHeader, PerSheetPoint point, SheetType sheetType, ExcelStyle style,
List<string> headers, List<collect_data> data, ref int dataFirstRowNum)
{
if (sheet.LastRowNum <= dataFirstRowNum) return;
var cellStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.数据);
int dataFirstCellNum = point.DataFirstCellNum.Value;
for (int rowIndex = dataFirstRowNum; rowIndex < sheet.LastRowNum + 1; rowIndex++)
{
var row = sheet.GetRow(rowIndex);
if (row == null) continue;
string department = row.GetOrCreate(dataFirstCellNum - 1).GetDecodeEscapes();
if (string.IsNullOrEmpty(department)) continue;
var deptData = data.Where(t => t.Department == department);
if (deptData == null || !deptData.Any()) continue;
for (int cellIndex = dataFirstCellNum; cellIndex < columnHeader.LastCellNum; cellIndex++)
{
var column = columnHeader.GetOrCreate(cellIndex).GetDecodeEscapes();
var cell = row.GetOrCreate(cellIndex);
var value = deptData.FirstOrDefault(t => t.TypeName == column)?.CellValue;
if (sheetType == SheetType.Income)
{
cell.SetCellValue<decimal>(value);
cell.CellStyle = cellStyle;
}
else if (cell.CellType != CellType.Formula)
{
cell.SetCellValue<decimal>(value);
if (headers != null && headers.Contains(column))
{
cell.CellStyle = cellStyle;
}
}
}
data.RemoveAll(t => t.Department == department);
if (rowIndex > dataFirstRowNum) dataFirstRowNum = rowIndex + 1;
}
}
private static void WriteCollectDataNonexistent(ISheet sheet, IRow columnHeader, PerSheetPoint point, SheetType sheetType, ExcelStyle style,
List<string> headers, List<collect_data> data, int dataFirstRowNum)
{
var departments = data.Select(s => s.Department).Where(w => !string.IsNullOrEmpty(w)).Distinct().ToList();
var filed = sheet.SheetName.Contains("工作量") ? collectWork : collectIncome;
var deptStyle = style.GetCellStyle();
var cellStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.数据);
foreach (string department in departments)
{
var deptData = data.Where(t => t.Department == department);
if (deptData == null || !deptData.Any()) continue;
var row = sheet.GetOrCreate(dataFirstRowNum);
for (int cellIndex = point.HeaderFirstCellNum.Value; cellIndex < columnHeader.LastCellNum; cellIndex++)
{
var column = columnHeader.GetCell(cellIndex).GetDecodeEscapes();
var cell = row.CreateCell(cellIndex);
if (filed.ContainsKey(column))
{
cell.SetCellOValue(filed[column]?.Invoke(deptData.First()));
cell.CellStyle = deptStyle;
}
else if (sheetType == SheetType.Income || (headers != null && headers.Contains(column)))
{
var value = deptData.FirstOrDefault(t => t.TypeName == column)?.CellValue;
cell.SetCellValue<decimal>(value);
cell.CellStyle = cellStyle;
}
}
dataFirstRowNum++;
}
}
/// <summary> 收入固定列 </summary>
private static readonly Dictionary<string, Func<collect_data, string>> collectIncome = new Dictionary<string, Func<collect_data, string>>
{
{ "科室名称", (dto) => dto.Department },
{ "核算单元(医生组)", (dto) => dto.AccountingUnitDoctor },
{ "核算单元(护理组)", (dto) => dto.AccountingUnitNurse },
{ "核算单元(医技组)", (dto) => dto.AccountingUnitTechnician },
};
/// <summary> 工作量固定列 </summary>
private static readonly Dictionary<string, Func<collect_data, string>> collectWork = new Dictionary<string, Func<collect_data, string>>
{
{ "科室名称", (dto) => dto.Department },
{ "核算单元", (dto) => dto.AccountingUnitDoctor },
};
#endregion
}
}
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class ExtractService : IAutoInjection
{
private readonly ILogger logger;
private readonly LogManageService logService;
private readonly QueryService queryService;
private readonly PersonService personService;
private readonly PerSheetService perSheetService;
private readonly PerforHospitalRepository hospitalRepository;
private readonly PerforPerallotRepository perallotRepository;
private readonly PerforcollectdataRepository collectdataRepository;
private readonly PerforPeremployeeRepository peremployeeRepository;
public ExtractService(
ILogger<ExtractService> logger,
LogManageService logService,
QueryService queryService,
PersonService personService,
PerSheetService perSheetService,
PerforHospitalRepository hospitalRepository,
PerforPerallotRepository perallotRepository,
PerforcollectdataRepository collectdataRepository,
PerforPeremployeeRepository peremployeeRepository
)
{
this.logger = logger;
this.logService = logService;
this.queryService = queryService;
this.personService = personService;
this.perSheetService = perSheetService;
this.hospitalRepository = hospitalRepository;
this.perallotRepository = perallotRepository;
this.collectdataRepository = collectdataRepository;
this.peremployeeRepository = peremployeeRepository;
}
/// <summary>
/// 抽取绩效文件
/// </summary>
/// <param name="allotId">抽取绩效Id</param>
/// <param name="hospitalId">医院Id</param>
/// <param name="email">邮箱地址</param>
/// <param name="groupName">即时日志分组名称</param>
/// <param name="filePath">历史提交文件地址</param>
public string Main(int allotId, int hospitalId, string email, string groupName = null, string filePath = null)
{
string extractFilePath = "";
IWorkbook workbook = null;
try
{
logService.ClearExtractLog(allotId);
var hospital = hospitalRepository.GetEntity(t => t.ID == hospitalId);
var allots = perallotRepository.GetEntities(t => t.HospitalId == hospitalId);
if (allots == null || !allots.Any(t => t.ID == allotId)) throw new Exception("绩效不存在");
var allot = allots.First(t => t.ID == allotId);
var dict = new Dictionary<ExDataDict, object>();
var data = queryService.Handler(hospitalId, allot, ref dict);
var standData = StandDataFormat(hospitalId, data);
var statesArray = new int[] { (int)AllotStates.GenerateSucceed, (int)AllotStates.Archive };
var templateFilePath = ExtractHelper.GetExtractFile(hospitalId, ref extractFilePath, filePath);
if (!FileHelper.IsExistFile(templateFilePath)) throw new PerformanceException("抽取文件创建失败");
workbook = ExcelHelper.GetWorkbook(templateFilePath);
if (workbook == null) throw new PerformanceException("文件读取失败");
WriteDataToFile(workbook, allotId, dict, standData);
}
catch (Exception ex)
{
logger.LogError("提取数据中发生异常: " + ex.ToString());
}
finally
{
using (FileStream file = new FileStream(extractFilePath, FileMode.OpenOrCreate))
{
workbook.Write(file);
}
workbook.Close();
}
return extractFilePath;
}
private void WriteDataToFile(IWorkbook workbook, int allotId, Dictionary<ExDataDict, object> exdict, List<ExtractTransDto> extractDto)
{
ExcelStyle style = new ExcelStyle(workbook);
var models = exdict[ExDataDict.ExModule] as List<ex_module>;
ExtractHelper.CreateNotExistSheet(models, workbook);
var employeeDict = peremployeeRepository.GetEntities(t => t.AllotId == allotId);
var collectData = collectdataRepository.GetEntities(t => t.AllotID == allotId);
WriteDataFactory factory = new WriteDataFactory();
for (int sheetIndex = 0; sheetIndex < workbook.NumberOfSheets; sheetIndex++)
{
var sheet = workbook.GetSheetAt(sheetIndex);
var sheetType = perSheetService.GetSheetType(sheet.SheetName);
if (sheetType == SheetType.Unidentifiable) continue;
var point = PerSheetDataFactory.GetDataRead(sheetType)?.Point;
if (point != null && point.DataFirstCellNum.HasValue)
ExtractHelper.ClearSheetPartialData(sheet, point, sheetType);
var customer = factory.GetWriteData(sheetType);
if (customer != null)
{
string sheetName = sheet.SheetName.NoBlank();
var collects = collectData?.Where(t => t.SheetName.NoBlank() == sheetName).ToList();
customer.WriteCollectData(sheet, point, sheetType, style, collects);
var exdata = extractDto.Where(t => t.SheetName.NoBlank() == sheetName)?.ToList();
var data = GetDataBySheetType(sheetType, exdata, employeeDict);
customer.WriteSheetData(sheet, point, sheetType, style, data, exdict);
}
}
}
private object GetDataBySheetType(SheetType sheetType, List<ExtractTransDto> extractDto, List<per_employee> employeeDict)
{
switch (sheetType)
{
case SheetType.Employee:
case SheetType.ClinicEmployee:
case SheetType.AccountBasic:
return employeeDict;
default:
return extractDto;
}
}
/// <summary>
/// 标准数据格式, 匹配科室字典
/// </summary>
/// <param name="hospitalId"></param>
/// <param name="results"></param>
/// <returns></returns>
private List<ExtractTransDto> StandDataFormat(int hospitalId, List<ex_result> results)
{
if (results == null || !results.Any()) return new List<ExtractTransDto>();
var dict = personService.GetDepartments(hospitalId)?.ToList();
if (dict == null || !dict.Any())
return results.Select(t => new ExtractTransDto
{
SheetName = t.Source,
DoctorName = t.DoctorName,
PersonnelNumber = t.PersonnelNumber,
Department = t.Department,
Category = t.Category,
Value = t.Fee ?? 0
}).ToList();
dict.ForEach(t =>
{
t.HISDeptName = WriteDataHelper.HasValue(t.HISDeptName, t.Department);
});
var data = results.GroupJoin(dict, outer => new { Department = outer.Department }, inner => new { Department = inner.HISDeptName }, (outer, inner) => new { outer, inner })
.Select(t =>
{
var dept = !string.IsNullOrEmpty(t.inner.FirstOrDefault()?.Department) ? t.inner.FirstOrDefault()?.Department : t.outer.Department;
return new ExtractTransDto
{
SheetName = t.outer.Source,
Department = dept,
Category = t.outer.Category,
DoctorName = t.outer.DoctorName,
PersonnelNumber = t.outer.PersonnelNumber,
Value = t.outer.Fee ?? 0,
OutDoctorAccounting = t.inner.FirstOrDefault(f => f.Department == dept)?.OutDoctorAccounting?.AccountingUnit,
OutNurseAccounting = t.inner.FirstOrDefault(f => f.Department == dept)?.OutNurseAccounting?.AccountingUnit,
OutTechnicAccounting = t.inner.FirstOrDefault(f => f.Department == dept)?.OutTechnicAccounting?.AccountingUnit,
InpatDoctorAccounting = t.inner.FirstOrDefault(f => f.Department == dept)?.InpatDoctorAccounting?.AccountingUnit,
InpatNurseAccounting = t.inner.FirstOrDefault(f => f.Department == dept)?.InpatNurseAccounting?.AccountingUnit,
InpatTechnicAccounting = t.inner.FirstOrDefault(f => f.Department == dept)?.InpatTechnicAccounting?.AccountingUnit,
};
});
var groupdata = data.GroupBy(t => new { t.Department, t.Category, t.SheetName }).Select(t => new ExtractTransDto
{
SheetName = t.Key.SheetName,
Department = t.Key.Department,
Category = t.Key.Category,
Value = t.Sum(group => group.Value) == 0 ? null : t.Sum(group => group.Value),
OutDoctorAccounting = t.First().OutDoctorAccounting,
OutNurseAccounting = t.First().OutNurseAccounting,
OutTechnicAccounting = t.First().OutTechnicAccounting,
InpatDoctorAccounting = t.First().InpatDoctorAccounting,
InpatNurseAccounting = t.First().InpatNurseAccounting,
InpatTechnicAccounting = t.First().InpatTechnicAccounting,
});
return groupdata.ToList();
}
}
}
using Dapper;
using Microsoft.Extensions.Logging;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Performance.Services.ExtractExcelService
{
public enum ExDataDict
{
ExModule = 1,
ExItem = 2,
ExSpecial = 3,
}
public class QueryService : IAutoInjection
{
private readonly ILogger logger;
private readonly PerforExmoduleRepository exmoduleRepository;
private readonly PerforExitemRepository exitemRepository;
private readonly PerforExspecialRepository exspecialRepository;
private readonly PerforExscriptRepository exscriptRepository;
private readonly PerforExresultRepository exresultRepository;
private readonly PerforHospitalconfigRepository hosconfigRepository;
private readonly PerforPerallotRepository perallotRepository;
public QueryService(
ILogger<QueryService> logger,
PerforExmoduleRepository exmoduleRepository,
PerforExitemRepository exitemRepository,
PerforExspecialRepository exspecialRepository,
PerforExscriptRepository exscriptRepository,
PerforExresultRepository exresultRepository,
PerforHospitalconfigRepository hosconfigRepository,
PerforPerallotRepository perallotRepository
)
{
this.logger = logger;
this.exmoduleRepository = exmoduleRepository;
this.exitemRepository = exitemRepository;
this.exspecialRepository = exspecialRepository;
this.exscriptRepository = exscriptRepository;
this.exresultRepository = exresultRepository;
this.hosconfigRepository = hosconfigRepository;
this.perallotRepository = perallotRepository;
}
private readonly DateTime CreateTime = DateTime.Now;
/// <summary>
/// 获取抽取数据
/// </summary>
/// <param name="hospitalId"></param>
/// <param name="allot"></param>
/// <returns></returns>
public List<ex_result> Handler(int hospitalId, per_allot allot, ref Dictionary<ExDataDict, object> dict)
{
try
{
var configs = hosconfigRepository.GetEntities(t => t.HospitalId == hospitalId);
if (configs == null || !configs.Any()) throw new Exception("医院未配置绩效抽取信息");
dict = new Dictionary<ExDataDict, object>
{
{ ExDataDict.ExModule, new List<ex_module>() },
{ ExDataDict.ExItem, new List<ex_item>() },
{ ExDataDict.ExSpecial, new List<ex_script>() }
};
var extypeIds = GetQueryScriptIds(hospitalId, ref dict);
ClearHistoryData(allot.ID);
var data = new List<ex_result>();
var scripts = exscriptRepository.GetEntities(t => extypeIds.Contains(t.TypeId));
if (scripts != null && scripts.Any())
{
var allmodules = dict[ExDataDict.ExModule] as List<ex_module>;
foreach (var pair in dict)
{
switch (pair.Key)
{
case ExDataDict.ExModule:
data.AddRange(ExtractModuleData(allot, scripts, configs, pair.Value));
break;
case ExDataDict.ExItem:
data.AddRange(ExtractItemData(allot, scripts, configs, allmodules, pair.Value));
break;
case ExDataDict.ExSpecial:
data.AddRange(ExtractSpecialData(allot, scripts, configs, pair.Value));
break;
}
}
}
return data;
}
catch (Exception ex)
{
logger.LogError("获取数据时发生异常");
throw ex;
}
}
/// <summary>
/// 获取医院抽取项配置
/// </summary>
/// <param name="hospitalId"></param>
/// <param name="dict"></param>
/// <returns></returns>
private List<int> GetQueryScriptIds(int hospitalId, ref Dictionary<ExDataDict, object> dict)
{
var extypeIds = new List<int>();
var modules = exmoduleRepository.GetEntities(t => t.HospitalId == hospitalId);
var items = new List<ex_item>();
if (modules != null && modules.Any())
{
dict[ExDataDict.ExModule] = modules;
extypeIds.AddRange(modules.Select(t => t.TypeId ?? 0));
items = exitemRepository.GetEntities(t => t.ModuleId.HasValue && modules.Select(m => m.Id).Contains(t.ModuleId.Value));
if (items != null && items.Any(t => t.TypeId.HasValue))
{
dict[ExDataDict.ExItem] = items;
extypeIds.AddRange(items.Select(t => t.TypeId ?? 0));
}
}
var specials = exspecialRepository.GetEntities(t => t.HospitalId == hospitalId);
if (specials != null && specials.Any())
{
dict[ExDataDict.ExSpecial] = specials;
extypeIds.AddRange(specials.Select(t => t.TypeId ?? 0));
}
var exids = extypeIds.Where(t => t > 0);
if (exids == null || !exids.Any()) return new List<int>();
return exids.Distinct().ToList();
}
/// <summary>
/// 清除历史抽取数据
/// </summary>
/// <param name="allotId"></param>
private void ClearHistoryData(int allotId)
{
logger.LogInformation($"开始清除历史提取数据");
perallotRepository.ClearResultData(allotId);
logger.LogInformation($"清除历史提取数据已完成");
}
#region ExResultData
/// <summary>
/// 获取收入费用
/// </summary>
/// <param name="allot"></param>
/// <param name="scripts"></param>
/// <param name="configs"></param>
/// <param name="dictValue"></param>
/// <returns></returns>
private List<ex_result> ExtractModuleData(per_allot allot, List<ex_script> scripts, List<sys_hospitalconfig> configs, object dictValue)
{
var data = new List<ex_result>();
if (dictValue is List<ex_module> modules && modules != null && modules.Any(t => t.TypeId.HasValue && t.TypeId > 0))
{
var typeIds = modules.Where(t => t.TypeId.HasValue && t.TypeId > 0).Select(t => t.TypeId.Value).Distinct().ToList();
if (typeIds == null || typeIds.Count == 0) return new List<ex_result>();
foreach (var typeId in typeIds)
{
foreach (var script in scripts.Where(t => t.TypeId == typeId))
{
var config = configs.FirstOrDefault(t => t.Id == script.ConfigId) ?? configs.FirstOrDefault(t => t.DataBaseType == script.DatabaseType);
if (config == null) continue;
var querydata = QueryData(config, allot, script.ExecScript);
if (querydata != null && querydata.Any())
{
var thisModules = modules.Where(t => t.TypeId == typeId).ToList();
thisModules.ForEach(f =>
{
var result = querydata.Select(t => new ex_result
{
Department = t.Department,
Category = t.Category?.Trim(),
Fee = t.Value,
DoctorName = t.DoctorName,
PersonnelNumber = t.PersonnelNumber,
Source = f.ModuleName,
DatabaseType = config.DataBaseType,
ConfigId = config.Id,
AllotId = allot.ID,
CreateTime = CreateTime,
}).ToList();
exresultRepository.AddRange(result.ToArray());
data.AddRange(result);
});
}
}
}
}
return data;
}
/// <summary>
/// 获取工作量、成本等费用
/// </summary>
/// <param name="allot"></param>
/// <param name="scripts"></param>
/// <param name="configs"></param>
/// <param name="modules"></param>
/// <param name="dictValue"></param>
/// <returns></returns>
private List<ex_result> ExtractItemData(per_allot allot, List<ex_script> scripts, List<sys_hospitalconfig> configs, List<ex_module> modules, object dictValue)
{
var data = new List<ex_result>();
if (dictValue is List<ex_item> items && items != null && items.Any(t => t.TypeId.HasValue && t.TypeId > 0))
{
var typeIds = items.Where(t => t.TypeId.HasValue && t.TypeId > 0).Select(t => t.TypeId.Value).Distinct().ToList();
foreach (var typeId in typeIds)
{
foreach (var script in scripts.Where(t => t.TypeId == typeId))
{
var config = configs.FirstOrDefault(t => t.Id == script.ConfigId);
if (config == null) continue;
var querydata = QueryData(config, allot, script.ExecScript);
if (querydata != null && querydata.Any())
{
var thisItems = items.Where(t => t.TypeId == typeId).ToList();
var modulename = modules.FirstOrDefault(t => t.Id == thisItems.First().ModuleId)?.ModuleName;
thisItems.ForEach(f =>
{
var result = querydata.Select(t => new ex_result
{
Department = t.Department,
Category = f.ItemName,
Fee = t.Value,
DoctorName = t.DoctorName,
PersonnelNumber = t.PersonnelNumber,
Source = modulename,
DatabaseType = config.DataBaseType,
ConfigId = config.Id,
AllotId = allot.ID,
CreateTime = CreateTime,
}).ToList();
exresultRepository.AddRange(result.ToArray());
data.AddRange(result);
});
}
}
}
}
return data;
}
/// <summary>
/// 获取特殊核算费用
/// </summary>
/// <param name="allot"></param>
/// <param name="scripts"></param>
/// <param name="configs"></param>
/// <param name="dictValue"></param>
/// <returns></returns>
private List<ex_result> ExtractSpecialData(per_allot allot, List<ex_script> scripts, List<sys_hospitalconfig> configs, object dictValue)
{
var data = new List<ex_result>();
if (dictValue is List<ex_special> specials && specials != null && specials.Any(t => t.TypeId.HasValue && t.TypeId > 0))
{
var typeIds = specials.Where(t => t.TypeId.HasValue && t.TypeId > 0).Select(t => t.TypeId.Value).Distinct().ToList();
foreach (var typeId in typeIds)
{
foreach (var script in scripts.Where(t => t.TypeId == typeId))
{
var config = configs.FirstOrDefault(t => t.Id == script.ConfigId);
if (config == null) continue;
var querydata = QueryData(config, allot, script.ExecScript);
if (querydata != null && querydata.Any())
{
var thisSpecials = specials.Where(t => t.TypeId == typeId).ToList();
thisSpecials.ForEach(f =>
{
var result = querydata.Select(t => new ex_result
{
Department = f.Department,
Category = f.Target,
Fee = t.Value,
DoctorName = t.DoctorName,
PersonnelNumber = t.PersonnelNumber,
Source = "4.2 特殊核算单元绩效测算表",
DatabaseType = config.DataBaseType,
ConfigId = config.Id,
AllotId = allot.ID,
CreateTime = CreateTime,
}).ToList();
exresultRepository.AddRange(result.ToArray());
data.AddRange(result);
});
}
}
}
}
return data;
}
#endregion
#region QueryData
/// <summary>
/// 查询数据
/// </summary>
/// <param name="config"></param>
/// <param name="allot"></param>
/// <param name="execsql"></param>
/// <param name="source"></param>
/// <param name="category"></param>
/// <returns></returns>
private IEnumerable<ExtractDto> QueryData(sys_hospitalconfig config, per_allot allot, string execsql)
{
var parameters = GetParameters(allot);
using (var connection = ConnectionBuilder.Create((DatabaseType)config.DataBaseType, config.DbSource, config.DbName, config.DbUser, config.DbPassword))
{
foreach (var item in parameters)
{
execsql = Regex.Replace(execsql, item.Key, item.Value, RegexOptions.IgnoreCase);
}
logger.LogInformation($"提取绩效数据SQL脚本{execsql}");
var result = connection.Query<ExtractDto>(execsql, commandTimeout: 20000);
logger.LogInformation($"提取绩效数据执行脚本获取数据{result?.Count() ?? 0}条记录");
return result;
}
}
/// <summary>
/// 获取参数
/// </summary>
/// <param name="allot"></param>
/// <returns></returns>
private Dictionary<string, string> GetParameters(per_allot allot)
{
DateTime beginTime = new DateTime(allot.Year, allot.Month, 1);
Dictionary<string, string> pairs = new Dictionary<string, string>
{
{ "@beginTime", $"'{beginTime.ToString("yyyy-MM-dd")}'" },
{ "@endTime", $"'{beginTime.AddMonths(1).ToString("yyyy-MM-dd")}'"},
};
return pairs;
}
#endregion
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
class AccountBasicDataWrite : ISheetDataWrite
{
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{
}
public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null)
{
}
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
class ClinicEmployeeDataWrite : ISheetDataWrite
{
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{
}
public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null)
{
}
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
public class EmployeeDataWrite : ISheetDataWrite
{
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{
}
public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict)
{
if (data is List<per_employee> employees && employees.Any(t => accountingUnits.Contains(t.UnitType)))
{
int dataFirstRowNum = point.DataFirstRowNum.Value;
var columns = sheet.CreateRow(point.HeaderFirstRowNum.Value).GetCellValues();
ClearSheetPartialData(sheet, employees, columns, ref dataFirstRowNum);
foreach (var employee in employees)
{
var row = sheet.GetOrCreate(dataFirstRowNum);
for (int cellIndex = 0; cellIndex < columns.Count(); cellIndex++)
{
var column = columns[cellIndex];
if (string.IsNullOrEmpty(column) || !employeeDict.ContainsKey(column)) continue;
var cell = row.GetOrCreate(cellIndex);
cell.SetCellOValue(employeeDict[column].Invoke(employee));
}
dataFirstRowNum++;
}
}
}
private void ClearSheetPartialData(ISheet sheet, List<per_employee> employees, List<string> columns, ref int dataFirstRowNum)
{
var pairs = new Dictionary<string, int>();
foreach (var key in new string[] { "核算单元", "人员工号", "医生姓名" })
{
if (!pairs.ContainsKey(key) && columns.Contains(key))
pairs.Add(key, columns.IndexOf(key));
}
var clearDict = new Dictionary<string, int>();
foreach (var key in new string[] { "出勤率" })
{
if (!clearDict.ContainsKey(key) && columns.Contains(key))
clearDict.Add(key, columns.IndexOf(key));
}
for (int rowIndex = dataFirstRowNum; rowIndex < sheet.LastRowNum; rowIndex++)
{
var row = sheet.GetRow(dataFirstRowNum);
string accountingUnit = row.GetOrCreate(pairs["核算单元"]).GetDecodeEscapes();
string personnel = row.GetOrCreate(pairs["人员工号"]).GetDecodeEscapes();
string doctorName = row.GetOrCreate(pairs["医生姓名"]).GetDecodeEscapes();
var employee = employees.FirstOrDefault(t => t.AccountingUnit == accountingUnit && t.PersonnelNumber == personnel && t.DoctorName == doctorName);
if (employee == null)
{
}
else
{
foreach (var clear in clearDict)
{
if (clear.Value < 0) return;
var cell = row.GetOrCreate(clear.Value);
if (cell.CellType != CellType.Formula) cell.SetCellValue("");
}
employees.Remove(employee);
}
if (rowIndex > dataFirstRowNum) dataFirstRowNum = rowIndex + 1;
}
}
private readonly string[] accountingUnits = new string[] { AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString() };
private readonly Dictionary<string, Func<per_employee, object>> employeeDict = new Dictionary<string, Func<per_employee, object>>
{
{ "人员分类", (t) => t.UnitType },
{ "核算单元", (t) => t.AccountingUnit },
{ "人员工号", (t) => t.PersonnelNumber },
{ "医生姓名", (t) => t.DoctorName },
{ "参加工作时间", (t) => t.WorkTime },
{ "出勤率", (t) => t.Attendance },
};
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
public interface ISheetDataWrite
{
void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects);
void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null);
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
public class IncomeDataWrite : ISheetDataWrite
{
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
var columns = collects.Where(t => !string.IsNullOrEmpty(t.TypeName)).Select(t => t.TypeName).Distinct().OrderBy(t => t).ToList();
var headers = columns.Select(t => new ExcelHeader
{
ColumnName = t.Trim(),
DoctorFactor = 0,
NurseFactor = 0,
TechnicianFactor = 0
}).ToList();
WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers);
WriteDataHelper.WriteCollectData(sheet, point, sheetType, style, columns, collects);
}
public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null)
{
var modules = exdict[ExDataDict.ExModule] as List<ex_module>;
var module = modules?.FirstOrDefault(t => t.SheetType == (int)sheetType && t.ModuleName.NoBlank() == sheet.SheetName.NoBlank());
if (module == null) return;
var items = exdict[ExDataDict.ExItem] as List<ex_item>;
var modelItems = items?.Where(t => t.ModuleId == module.Id);
if (modelItems == null || !modelItems.Any()) return;
var headers = modelItems.Select(t => new ExcelHeader
{
ColumnName = t.ItemName.Trim(),
DoctorFactor = t.FactorValue1 ?? 0,
NurseFactor = t.FactorValue2 ?? 0,
TechnicianFactor = t.FactorValue3 ?? 0
}).ToList();
WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers);
if (data is List<ExtractTransDto> extractDto && extractDto.Any())
{
var columns = headers.Select(t => t.ColumnName).ToList();
WriteDataHelper.WriteSheetData(sheet, point, sheetType, style, columns, extractDto);
}
}
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
public class OtherIncomeDataWrite : ISheetDataWrite
{
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
var columns = collects.Where(t => !string.IsNullOrEmpty(t.TypeName)).Select(t => t.TypeName).Distinct().OrderBy(t => t).ToList();
var headers = columns.Select(t => new ExcelHeader
{
ColumnName = t.Trim(),
DoctorFactor = 0,
NurseFactor = 0,
TechnicianFactor = 0
}).ToList();
WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers);
WriteDataHelper.WriteCollectData(sheet, point, sheetType, style, columns, collects);
}
public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null)
{
var modules = exdict[ExDataDict.ExModule] as List<ex_module>;
var module = modules?.FirstOrDefault(t => t.SheetType == (int)sheetType && t.ModuleName.NoBlank() == sheet.SheetName.NoBlank());
if (module == null) return;
var items = exdict[ExDataDict.ExItem] as List<ex_item>;
var modelItems = items?.Where(t => t.ModuleId == module.Id);
if (modelItems == null || !modelItems.Any()) return;
var headers = modelItems.Select(t => new ExcelHeader
{
ColumnName = t.ItemName,
DoctorFactor = t.FactorValue1 ?? 0,
NurseFactor = t.FactorValue2 ?? 0,
TechnicianFactor = t.FactorValue3 ?? 0
}).ToList();
WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers);
if (data is List<ExtractTransDto> extractDto && extractDto.Any())
{
var columns = headers.Select(t => t.ColumnName).ToList();
WriteDataHelper.WriteSheetData(sheet, point, sheetType, style, columns, extractDto);
}
}
}
}
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
public class SpecialUnitDataWrite : ISheetDataWrite
{
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{
}
public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null)
{
try
{
var columns = sheet.GetOrCreate(point.HeaderFirstRowNum.Value).GetCellValues();
int dataFirstRowNum = point.DataFirstRowNum.Value;
ClearSheetPartialData(sheet, columns, dataFirstRowNum, SpecialUnitColumns.Quantity);
var exSpecials = exdict[ExDataDict.ExSpecial] as List<ex_special>;
if (exSpecials == null || !exSpecials.Any()) return;
var extractDto = (data as List<ExtractTransDto>) ?? new List<ExtractTransDto>();
var mergedRegions = new List<SpecialCellRange>();
RemoveMergedRegion(sheet, ref mergedRegions);
SupplyMergedRegionData(sheet, style, mergedRegions);
var index = columns.IndexOf(SpecialUnitColumns.Department);
var needMergedRegions = mergedRegions.Where(t => t.FirstColumn == index && t.LastColumn == index)?.ToList() ?? new List<SpecialCellRange>();
var specials = exSpecials.GroupJoin(extractDto, outer => new { outer.Department, outer.Target }, inner => new { inner.Department, Target = inner.Category },
(outer, inner) => new SpecialDto
{
Department = outer.Department,
Target = outer.Target,
TargetFactor = outer.TargetFactor,
AdjustFactor = outer.AdjustFactor,
Quantity = inner.FirstOrDefault()?.Value
}).ToList();
SupplySpecialQuantity(sheet, style, specials, needMergedRegions, columns, ref dataFirstRowNum);
AddNewSpecialConfig(sheet, style, specials, needMergedRegions, columns, dataFirstRowNum);
AddMergedRegion(sheet, needMergedRegions, columns);
}
catch (Exception ex)
{
}
}
/// <summary>
/// 清除特殊科室数据(数量)
/// </summary>
/// <param name="sheet"></param>
/// <param name="columns"></param>
/// <param name="dataFirstRowNum"></param>
/// <param name="clear"></param>
private void ClearSheetPartialData(ISheet sheet, List<string> columns, int dataFirstRowNum, params string[] clear)
{
if (sheet == null) return;
if (columns == null || !columns.Any()) return;
if (clear == null || !clear.Any()) return;
var dict = clear.Select(t => columns.IndexOf(t))?.ToList();
if (dict == null || !dict.Any(t => t > -1)) return;
dict.RemoveAll(t => t == -1);
for (int rowIndex = dataFirstRowNum; rowIndex < sheet.LastRowNum + 1; rowIndex++)
{
var row = sheet.GetOrCreate(rowIndex);
foreach (var cellIndex in dict)
{
var cell = row.GetCell(cellIndex);
if (cell != null) row.RemoveCell(cell);
}
}
}
/// <summary>
/// 取消合并单元格
/// </summary>
/// <param name="sheet"></param>
/// <param name="mergedRegions"></param>
private void RemoveMergedRegion(ISheet sheet, ref List<SpecialCellRange> mergedRegions)
{
if (sheet.NumMergedRegions > 0)
{
for (int mergedIndex = sheet.NumMergedRegions - 1; mergedIndex >= 0; mergedIndex--)
{
var mergedRegion = sheet.GetMergedRegion(mergedIndex);
if (mergedRegion.FirstRow == 0 && mergedRegion.LastRow == 0) continue;
mergedRegions.Add(new SpecialCellRange(mergedRegion));
sheet.RemoveMergedRegion(mergedIndex);
}
}
}
/// <summary>
/// 补充取消单元格后的剩余单元格数据
/// </summary>
/// <param name="sheet"></param>
/// <param name="style"></param>
/// <param name="mergedRegions"></param>
private void SupplyMergedRegionData(ISheet sheet, ExcelStyle style, List<SpecialCellRange> mergedRegions)
{
if (mergedRegions == null || !mergedRegions.Any(t => t.FirstRow > 1)) return;
var basicStyle = style.GetCellStyle();
foreach (var merged in mergedRegions.Where(t => t.FirstRow > 1))
{
string value = ""; CellType cellType = CellType.Unknown;
var valueCell = sheet.GetRow(merged.FirstRow)?.GetCell(merged.FirstColumn);
if (valueCell != null)
{
cellType = valueCell.CellType;
valueCell.SetCellType(CellType.String);
value = valueCell.StringCellValue;
}
merged.Single = value;
if (string.IsNullOrEmpty(value)) continue;
for (int rowIndex = merged.FirstRow; rowIndex < merged.LastRow + 1; rowIndex++)
{
var row = sheet.GetRow(rowIndex);
if (row == null) row = sheet.CreateRow(rowIndex);
for (int cellIndex = merged.FirstColumn; cellIndex < merged.LastColumn + 1; cellIndex++)
{
var cell = row.GetCell(cellIndex);
if (cell == null) cell = row.CreateCell(cellIndex);
if (!string.IsNullOrEmpty(value)) SetCellValue(cell, value);
}
row.SetRowStyle(basicStyle);
}
}
}
/// <summary>
/// 补充已存在数据的抽取数据
/// </summary>
/// <param name="sheet"></param>
/// <param name="style"></param>
/// <param name="specials"></param>
/// <param name="ranges"></param>
/// <param name="columns"></param>
/// <param name="dataFirstRowNum"></param>
private void SupplySpecialQuantity(ISheet sheet, ExcelStyle style, List<SpecialDto> specials, List<SpecialCellRange> ranges, List<string> columns, ref int dataFirstRowNum)
{
if (sheet == null) return;
var rowStyle = style.GetCellStyle();
var cellStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.数据);
var quantityIndex = columns.IndexOf(SpecialUnitColumns.Quantity);
var dict = new Dictionary<string, int>();
var fixedColumns = new List<string> { SpecialUnitColumns.Department, SpecialUnitColumns.Target };
fixedColumns.ForEach(t =>
{
int index = columns.IndexOf(t);
if (!dict.ContainsKey(t) && index > -1) dict.Add(t, index);
});
if (fixedColumns.Count != dict.Count) return;
for (int rowIndex = dataFirstRowNum; rowIndex < sheet.LastRowNum + 1; rowIndex++)
{
var row = sheet.GetOrCreate(rowIndex);
var target = row.GetCell(dict[SpecialUnitColumns.Target]).GetDecodeEscapes();
if (!string.IsNullOrEmpty(target))
{
row.SetRowStyle(rowStyle);
var department = row.GetCell(dict[SpecialUnitColumns.Department]).GetDecodeEscapes();
CheckMergedRegions(rowIndex, department, ranges);
var special = specials.FirstOrDefault(t => t.Department == department && t.Target == target);
if (special != null)
{
var cell = row.GetOrCreate(quantityIndex);
cell.SetCellValue<double>(special.Quantity);
cell.CellStyle = cellStyle;
specials.Remove(special);
}
dataFirstRowNum = rowIndex + 1;
}
}
}
/// <summary>
/// 获取需要合并的单元格
/// </summary>
/// <param name="rowIndex"></param>
/// <param name="department"></param>
/// <param name="ranges"></param>
private void CheckMergedRegions(int rowIndex, string department, List<SpecialCellRange> ranges)
{
var range = ranges.FirstOrDefault(t => t.FirstRow <= rowIndex && t.LastRow >= rowIndex);
if (range == null)
{
if (rowIndex == 0) return;
int prevRowIndex = rowIndex - 1;
range = ranges.FirstOrDefault(t => t.FirstRow <= prevRowIndex && t.LastRow >= prevRowIndex);
if (range != null && range.Single == department)
range.LastRow = rowIndex;
else
{
var columnIndex = ranges.First().FirstColumn;
ranges.Add(new SpecialCellRange(new CellRangeAddress(rowIndex, rowIndex, columnIndex, columnIndex))
{
Single = department
});
}
}
}
/// <summary>
/// 添加新的特殊科室配置
/// </summary>
/// <param name="sheet"></param>
/// <param name="style"></param>
/// <param name="specials"></param>
/// <param name="ranges"></param>
/// <param name="columns"></param>
/// <param name="dataFirstRowNum"></param>
private void AddNewSpecialConfig(ISheet sheet, ExcelStyle style, List<SpecialDto> specials, List<SpecialCellRange> ranges, List<string> columns, int dataFirstRowNum)
{
if (specials == null || !specials.Any()) return;
int colIndex = ranges.FirstOrDefault()?.FirstColumn ?? 0;
var rowStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.数据);
foreach (var item in specials.GroupBy(t => t.Department))
{
var deptSpecials = item.ToList();
if (ranges != null && ranges.Select(t => t.Single).Contains(item.Key))
{
var range = ranges.First(t => t.Single == item.Key);
sheet.ShiftRows(range.LastRow + 1, sheet.LastRowNum + specials.Count, item.Count(), true, false);
for (int i = 1; i < item.Count() + 1; i++)
{
var shiftRow = sheet.CreateRow(range.LastRow + i);
WriteSpecialData(shiftRow, rowStyle, deptSpecials[i - 1], columns);
}
dataFirstRowNum += item.Count();
range.LastRow += item.Count();
foreach (var nextRange in ranges.Where(t => t.FirstRow > range.FirstRow))
{
nextRange.FirstRow += item.Count();
nextRange.LastRow += item.Count();
}
}
else
{
var range = new SpecialCellRange(new CellRangeAddress(dataFirstRowNum, dataFirstRowNum + item.Count() - 1, colIndex, colIndex))
{
Single = deptSpecials.First().Department
};
ranges.Add(range);
foreach (var special in deptSpecials)
{
var shiftRow = sheet.CreateRow(dataFirstRowNum);
WriteSpecialData(shiftRow, rowStyle, special, columns);
dataFirstRowNum++;
}
}
}
}
private void WriteSpecialData(IRow row, ICellStyle style, SpecialDto special, List<string> columns)
{
foreach (var item in specialField)
{
if (!columns.Contains(item.Key)) continue;
var index = columns.IndexOf(item.Key);
var cell = row.GetOrCreate(index);
if (cell != null && cell.CellType != CellType.Formula)
{
if (new string[] { SpecialUnitColumns.Department, SpecialUnitColumns.Target }.Contains(item.Key))
cell.SetCellValue(item.Value.Invoke(special)?.ToString());
else
cell.SetCellValue<double>(item.Value.Invoke(special));
cell.CellStyle = style;
}
}
}
/// <summary>
/// 合并单元格
/// </summary>
/// <param name="sheet"></param>
/// <param name="ranges"></param>
/// <param name="columns"></param>
private void AddMergedRegion(ISheet sheet, List<SpecialCellRange> ranges, List<string> columns)
{
if (columns == null || !columns.Any()) return;
if (ranges == null || !ranges.Any()) return;
var columnIndexs = new string[] { SpecialUnitColumns.Department, SpecialUnitColumns.PeopleNumber, SpecialUnitColumns.AdjustFactor }.Select(t => columns.IndexOf(t));
if (columnIndexs == null || !columnIndexs.Any(t => t > -1)) return;
foreach (var index in columnIndexs.Where(t => t > -1))
{
var address = ranges.Where(t => t.LastRow > t.FirstRow)
?.Select(t => new CellRangeAddress(t.FirstRow, t.LastRow, index, index));
if (address == null || !address.Any()) continue;
foreach (var item in address)
{
sheet.AddMergedRegion(item);
}
}
}
public void SetCellValue(ICell cell, string value)
{
switch (value)
{
case string reg when Regex.IsMatch(reg, @"^[+-]?\d*[.]?\d*$"):
cell.SetCellValue(ConvertHelper.To<double>(value));
break;
case string reg when Regex.IsMatch(reg, @"^[+-]?\d*$"):
cell.SetCellValue(ConvertHelper.To<int>(value));
break;
default:
cell.SetCellValue(value);
break;
}
}
private Dictionary<string, Func<SpecialDto, object>> specialField = new Dictionary<string, Func<SpecialDto, object>>
{
{ SpecialUnitColumns.Department, (t) => t.Department },
{ SpecialUnitColumns.Target, (t) => t.Target },
{ SpecialUnitColumns.TargetFactor, (t) => t.TargetFactor },
{ SpecialUnitColumns.Quantity, (t) => t.Quantity },
{ SpecialUnitColumns.AdjustFactor, (t) => t.AdjustFactor },
};
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
public class WorkloadDataWrite : ISheetDataWrite
{
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
var columns = collects.Where(t => !string.IsNullOrEmpty(t.TypeName)).Select(t => t.TypeName).Distinct().OrderBy(t => t).ToList();
var headers = columns.Select(t => new ExcelHeader
{
ColumnName = t.Trim(),
DoctorFactor = 0,
NurseFactor = 0,
TechnicianFactor = 0
}).ToList();
WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers);
WriteDataHelper.WriteCollectData(sheet, point, sheetType, style, columns, collects);
}
public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null)
{
var modules = exdict[ExDataDict.ExModule] as List<ex_module>;
var module = modules?.FirstOrDefault(t => t.SheetType == (int)sheetType && t.ModuleName.NoBlank() == sheet.SheetName.NoBlank());
if (module == null) return;
var items = exdict[ExDataDict.ExItem] as List<ex_item>;
var modelItems = items?.Where(t => t.ModuleId == module.Id);
if (modelItems == null || !modelItems.Any()) return;
var headers = modelItems.Select(t => new ExcelHeader
{
ColumnName = t.ItemName,
WorkloadFactor = t.FactorValue1 ?? 0
}).ToList();
WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers);
if (data is List<ExtractTransDto> extractDto && extractDto.Any())
{
var columns = headers.Select(t => t.ColumnName).Intersect(extractDto.Select(t => t.Category))?.ToList();
WriteDataHelper.WriteSheetData(sheet, point, sheetType, style, columns, extractDto);
}
}
}
}
using Performance.DtoModels;
using Performance.Services.ExtractExcelService.SheetDataWrite;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services.ExtractExcelService
{
public class WriteDataFactory
{
public ISheetDataWrite GetWriteData(SheetType sheetType)
{
ISheetDataWrite factory;
switch (sheetType)
{
//case SheetType.Employee:
// factory = new EmployeeDataWrite();
// break;
//case SheetType.ClinicEmployee:
// factory = new ClinicEmployeeDataWrite();
// break;
case SheetType.OtherIncome:
case SheetType.Expend:
factory = new OtherIncomeDataWrite();
break;
case SheetType.Income:
factory = new IncomeDataWrite();
break;
case SheetType.Workload:
factory = new WorkloadDataWrite();
break;
//case SheetType.AccountBasic:
// factory = new AccountBasicDataWrite();
// break;
case SheetType.SpecialUnit:
factory = new SpecialUnitDataWrite();
break;
default:
return null;
}
return factory;
}
}
}
......@@ -19,6 +19,7 @@ public class PerSheetDataReadExpend : IPerSheetDataRead
HeaderLastRowNum = 4,
HeaderFirstCellNum = 3,
DataFirstRowNum = 5,
DataFirstCellNum = 7,
AccountingUnit = new List<AccountingUnit>
{
new AccountingUnit
......
......@@ -19,6 +19,7 @@ public class PerSheetDataReadIncome : IPerSheetDataRead
HeaderLastRowNum = 4,
HeaderFirstCellNum = 3,
DataFirstRowNum = 5,
DataFirstCellNum = 7,
AccountingUnit = new List<AccountingUnit>
{
//核算单元(医技组)
......
......@@ -19,6 +19,7 @@ public class PerSheetDataReadOtherIncome : IPerSheetDataRead
HeaderLastRowNum = 4,
HeaderFirstCellNum = 3,
DataFirstRowNum = 5,
DataFirstCellNum = 7,
AccountingUnit = new List<AccountingUnit>
{
//核算单元(医技组)
......
......@@ -19,6 +19,7 @@ public class PerSheetDataReadWorkload : IPerSheetDataRead
HeaderLastRowNum = 1,
HeaderFirstCellNum = 1,
DataFirstRowNum = 3,
DataFirstCellNum = 3,
AccountingUnit = new List<AccountingUnit>
{
new AccountingUnit
......
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