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

115 lines
4.5 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.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;
}
}
}