KOP_Library_v5/ViewComponents/NotVisualComponents/PdfTable.cs

171 lines
5.4 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 MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
using PdfSharp.Pdf.Content.Objects;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ViewComponents.NotVisualComponents
{
public partial class PdfTable : Component
{
public PdfTable()
{
InitializeComponent();
}
public PdfTable(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public bool createTable<T>(string filepath, string header, List<(int, int)> merges, List<int> heights, List<(bool, 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("Объединения заходят друг на друга");
}
//создание документа
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Document _document = new Document();
var style = _document.Styles["Normal"];
style = _document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Name = "Arial";
style.Font.Size = 25;
style.Font.Bold = true;
style = _document.Styles.AddStyle("Table", "Normal");
style.Font.Name = "Times New Roman";
style.Font.Size = 12;
//добавление заголовка
var section = _document.AddSection();
var paragraph = section.AddParagraph(header);
paragraph.Format.Alignment = ParagraphAlignment.Center;
paragraph.Format.SpaceAfter = "2cm";
paragraph.Style = "NormalTitle";
//добавление таблицы
Table table = section.AddTable();
table.Style = "Table";
table.Borders.Width = 0.25;
Column column;
for (int i = 0; i < items.Count + 2; i++)
{
column = table.AddColumn();
column.Format.Alignment = ParagraphAlignment.Center;
}
// создание шапки и заполнение контентом
int mergeRange = 0; //размерность слияния
int mergeIndex = 0; //стартовый индекс начала слияния
Row row;
for (int i = 0; i < headers.Count; i++)
{
//если элемент шапки не группируется по строкам
if (headers[i].Item1 == false)
{
//стилизация ячейки
row = table.AddRow();
row.Height = heights[i];
row.Format.Font.Bold = true;
row.Format.Alignment = ParagraphAlignment.Center;
row.Cells[0].AddParagraph(headers[i].Item2);
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
row.Cells[0].MergeRight = 1;
AddTheContent<T>(items, table, row.Index, 2);
mergeIndex++;
}
//если элемент шапки группируются по строкам
if (headers[i].Item1 == true)
{
mergeRange = merges.Find(x => x.Item1 == mergeIndex).Item2 - mergeIndex;
mergeIndex = merges.Find(x => x.Item1 == mergeIndex).Item2 + 1;
//стилизация ячейки. в этом блоке кода (до цикла) создаётся объединяющая ячейка
row = table.AddRow();
row.Height = heights[i];
row.Format.Alignment = ParagraphAlignment.Center;
row.Format.Font.Bold = true;
row.Cells[0].AddParagraph(headers[i].Item2);
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
row.Cells[0].MergeDown = mergeRange;
//с этого места создаются дочерние ячейки
for (int k = 0; k<mergeRange; k++)
{
i++;
row.Cells[1].AddParagraph(headers[i].Item2);
AddTheContent<T>(items, table, row.Index, 2);
row.Cells[1].VerticalAlignment = VerticalAlignment.Center;
row = table.AddRow();
row.Height = heights[i];
row.Format.Font.Bold = true;
row.Format.Alignment = ParagraphAlignment.Center;
}
i++;
row.Cells[1].AddParagraph(headers[i].Item2);
AddTheContent<T>(items, table, row.Index, 2);
row.Cells[1].VerticalAlignment = VerticalAlignment.Center;
}
}
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = _document;
renderer.RenderDocument();
renderer.PdfDocument.Save(filepath);
return true;
}
//метод заполнения таблицы контентом, заполнение происходит построчно.
public void AddTheContent<T>(List<T> items, Table table, int row_index, int cell_index)
{
foreach (Row r in table.Rows)
{
for (int i = 0; i<items.Count; i++)
{
if (r.Index == row_index && row_index == 0) r.Cells[cell_index+i].AddParagraph((i+1).ToString());
else if(row_index!=0 && r.Index == row_index)
{
T item = items[i];
var type = typeof(T);
var fields = type.GetFields();
r.Cells[cell_index + i].AddParagraph(fields[row_index-1].GetValue(item).ToString());
r.Cells[cell_index + i].VerticalAlignment = VerticalAlignment.Center;
}
}
}
}
}
}