PIbd-31_Putincev.D.M._COP_29/COP/PutincevLibrary/ComponentExcelWithTable.cs

178 lines
6.2 KiB
C#

using NPOI.XSSF.UserModel;
using OfficeOpenXml.Drawing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PutincevLibrary.Info;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using BorderStyle = NPOI.SS.UserModel.BorderStyle;
using HorizontalAlignment = NPOI.SS.UserModel.HorizontalAlignment;
namespace PutincevLibrary
{
public partial class ComponentExcelWithTable : Component
{
public ComponentExcelWithTable()
{
InitializeComponent();
}
public ComponentExcelWithTable(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void GenerateDocument<T>(ExcelTableInfo<T> info) where T : class
{
if (string.IsNullOrEmpty(info.FilePath))
{
throw new ArgumentException("File path is null or empty.");
}
if (string.IsNullOrEmpty(info.DocumentTitle))
{
throw new ArgumentException("Document title is null or empty.");
}
if (info.Data == null || info.Data.Count == 0)
{
throw new ArgumentException("Data is null or empty.");
}
var workbook = new XSSFWorkbook();
var sheet = workbook.CreateSheet("Таблица");
sheet.CreateRow(0).CreateCell(0).SetCellValue(info.DocumentTitle);
int curRow = 1;
int curCol = 0;
List<string> headers = new();
var dataCellStyle = GetDataCellStyle(workbook);
var headerCellStyle = GetHeaderCellStyle(workbook);
foreach (var header in info.Headers)
{
headers.Add(header.Key);
var currentRow = sheet.CreateRow(curRow);
var curCell = currentRow.CreateCell(curCol);
if (header.Value.Item1.Count > 1)
{
sheet.AddMergedRegion(new CellRangeAddress(curRow, curRow + header.Value.Item1.Count - 1, curCol, curCol));
curCol++;
foreach (var (key, displayName) in header.Value.Item1)
{
int id = header.Value.Item1.IndexOf((key, displayName));
var cellValue = currentRow.CreateCell(1);
cellValue.SetCellValue(displayName);
currentRow.Height = (short)(header.Value.Item2[id] * 20);
headers.Add(displayName);
cellValue.CellStyle = headerCellStyle;
currentRow = sheet.CreateRow(currentRow.RowNum + 1);
}
}
else
{
int id = header.Value.Item1.IndexOf(header.Value.Item1[0]);
sheet.AddMergedRegion(new CellRangeAddress(curRow, curRow, curCol, curCol + 1));
currentRow.Height = (short)(header.Value.Item2[id] * 20);
curRow++;
}
curCell.SetCellValue(header.Key);
curCell.CellStyle = headerCellStyle;
if (header.Value.Item1.Count > 1)
{
curCol--;
curRow += header.Value.Item1.Count;
}
}
curCol = 2;
foreach (var data in info.Data)
{
curRow = 1;
foreach (var header in info.Headers.Values)
{
foreach (var (key, _) in header.Item1)
{
var property = typeof(T).GetProperty(key);
var cellValue = sheet.GetRow(curRow)?.CreateCell(curCol);
if (cellValue != null && property != null)
{
var value = property?.GetValue(data)?.ToString();
var rowHeight = GetRowHeight(key, info);
var currentRow = sheet.GetRow(curRow);
if (rowHeight != null)
{
currentRow.Height = (short)(rowHeight.Value * 20);
}
cellValue.SetCellValue(value);
cellValue.CellStyle = dataCellStyle;
}
curRow++;
}
}
curCol++;
}
using var fs = new FileStream(info.FilePath, FileMode.Create, FileAccess.Write);
workbook.Write(fs);
}
private static int? GetRowHeight<T>(string header, ExcelTableInfo<T> info) where T : class
{
foreach (var item in info.Headers)
{
foreach (var (key, displayName) in item.Value.Item1)
{
int id = item.Value.Item1.IndexOf((key, displayName));
if (key == header)
return item.Value.Item2[id];
}
}
return 0;
}
private static ICellStyle GetHeaderCellStyle(IWorkbook workbook)
{
var style = workbook.CreateCellStyle();
style.BorderBottom = BorderStyle.Thin;
style.BorderLeft = BorderStyle.Thin;
style.BorderRight = BorderStyle.Thin;
style.BorderTop = BorderStyle.Thin;
var font = workbook.CreateFont();
font.Boldweight = (short)FontBoldWeight.Bold;
style.SetFont(font);
style.Alignment = HorizontalAlignment.Center;
style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
return style;
}
private static ICellStyle GetDataCellStyle(IWorkbook workbook)
{
var style = workbook.CreateCellStyle();
style.BorderBottom = BorderStyle.Thin;
style.BorderLeft = BorderStyle.Thin;
style.BorderRight = BorderStyle.Thin;
style.BorderTop = BorderStyle.Thin;
return style;
}
}
public class Property
{
public string? Name { get; set; }
}
}