KOP_Library_v5/ViewComponents/NotVisualComponents/PdfTable.cs

178 lines
6.1 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>(DataForPDFTable<T> dataForPDF)
{
//проверки
if (dataForPDF.Merges.Count == 0 || dataForPDF.Heights.Count == 0 || dataForPDF.Headers.Count == 0
|| dataForPDF.Data.Count == 0 || string.IsNullOrEmpty(dataForPDF.FilePath)
|| string.IsNullOrEmpty(dataForPDF.DocumentTitle)) throw new ArgumentException("Недостаточно данных");
int[] cellsArray = new int[dataForPDF.Heights.Count];
foreach (var merge in dataForPDF.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("Объединения заходят друг на друга");
}
foreach ((string, string) el in dataForPDF.Headers)
if (string.IsNullOrEmpty(el.Item2)) 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(dataForPDF.DocumentTitle);
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 < dataForPDF.Data.Count + 2; i++)
{
column = table.AddColumn();
column.Format.Alignment = ParagraphAlignment.Center;
}
// создание шапки и заполнение контентом
int mergeRange = 0; //размерность слияния
int mergeIndex = 0; //стартовый индекс начала слияния
Row row;
for (int i = 0; i < dataForPDF.Headers.Count; i++)
{
//если элемент шапки группируются по строкам
if (dataForPDF.Merges.Select(x => x.Item1).Contains(mergeIndex))
{
mergeRange = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 - mergeIndex;
mergeIndex = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 + 1;
//стилизация ячейки. в этом блоке кода (до цикла) создаётся объединяющая ячейка
row = table.AddRow();
row.Height = dataForPDF.Heights[i];
row.Format.Alignment = ParagraphAlignment.Center;
row.Format.Font.Bold = true;
row.Cells[0].AddParagraph(dataForPDF.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(dataForPDF.Headers[i].Item2);
AddTheContent<T>(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2);
row.Cells[1].VerticalAlignment = VerticalAlignment.Center;
row = table.AddRow();
row.Height = dataForPDF.Heights[i];
row.Format.Font.Bold = true;
row.Format.Alignment = ParagraphAlignment.Center;
}
i++;
row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2);
AddTheContent<T>(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2);
row.Cells[1].VerticalAlignment = VerticalAlignment.Center;
}
else //если элемент шапки не группируется по строкам
{
//стилизация ячейки
row = table.AddRow();
row.Height = dataForPDF.Heights[i];
row.Format.Font.Bold = true;
row.Format.Alignment = ParagraphAlignment.Center;
row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2);
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
row.Cells[0].MergeRight = 1;
AddTheContent<T>(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2);
mergeIndex++;
}
}
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = _document;
renderer.RenderDocument();
renderer.PdfDocument.Save(dataForPDF.FilePath);
return true;
}
//метод заполнения таблицы контентом, заполнение происходит построчно.
public void AddTheContent<T>(List<T> items, Table table, string header, 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();
var field = fields.FirstOrDefault(x => x.Name.Equals(header));
r.Cells[cell_index + i].AddParagraph(field.GetValue(item).ToString());
r.Cells[cell_index + i].VerticalAlignment = VerticalAlignment.Center;
}
}
}
}
}
}