COP/ExcelComponents/ExcelBuilder.cs
2024-07-29 20:21:07 +04:00

222 lines
5.8 KiB
C#

using ExcelComponents.Models;
using OfficeOpenXml;
using OfficeOpenXml.Drawing.Chart;
using OfficeOpenXml.Style;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ExcelComponents
{
public class ExcelBuilder
{
private ExcelPackage? package = null;
private ExcelWorksheet? worksheet = null;
public ExcelBuilder()
{
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
}
private void SetStyle(int row, int col, ExcelCellStyle style)
{
if (worksheet == null)
{
return;
}
ExcelStyle excelStyle = worksheet.Cells[row, col].Style;
excelStyle.WrapText = style.WrapText;
excelStyle.HorizontalAlignment = style.HorizontalAlignment;
excelStyle.VerticalAlignment = style.VerticalAlignment;
excelStyle.Border.Top.Style = style.TopBorderStyle;
excelStyle.Border.Bottom.Style = style.BottomBorderStyle;
excelStyle.Border.Left.Style = style.LeftBorderStyle;
excelStyle.Border.Right.Style = style.RightBorderStyle;
}
private void SetStyle(int row, int col, int endRow, int endCol, ExcelCellStyle style)
{
if (worksheet == null)
{
return;
}
ExcelStyle excelStyle = worksheet.Cells[row, col, endRow, endCol].Style;
excelStyle.WrapText = style.WrapText;
excelStyle.HorizontalAlignment = style.HorizontalAlignment;
excelStyle.VerticalAlignment = style.VerticalAlignment;
excelStyle.Border.Top.Style = style.TopBorderStyle;
excelStyle.Border.Bottom.Style = style.BottomBorderStyle;
excelStyle.Border.Left.Style = style.LeftBorderStyle;
excelStyle.Border.Right.Style = style.RightBorderStyle;
}
private void MergeCells(int row, int col, int endRow, int endCol, ExcelCellStyle? style = null)
{
if(worksheet == null) { return; }
worksheet.Cells[row, col, endRow, endCol].Merge = true;
style ??= new();
SetStyle(row, col, endRow, endCol, style);
}
public void ConfigureColumns(double[] columnWidth)
{
if(worksheet == null)
{
return;
}
for(int i = 0; i < columnWidth.Length; i++)
{
worksheet.Column(i+1).Width = columnWidth[i];
}
}
public void CreateDocument()
{
package = new();
worksheet = package.Workbook.Worksheets.Add("First list");
}
public void SaveDocument(string filePath)
{
package?.SaveAs(filePath);
}
public void InsertText(int row, int column, string str,ExcelCellStyle? style = null)
{
if(worksheet == null)
{
return;
}
worksheet.Cells[row, column].Value = str;
style ??= new();
SetStyle(row, column, style);
}
private static string GetPropertyValue<T>(string propertyName, T obj)
{
Type type = typeof(T);
string value = type.GetProperty(propertyName)!.GetValue(obj, null).ToString()!;
return value;
}
public void InsertTable<T>(Dictionary<int, int> merge, string[] headers, string[] props, T[] data )
{
if(worksheet == null)
{
return;
}
ExcelCellStyle style = new()
{
NoBorder = false,
WrapText = true,
};
int rowInd = 2;
int colStart = 1;
int colInd = colStart;
int mergeskip = 0;
foreach(string header in headers){
InsertText(rowInd, colInd, header,style);
if (mergeskip == 0)
{
if (!merge.ContainsKey(colInd - colStart))
{
MergeCells(rowInd, colInd, rowInd + 1, colInd, style);
colInd++;
}
else
{
int colEnd = colInd + merge[colInd - colStart] - 1;
MergeCells(rowInd, colInd, rowInd, colEnd, style);
rowInd = 3;
mergeskip = merge[colInd - colStart];
}
}
else
{
mergeskip--;
colInd++;
if(mergeskip == 0)
{
rowInd = 2;
}
}
}
rowInd++;
for(int i = 0; i < data.Length; i++)
{
colInd = colStart;
rowInd++;
foreach(string prop in props)
{
string value = GetPropertyValue(prop, data[i]);
InsertText(rowInd, colInd, value, style);
colInd++;
}
}
}
public void InsertBigText(string[] text, ExcelCellStyle? style = null)
{
if (worksheet == null)
{
return;
}
style ??= new() { HorizontalAlignment = ExcelHorizontalAlignment.Left};
for (int i = 0; i < text.Length; i++)
{
worksheet.Cells[i + 2, 1].Value = text[i];
MergeCells(i + 2, 1, i + 2, text[i].Length / 7 + 1, style);
}
}
public void InsertLinearChart(string chartTitle, List<(string, double[])> data, string[] labels, ChartLegendPosition legendPosition)
{
if(worksheet == null) { return; }
ExcelChart linearchar = (ExcelLineChart)worksheet.Drawings.AddChart("Linear Chart", eChartType.Line);
linearchar.Title.Text = chartTitle;
foreach(var item in data)
{
linearchar.Series.Add(ArrayToString(item.Item2)).Header = item.Item1;
}
linearchar.Series[0].XSeries = ArrayToString(labels);
linearchar.Legend.Position = GetLegendPosition(legendPosition);
linearchar.SetSize(500, 500);
linearchar.SetPosition(1, 0, 0, 0);
}
private static string ArrayToString<T>(T[] data)
{
StringBuilder builder = new StringBuilder("{");
for(int i = 0; i < data.Length; i++)
{
if (typeof(T) == typeof(string))
{
builder.Append($"\"{data[i]}\"");
}
else if (typeof(T) == typeof(double))
{
builder.Append(data[i].ToString().Replace(",", "."));
}
else
{
builder.Append(data[i].ToString());
}
if(i == data.Length - 1)
{
builder.Append('}');
}
else
{
builder.Append(',');
}
}
return builder.ToString();
}
private static eLegendPosition GetLegendPosition(ChartLegendPosition legendPosition)
{
return legendPosition switch
{
ChartLegendPosition.Top => eLegendPosition.Top,
ChartLegendPosition.Bottom => eLegendPosition.Bottom,
ChartLegendPosition.Left => eLegendPosition.Left,
ChartLegendPosition.Right => eLegendPosition.Right,
_ => eLegendPosition.Right
};
}
}
}