115 lines
4.5 KiB
C#
115 lines
4.5 KiB
C#
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;
|
||
}
|
||
}
|
||
} |