PIbd-31_Rodionov.I.A._COP_28/COP/RodionovLibrary/NonVisualComponents/WordTableComponent.cs

198 lines
8.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 Word = Microsoft.Office.Interop.Word;
using System.ComponentModel;
using RodionovLibrary.NonVisualComponents.HelperModels;
namespace RodionovLibrary.NonVisualComponents
{
public partial class WordTableComponent : Component
{
public WordTableComponent()
{
InitializeComponent();
}
public WordTableComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateTable<T>(WordTableInfo<T> tableInfo)
{
ValidateInputData(tableInfo);
var wordApp = new Word.Application();
var document = wordApp.Documents.Add();
var range = document.Range();
var paragraph = range.Paragraphs.Add();
paragraph.Range.Text = tableInfo.Title;
paragraph.Range.Font.Name = "Times New Roman";
paragraph.Range.Font.Size = 18;
paragraph.Range.Font.Bold = 1;
paragraph.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
paragraph.Range.ParagraphFormat.SpaceAfter = 8;
paragraph.Range.InsertParagraphAfter();
var table = document.Tables.Add(paragraph.Range, tableInfo.Items.Count + 2, tableInfo.ColumnParameters.Count);
table.Borders.Enable = 1;
table.Range.Font.Name = "Times New Roman";
table.Range.Font.Size = 11;
for (int i = 0; i < tableInfo.ColumnParameters.Count; i++)
{
table.Columns[i + 1].Width = (float)(tableInfo.ColumnParameters[i].Width * 28.35);
}
AddTableHeaderRow(table, tableInfo.ColumnParameters, true);
AddTableHeaderRow(table, tableInfo.ColumnParameters, false);
MergeColumns(table, tableInfo.MergedColumns);
AddTableData(table, tableInfo.Items, tableInfo.ColumnParameters);
document.SaveAs2(tableInfo.FileName);
wordApp.Quit();
}
private void AddTableHeaderRow(Word.Table table, List<ColumnParameters> columnParameters, bool isFirstRow)
{
for (int i = 0; i < columnParameters.Count; i++)
{
var header = isFirstRow ? columnParameters[i].FirstRowHeader : columnParameters[i].SecondRowHeader;
if (!string.IsNullOrEmpty(header))
{
var cell = table.Cell(isFirstRow ? 1 : 2, i + 1);
cell.Range.Text = header;
cell.Range.Bold = 1;
cell.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
cell.VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
cell.Range.ParagraphFormat.SpaceBefore = 4;
cell.Range.ParagraphFormat.SpaceAfter = 4;
}
}
}
private void MergeColumns(Word.Table table, List<(int start, int end)> mergedColumns)
{
for (int i = 1; i <= table.Columns.Count; i++)
{
bool isMergedHorizontally = mergedColumns.Any(m => m.start <= i - 1 && m.end >= i - 1);
if (!isMergedHorizontally)
{
table.Cell(1, i).Merge(table.Cell(2, i));
}
}
int xOffset = 0;
foreach (var (start, end) in mergedColumns)
{
var cellStart = table.Cell(1, start + 1 - xOffset);
var cellEnd = table.Cell(1, end + 1 - xOffset);
string textToKeep = cellStart.Range.Text.TrimEnd('\r', '\a');
cellStart.Merge(cellEnd);
cellStart.Range.Text = textToKeep;
xOffset += end - start;
}
}
private void AddTableData<T>(Word.Table table, List<T> items, List<ColumnParameters> columnParameters)
{
for (int rowIndex = 0; rowIndex < items.Count; rowIndex++)
{
var item = items[rowIndex];
for (int colIndex = 0; colIndex < columnParameters.Count; colIndex++)
{
var property = typeof(T).GetProperty(columnParameters[colIndex].PropertyName);
var value = property?.GetValue(item)?.ToString() ?? string.Empty;
table.Cell(rowIndex + 3, colIndex + 1).Range.Text = value;
table.Cell(rowIndex + 3, colIndex + 1).Range.Bold = 0;
table.Cell(rowIndex + 3, colIndex + 1).Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
table.Cell(rowIndex + 3, colIndex + 1).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(rowIndex + 3, colIndex + 1).Range.ParagraphFormat.SpaceBefore = 2;
table.Cell(rowIndex + 3, colIndex + 1).Range.ParagraphFormat.SpaceAfter = 2;
}
}
}
private void ValidateInputData<T>(WordTableInfo<T> tableInfo)
{
if (string.IsNullOrEmpty(tableInfo.FileName) || string.IsNullOrEmpty(tableInfo.Title))
{
throw new ArgumentException("Не все данные заполнены");
}
CheckColumnParameters(tableInfo.ColumnParameters);
if (tableInfo.Items == null || tableInfo.Items.Count == 0)
{
throw new ArgumentException("Данные для основной части таблицы не заданы");
}
foreach (var column in tableInfo.ColumnParameters)
{
if (typeof(T).GetProperty(column.PropertyName) == null)
{
throw new ArgumentException($"Свойство '{column.PropertyName}' не найдено в классе {typeof(T).Name}.");
}
}
ValidateMergedColumns(tableInfo.MergedColumns, tableInfo.ColumnParameters.Count);
}
private void CheckColumnParameters(List<ColumnParameters> columnParameters)
{
if (columnParameters == null || columnParameters.Count == 0)
{
throw new ArgumentException("Не заданы колонки для таблицы");
}
foreach (var column in columnParameters)
{
if (string.IsNullOrEmpty(column.FirstRowHeader) && string.IsNullOrEmpty(column.SecondRowHeader))
{
throw new ArgumentException("Заголовок не задан для одной из колонок в таблице");
}
if (column.Width <= 0)
{
throw new ArgumentException("Ширина колонки должна быть больше нуля.");
}
if (string.IsNullOrEmpty(column.PropertyName))
{
throw new ArgumentException("Свойство не задано для одной из колонок.");
}
}
}
private void ValidateMergedColumns(List<(int start, int end)> mergedColumns, int totalColumns)
{
if (mergedColumns == null || mergedColumns.Count == 0)
{
return;
}
foreach (var (start, end) in mergedColumns)
{
if (start < 0 || end >= totalColumns)
{
throw new ArgumentException("Индексы объединенных колонок выходят за пределы допустимых значений.");
}
var overlappingRanges = mergedColumns
.Where(m => m != (start, end))
.Any(m => m.start <= end && m.end >= start);
if (overlappingRanges)
{
throw new ArgumentException("Объединенные ячейки пересекаются.");
}
}
}
}
}