Files
Backend-Api/0_Framework/Excel/ExcelGenerator.cs

203 lines
7.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using LicenseContext = OfficeOpenXml.LicenseContext;
namespace _0_Framework.Excel;
public class ExcelGenerator
{
public ExcelGenerator()
{
OfficeOpenXml.ExcelPackage.License.SetNonCommercialOrganization("Gozareshgir Noncommercial organization");
}
public static byte[] GenerateExcel<T>(List<T> obj, string date = "") where T : class
{
var templatePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Test", "template (2).xlsx");
// Open the template
FileInfo fileInfo = new FileInfo(templatePath);
using ExcelPackage package = new ExcelPackage(fileInfo);
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
var titles = GetNonEmptyDisplayNames<T>(obj);
var col = 1;
for (int i = 0; i < titles.Count; i++)
{
worksheet.Cells[1, col].Value = titles[i];
col++;
}
int row = 2;
foreach (var item in obj)
{
int column = 1;
foreach (var prop in typeof(T).GetProperties())
{
var displayNameAttr = prop.GetCustomAttribute<DisplayNameAttribute>();
if (displayNameAttr != null && titles.Contains(displayNameAttr.DisplayName))
{
var value = prop.GetValue(item);
worksheet.Cells[row, column].Value = value?.ToString();
column++;
}
}
row++;
}
worksheet.View.RightToLeft = true;
worksheet.HeaderFooter.OddHeader.LeftAlignedText = !string.IsNullOrWhiteSpace(date)
? $"تاریخ: {date}\r\nشماره ثبت: 1727"
: "شماره ثبت: 1727";
return package.GetAsByteArray();
}
public static byte[] CreateExcel<T>(List<T> dataList)
{
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
// Add property names as sub-header using DisplayName attribute
var properties = typeof(T).GetProperties();
for (int i = 0; i < properties.Length; i++)
{
var displayNameAttribute = properties[i].GetCustomAttribute<DisplayNameAttribute>();
var displayName = displayNameAttribute != null ? displayNameAttribute.DisplayName : properties[i].Name;
worksheet.Cells[3, i + 1].Value = displayName;
}
// Populate data and calculate column widths
for (int i = 0; i < dataList.Count; i++)
{
for (int j = 0; j < properties.Length; j++)
{
var cellValue = properties[j].GetValue(dataList[i]);
worksheet.Cells[i + 4, j + 1].Value = cellValue;
}
}
// Calculate total width of all filled columns
worksheet.Cells.AutoFitColumns(); // AutoFit columns to calculate their widths correctly
double totalDataWidth = 0;
for (int i = 1; i <= properties.Length; i++)
{
totalDataWidth += worksheet.Column(i).Width;
}
double headerWidth = totalDataWidth / 3.0;
// Create dynamic headers with adjusted widths
int totalColumns = properties.Length;
int colEnd1 = (int)Math.Floor((double)totalColumns / 3.0);
int colStart2 = colEnd1 + 1;
int colEnd2 = colStart2 + (int)Math.Floor((double)totalColumns / 3.0) - 1;
int colStart3 = colEnd2 + 1;
int colEnd3 = totalColumns;
worksheet.Cells[1, 1, 2, colEnd1].Merge = true;
worksheet.Cells[1, 1, 2, colEnd1].Value = "Dynamic Header 1";
worksheet.Column(1).Width = headerWidth;
worksheet.Cells[1, colStart2, 2, colEnd2].Merge = true;
worksheet.Cells[1, colStart2, 2, colEnd2].Value = "Dynamic Header 2";
worksheet.Column(colStart2).Width = headerWidth;
worksheet.Cells[1, colStart3, 2, colEnd3].Merge = true;
worksheet.Cells[1, colStart3, 2, colEnd3].Value = "Dynamic Header 3";
worksheet.Column(colStart3).Width = headerWidth;
// Add footer
worksheet.Cells[dataList.Count + 4, 1].Value = "Footer";
worksheet.Cells[dataList.Count + 4, 1, dataList.Count + 4, totalColumns].Merge = true;
// Return as byte array
return package.GetAsByteArray();
}
}
public static List<string> GetDisplayNames<T>(List<T> obj)
{
return typeof(T).GetProperties()
.Select(prop => prop.GetCustomAttribute<DisplayNameAttribute>())
.Where(attr => attr != null)
.Select(attr => attr.DisplayName)
.ToList();
}
public static List<string> GetNonEmptyDisplayNames<T>(List<T> obj)
{
var displayNames = new List<string>();
var item = obj.FirstOrDefault();
foreach (var prop in typeof(T).GetProperties())
{
var displayNameAttr = prop.GetCustomAttribute<DisplayNameAttribute>();
if (displayNameAttr != null)
{
var value = prop.GetValue(item) as string;
if (!string.IsNullOrEmpty(value))
{
displayNames.Add(displayNameAttr.DisplayName);
}
}
}
return displayNames.Distinct().ToList(); // Using Distinct to avoid duplicate display names
}
public record ExcelTestVm(long Id, string Name, DateTime DateTime);
public List<ExcelTestVm> GetDataFromExcel(Stream fileStream)
{
var resultList = new List<ExcelTestVm>();
using var package = new ExcelPackage(fileStream);
var worksheet = package.Workbook.Worksheets[0]; // Assuming first sheet
int rows = worksheet.Dimension.Rows;
for (int row = 2; row <= rows; row++) // Skipping the header row
{
var idCell = worksheet.Cells[row, 1].Text;
var nameCell = worksheet.Cells[row, 2].Text;
var birthDateCell = worksheet.Cells[row, 3].Text;
// Validation
if (string.IsNullOrEmpty(idCell) || string.IsNullOrEmpty(nameCell) ||
string.IsNullOrEmpty(birthDateCell))
{
throw new Exception($"Row {row}: Missing required data.");
}
if (!int.TryParse(idCell, out int id))
{
throw new Exception($"Row {row}: Invalid data type for ID.");
}
if (!DateTime.TryParse(birthDateCell, out DateTime birthDate))
{
throw new Exception($"Row {row}: Invalid date format for Birth Date.");
}
var data = new ExcelTestVm(id, nameCell, birthDate);
resultList.Add(data);
}
return resultList;
}
}