176 lines
6.2 KiB
C#
176 lines
6.2 KiB
C#
using COP.Info;
|
|
using DocumentFormat.OpenXml.EMMA;
|
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
|
using DocumentFormat.OpenXml.Spreadsheet;
|
|
using NPOI.HSSF.Util;
|
|
using NPOI.SS.UserModel;
|
|
using NPOI.SS.Util;
|
|
using NPOI.XSSF.UserModel;
|
|
using System;
|
|
using System.ComponentModel;
|
|
using BorderStyle = NPOI.SS.UserModel.BorderStyle;
|
|
using HorizontalAlignment = NPOI.SS.UserModel.HorizontalAlignment;
|
|
|
|
namespace COP
|
|
{
|
|
public partial class ExcelTable : Component
|
|
{
|
|
public ExcelTable()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public ExcelTable(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("Sheet1");
|
|
|
|
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.Item1.Count > 1)
|
|
{
|
|
sheet.AddMergedRegion(new CellRangeAddress(curRow, curRow + header.Value.Item1.Item1.Count - 1, curCol, curCol));
|
|
curCol++;
|
|
foreach (var item in header.Value.Item1.Item2)
|
|
{
|
|
int id = header.Value.Item1.Item2.IndexOf(item);
|
|
var cellValue = currentRow.CreateCell(1);
|
|
cellValue.SetCellValue(item);
|
|
currentRow.Height = (short)(header.Value.Item2[id] * 20);
|
|
headers.Add(item);
|
|
cellValue.CellStyle = headerCellStyle;
|
|
currentRow = sheet.CreateRow(currentRow.RowNum + 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int id = header.Value.Item1.Item1.IndexOf(header.Value.Item1.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.Item1.Count > 1)
|
|
{
|
|
curCol--;
|
|
curRow += header.Value.Item1.Item1.Count;
|
|
}
|
|
}
|
|
|
|
curCol = 2;
|
|
foreach (var data in info.Data)
|
|
{
|
|
curRow = 1;
|
|
|
|
foreach (var header in info.Headers.Values)
|
|
{
|
|
foreach (var item in header.Item1.Item1)
|
|
{
|
|
var property = typeof(T).GetProperty(item);
|
|
var cellValue = sheet.GetRow(curRow)?.CreateCell(curCol);
|
|
if (cellValue != null && property != null)
|
|
{
|
|
var value = property?.GetValue(data)?.ToString();
|
|
var rowHeight = GetRowHeight(item, 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 elem in item.Value.Item1.Item1)
|
|
{
|
|
int id = item.Value.Item1.Item1.IndexOf(elem);
|
|
if (item.Value.Item1.Item1[id] == 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 = 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; }
|
|
}
|
|
}
|