VisualComponents/VisualComponentsLib/Components/ComponentBigTable.cs
2023-10-11 12:14:23 +04:00

286 lines
9.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 DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VisualComponentsLib.Components.SupportClasses;
using Spire.Doc.Formatting;
using System.CodeDom;
using DocumentFormat.OpenXml.Vml;
namespace VisualComponentsLib.Components
{
public partial class ComponentBigTable : Component
{
private WordprocessingDocument? _wordDocument;
private Body? _docBody;
public ComponentBigTable()
{
InitializeComponent();
}
public ComponentBigTable(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateDoc<T> (SetDataTable<T> setDataTable)
{
//создаём документ word
_wordDocument = WordprocessingDocument.Create(setDataTable.FilePath, WordprocessingDocumentType.Document);
//вытаскиваем главную часть из вордовского документа
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
//генерируем тело основной части документа
_docBody = mainPart.Document.AppendChild(new Body());
_wordDocument.Close();
AddTable<T> (setDataTable);
}
//создание таблицы
private void AddTable<T> (SetDataTable<T> setDataTable)
{
if (!CheckData(setDataTable.DataList))
{
throw new Exception("Не все ячейки заполнены");
}
using (var document = WordprocessingDocument.Open(setDataTable.FilePath, true))
{
var doc = document.MainDocumentPart.Document;
#region Создание заголовка
ParagraphProperties paragraphProperties = new();
paragraphProperties.AppendChild(new Justification
{
Val = JustificationValues.Center
});
paragraphProperties.AppendChild(new Indentation());
Paragraph header = new();
header.AppendChild(paragraphProperties);
var docRun = new Run();
var properties = new RunProperties();
properties.AppendChild(new FontSize
{
Val = "48"
});
properties.Append(new Bold());
docRun.AppendChild(properties);
docRun.AppendChild(new Text(setDataTable.FileHeader));
header.AppendChild(docRun);
#endregion
#region Создание таблицы
Table table = new Table();
TableProperties props = new TableProperties(
new TableBorders(
new TopBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
new BottomBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
new LeftBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
new RightBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
new InsideHorizontalBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
new InsideVerticalBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
}
));
table.AppendChild<TableProperties>(props);
//генерация шапки таблицы
var _tr = new TableRow();
int indexHeaderHeigh = 0;
int indexHeaderWidth = 0;
//пробегаемся по словарю, чтобы сразу заполнять данные в нужной последовательности
foreach (var item in setDataTable.ColumnsSettings)
{
_tr.Append(new TableRowProperties(new TableRowHeight
{
Val = Convert.ToUInt32(setDataTable.HeightRow[indexHeaderHeigh])
}));
var tc = new TableCell();
tc.Append(new TableCellProperties(new TableCellWidth
{
Type = TableWidthUnitValues.Dxa,
Width = setDataTable.WidthCol[indexHeaderWidth].ToString(),
}
));
if (string.IsNullOrEmpty(setDataTable.ColumnsSettings[indexHeaderWidth].NameField) ||
string.IsNullOrEmpty(setDataTable.ColumnsSettings[indexHeaderWidth].NameColumn))
{
throw new Exception("Некорректное заполнение информации для шапки таблицы");
}
Paragraph tableHeader = new();
var Run = new Run();
var headerProperties = new RunProperties();
headerProperties.Append(new Bold());
Run.AppendChild(headerProperties);
Run.AppendChild(new Text(item.Value.NameColumn));
tableHeader.AppendChild(Run);
tc.Append(tableHeader);
_tr.Append(tc);
indexHeaderWidth++;
}
table.Append(_tr);
//увеличиваем счётчик на 1, т. к. в списке только два значения
indexHeaderHeigh++;
indexHeaderWidth = 0;
int numberColunm = 0;
//генерация тела таблицы
for (var i = 1; i < setDataTable.DataList.Count; i++)
{
var tr = new TableRow();
//пробегаемся по словарю, чтобы сразу добавлять значения в нужном порядке
foreach (var item in setDataTable.ColumnsSettings)
{
tr.Append(new TableRowProperties(new TableRowHeight
{
Val = Convert.ToUInt32(setDataTable.HeightRow[indexHeaderHeigh])
}));
var tc = new TableCell();
tc.Append(new TableCellProperties(new TableCellWidth
{
Type = TableWidthUnitValues.Dxa,
Width = setDataTable.WidthCol[indexHeaderWidth].ToString(),
}
));
//вытаскиваем нужное значение
foreach(var val in setDataTable.DataList[i].GetType().GetProperties())
{
if(val.Name == item.Value.NameField)
{
var newParagraph = new Paragraph();
var newRun = new Run();
var runProperties = new RunProperties();
if(indexHeaderWidth == 0)
{
runProperties.Append(new Bold());
}
newRun.AppendChild(runProperties);
newRun.AppendChild(new Text(val.GetValue(setDataTable.DataList[i]).ToString()));
newParagraph.AppendChild(newRun);
tc.Append(newParagraph);
break;
}
}
tr.Append(tc);
indexHeaderWidth++;
}
indexHeaderWidth = 0;
table.Append(tr);
}
#endregion
doc.Body.Append(header);
doc.Body.Append(table);
doc.Save();
}
}
//проверка заполненности входных значений
bool CheckData<T>(List<T> dataList)
{
foreach(var data in dataList)
{
foreach (var value in data.GetType().GetProperties())
{
//для простоты проверки приводим значение каждого поля к типу string
if(string.IsNullOrEmpty(value.GetValue(data).ToString()))
{
return false;
}
}
}
return true;
}
}
}