2023-11-15 22:29:35 +04:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 17:28:16 +04:00
|
|
|
|
public bool createTable<T>(DataForPDFTable<T> dataForPDF)
|
2023-11-15 22:29:35 +04:00
|
|
|
|
{
|
|
|
|
|
//проверки
|
2023-11-16 17:28:16 +04:00
|
|
|
|
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)
|
2023-11-15 22:29:35 +04:00
|
|
|
|
{
|
|
|
|
|
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("Объединения заходят друг на друга");
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 17:28:16 +04:00
|
|
|
|
foreach ((bool, string) el in dataForPDF.Headers)
|
|
|
|
|
if (string.IsNullOrEmpty(el.Item2)) throw new ArgumentException("Элементы шапки не могут быть пустыми");
|
|
|
|
|
|
2023-11-15 22:29:35 +04:00
|
|
|
|
//создание документа
|
|
|
|
|
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();
|
2023-11-16 17:28:16 +04:00
|
|
|
|
var paragraph = section.AddParagraph(dataForPDF.DocumentTitle);
|
2023-11-15 22:29:35 +04:00
|
|
|
|
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;
|
|
|
|
|
|
2023-11-16 17:28:16 +04:00
|
|
|
|
for (int i = 0; i < dataForPDF.Data.Count + 2; i++)
|
2023-11-15 22:29:35 +04:00
|
|
|
|
{
|
|
|
|
|
column = table.AddColumn();
|
|
|
|
|
column.Format.Alignment = ParagraphAlignment.Center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// создание шапки и заполнение контентом
|
|
|
|
|
|
|
|
|
|
int mergeRange = 0; //размерность слияния
|
|
|
|
|
int mergeIndex = 0; //стартовый индекс начала слияния
|
|
|
|
|
Row row;
|
2023-11-16 17:28:16 +04:00
|
|
|
|
for (int i = 0; i < dataForPDF.Headers.Count; i++)
|
2023-11-15 22:29:35 +04:00
|
|
|
|
{
|
|
|
|
|
//если элемент шапки не группируется по строкам
|
2023-11-16 17:28:16 +04:00
|
|
|
|
if (dataForPDF.Headers[i].Item1 == false)
|
2023-11-15 22:29:35 +04:00
|
|
|
|
{
|
|
|
|
|
//стилизация ячейки
|
|
|
|
|
row = table.AddRow();
|
2023-11-16 17:28:16 +04:00
|
|
|
|
row.Height = dataForPDF.Heights[i];
|
2023-11-15 22:29:35 +04:00
|
|
|
|
row.Format.Font.Bold = true;
|
|
|
|
|
row.Format.Alignment = ParagraphAlignment.Center;
|
2023-11-16 17:28:16 +04:00
|
|
|
|
row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2);
|
2023-11-15 22:29:35 +04:00
|
|
|
|
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
|
|
|
|
|
row.Cells[0].MergeRight = 1;
|
|
|
|
|
|
2023-11-16 17:28:16 +04:00
|
|
|
|
AddTheContent<T>(dataForPDF.Data, table, row.Index, 2);
|
2023-11-15 22:29:35 +04:00
|
|
|
|
|
|
|
|
|
mergeIndex++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//если элемент шапки группируются по строкам
|
2023-11-16 17:28:16 +04:00
|
|
|
|
if (dataForPDF.Headers[i].Item1 == true)
|
2023-11-15 22:29:35 +04:00
|
|
|
|
{
|
2023-11-16 17:28:16 +04:00
|
|
|
|
mergeRange = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 - mergeIndex;
|
|
|
|
|
mergeIndex = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 + 1;
|
2023-11-15 22:29:35 +04:00
|
|
|
|
|
|
|
|
|
//стилизация ячейки. в этом блоке кода (до цикла) создаётся объединяющая ячейка
|
|
|
|
|
row = table.AddRow();
|
2023-11-16 17:28:16 +04:00
|
|
|
|
row.Height = dataForPDF.Heights[i];
|
2023-11-15 22:29:35 +04:00
|
|
|
|
row.Format.Alignment = ParagraphAlignment.Center;
|
|
|
|
|
row.Format.Font.Bold = true;
|
2023-11-16 17:28:16 +04:00
|
|
|
|
row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2);
|
2023-11-15 22:29:35 +04:00
|
|
|
|
row.Cells[0].VerticalAlignment = VerticalAlignment.Center;
|
|
|
|
|
row.Cells[0].MergeDown = mergeRange;
|
|
|
|
|
|
|
|
|
|
//с этого места создаются дочерние ячейки
|
|
|
|
|
for (int k = 0; k<mergeRange; k++)
|
|
|
|
|
{
|
|
|
|
|
i++;
|
2023-11-16 17:28:16 +04:00
|
|
|
|
row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2);
|
|
|
|
|
AddTheContent<T>(dataForPDF.Data, table, row.Index, 2);
|
2023-11-15 22:29:35 +04:00
|
|
|
|
row.Cells[1].VerticalAlignment = VerticalAlignment.Center;
|
|
|
|
|
row = table.AddRow();
|
2023-11-16 17:28:16 +04:00
|
|
|
|
row.Height = dataForPDF.Heights[i];
|
2023-11-15 22:29:35 +04:00
|
|
|
|
row.Format.Font.Bold = true;
|
|
|
|
|
row.Format.Alignment = ParagraphAlignment.Center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i++;
|
2023-11-16 17:28:16 +04:00
|
|
|
|
row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2);
|
|
|
|
|
AddTheContent<T>(dataForPDF.Data, table, row.Index, 2);
|
2023-11-15 22:29:35 +04:00
|
|
|
|
row.Cells[1].VerticalAlignment = VerticalAlignment.Center;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
|
|
|
|
|
renderer.Document = _document;
|
|
|
|
|
renderer.RenderDocument();
|
2023-11-16 17:28:16 +04:00
|
|
|
|
renderer.PdfDocument.Save(dataForPDF.FilePath);
|
2023-11-15 22:29:35 +04:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|