PIbd-33_Abazov_A.A._KOP_29/AbazovApp/AbazovViewComponents/LogicalComponents/ExcelTableComponent.cs
2023-10-15 18:07:28 +04:00

195 lines
8.7 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 Microsoft.Office.Core;
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Common;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace AbazovViewComponents.LogicalComponents
{
public partial class ExcelTableComponent : Component
{
public ExcelTableComponent()
{
InitializeComponent();
}
public ExcelTableComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
}
private string GetExcelColumnName(int columnNumber)
{
string columnName = "";
while (columnNumber > 0)
{
int modulo = (columnNumber - 1) % 26;
columnName = Convert.ToChar('A' + modulo) + columnName;
columnNumber = (columnNumber - modulo) / 26;
}
return columnName;
}
public bool createWithTable<T>(string path, string title, List<(int, int)> merges, List<int> heights, List<(string, string)> headers, List<T> items)
{
if (merges.Count == 0 || heights.Count == 0 || headers.Count == 0 || items.Count == 0) throw new ArgumentException("Недостаточно данных");
int[] cellsArray = new int[heights.Count];
foreach (var merge in merges)
{
if (merge.Item1 >= merge.Item2) throw new ArgumentException("Неправильно заполнены объединения строк");
for (int i = merge.Item1; i < merge.Item2; i++)
{
cellsArray[i]++;
}
}
foreach (int cell in cellsArray)
{
if (cell > 1) throw new ArgumentException("Объединения заходят друг на друга");
}
var excelApp = new Microsoft.Office.Interop.Excel.Application { SheetsInNewWorkbook = 1 };
Workbook workbook = excelApp.Workbooks.Add(Type.Missing);
try
{
//create
Worksheet worksheet = (Worksheet)workbook.Worksheets.get_Item(1);
//header
var excelcells = worksheet.get_Range("A1", "A1");
excelcells.Font.Bold = true;
excelcells.Font.Size = 14;
excelcells.Font.Name = "Times New Roman";
excelcells.ColumnWidth = 8;
excelcells.RowHeight = 25;
excelcells.HorizontalAlignment = Constants.xlCenter;
excelcells.VerticalAlignment = Constants.xlCenter;
excelcells.Value2 = title;
//checks
List<Microsoft.Office.Interop.Excel.Range> ranges = new List<Microsoft.Office.Interop.Excel.Range>();
foreach (var merge in merges)
{
ranges.Add(worksheet.get_Range("A" + (merge.Item1 + 2), "A" + (merge.Item2 + 2)));
}
int rangeIndex = 0;
int headerIndex = 0;
List<FieldInfo> cellFields = new List<FieldInfo>();
var type = typeof(T);
for (int i = 0; i < heights.Count; i++)
{
if (cellsArray[i] == 1)
{
//work with merge
if (!string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают");
var groupRange = ranges[rangeIndex];
groupRange.Merge(Type.Missing);
groupRange.Font.Bold = true;
groupRange.Font.Size = 14;
groupRange.Font.Name = "Times New Roman";
groupRange.ColumnWidth = 20;
groupRange.HorizontalAlignment = Constants.xlCenter;
groupRange.VerticalAlignment = Constants.xlCenter;
groupRange.Value2 = headers[headerIndex].Item2;
headerIndex++;
//work with cells in merge
for (; i <= merges[rangeIndex].Item2; i++)
{
//work with cell
if (string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают");
var field = type.GetField(headers[headerIndex].Item1);
if (field == null) throw new ArgumentException("В заголовках указано поле, которого нет в переданном классе");
//format header
var range = worksheet.get_Range("B" + (i + 2), "B" + (i + 2));
range.Font.Bold = true;
range.Font.Size = 14;
range.Font.Name = "Times New Roman";
range.ColumnWidth = 20;
range.RowHeight = heights[i];
range.HorizontalAlignment = Constants.xlCenter;
range.VerticalAlignment = Constants.xlCenter;
range.Value2 = headers[headerIndex].Item2;
cellFields.Add(field);
headerIndex++;
}
i--;
rangeIndex++;
}
else
{
//work with cell
if (string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают");
var field = type.GetField(headers[headerIndex].Item1);
if (field == null) throw new ArgumentException("В заголовках указано поле, которого нет в переданном классе");
//format header
var range = worksheet.get_Range("A" + (i + 2), "B" + (i + 2));
range.Merge(Type.Missing);
range.Font.Bold = true;
range.Font.Size = 14;
range.Font.Name = "Times New Roman";
range.ColumnWidth = 40;
range.RowHeight = heights[i];
range.HorizontalAlignment = Constants.xlCenter;
range.VerticalAlignment = Constants.xlCenter;
range.Value2 = headers[headerIndex].Item2;
cellFields.Add(field);
headerIndex++;
}
}
int columnNum = 3;
foreach (T item in items)
{
string column = GetExcelColumnName(columnNum);
int rowNum = 2;
foreach (var cellField in cellFields)
{
var range = worksheet.get_Range(column + rowNum, column + rowNum);
range.Font.Size = 14;
range.Font.Name = "Times New Roman";
range.ColumnWidth = 20;
range.HorizontalAlignment = Constants.xlCenter;
range.VerticalAlignment = Constants.xlCenter;
range.Value2 = cellField.FieldType == typeof(bool) ? ((bool) cellField.GetValue(item) ? "Да" : "Нет") : cellField.GetValue(item);
rowNum++;
}
columnNum++;
}
var borderRange = worksheet.get_Range("A2", GetExcelColumnName(columnNum-1) + (headerIndex - 1));
borderRange.Borders.LineStyle = XlLineStyle.xlContinuous;
borderRange.Borders.Weight = 2d;
//save
object missing = System.Reflection.Missing.Value;
workbook.SaveAs(path, XlFileFormat.xlOpenXMLWorkbook, missing, missing, false, false, XlSaveAsAccessMode.xlNoChange,
XlSaveConflictResolution.xlUserResolution, true, missing, missing, missing);
workbook.Close();
excelApp.Quit();
return true;
}
catch (Exception ex)
{
workbook.Close();
excelApp.Quit();
throw;
}
}
}
}