PIbd-31_PotapovNS_COP_20/WinFormSolution/Components/ComponentExcelTableWithColumnHeader.cs

115 lines
4.5 KiB
C#
Raw Normal View History

2024-10-23 17:56:27 +04:00
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace Components
{
public partial class ComponentExcelTableWithColumnHeader : Component
{
public ComponentExcelTableWithColumnHeader()
{
InitializeComponent();
}
public ComponentExcelTableWithColumnHeader(IContainer container) : this()
{
container.Add(this);
}
public void GenerateExcelFile<T>(
string filePath,
string documentTitle,
List<(int StartRow, int EndRow, int StartCol, int EndCol, string title)> mergeCellsInfo,
List<T> tableData,
List<(string title, string propertyName, float height)> headersConfig)
{
if (string.IsNullOrEmpty(filePath) || headersConfig == null)
{
throw new ArgumentException("Все входные данные должны быть заполнены.");
}
Excel.Application excelApp = new Excel.Application();
excelApp.Visible = false;
Excel.Workbook workbook = excelApp.Workbooks.Add();
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets[1];
worksheet.Cells[1, 1].Value = documentTitle;
worksheet.Range[worksheet.Cells[1, 1], worksheet.Cells[1, tableData.Count + 2]].Merge();
worksheet.Cells[1, 1].HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
for (int i = 0; i < headersConfig.Count; i++)
{
worksheet.Cells[2 + i, 2].Value = headersConfig[i].title;
worksheet.Cells[2 + i, 2].Font.Bold = true;
worksheet.Rows[i + 1].RowHeight = headersConfig[i].height;
}
for (int colIndex = 0; colIndex < tableData.Count; colIndex++)
{
var data = tableData[colIndex];
for (int rowIndex = 0; rowIndex < headersConfig.Count; rowIndex++)
{
var property = data.GetType().GetProperty(headersConfig[rowIndex].propertyName);
if (property != null)
{
worksheet.Cells[rowIndex + 2, colIndex + 3].Value = property.GetValue(data);
}
}
}
List<int> rows = new List<int>();
foreach (var mergeInfo in mergeCellsInfo)
{
ValidateMergeCells(mergeCellsInfo);
worksheet.Range[worksheet.Cells[mergeInfo.StartRow + 1, mergeInfo.StartCol],
worksheet.Cells[mergeInfo.EndRow + 1, mergeInfo.EndCol]].Merge();
worksheet.Cells[mergeInfo.StartRow + 1, mergeInfo.StartCol].Value = mergeInfo.title;
for (int r = mergeInfo.StartRow + 1; r <= mergeInfo.EndRow + 1; r++)
{
rows.Add(r);
}
}
for (int i = 2; i < headersConfig.Count + 2; i++)
{
if (!rows.Contains(i))
{
worksheet.Range[worksheet.Cells[i, 1], worksheet.Cells[i, 2]].Merge();
}
}
workbook.SaveAs(filePath);
workbook.Close();
Marshal.ReleaseComObject(workbook);
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
}
private void ValidateMergeCells(List<(int StartRow, int EndRow, int StartCol, int EndCol, string title)> mergeCellsInfo)
{
for (int i = 0; i < mergeCellsInfo.Count; i++)
{
for (int j = i + 1; j < mergeCellsInfo.Count; j++)
{
if (CellsOverlap(mergeCellsInfo[i], mergeCellsInfo[j]))
{
throw new InvalidOperationException("Объединенные ячейки пересекаются.");
}
}
}
}
private bool CellsOverlap(
(int StartRow, int EndRow, int StartCol, int EndCol, string title) range1,
(int StartRow, int EndRow, int StartCol, int EndCol, string title) range2)
{
bool rowsOverlap = range1.StartRow <= range2.EndRow && range1.EndRow >= range2.StartRow;
bool colsOverlap = range1.StartCol <= range2.EndCol && range1.EndCol >= range2.StartCol;
return rowsOverlap && colsOverlap;
}
}
}