|
|
@@ -0,0 +1,233 @@
|
|
|
+using QuestPDF.ConformanceTests.TestEngine;
|
|
|
+using QuestPDF.Drawing;
|
|
|
+using QuestPDF.Fluent;
|
|
|
+using QuestPDF.Helpers;
|
|
|
+using QuestPDF.Infrastructure;
|
|
|
+
|
|
|
+namespace QuestPDF.ConformanceTests.Table;
|
|
|
+
|
|
|
+internal class TableWithHeaderCellsSpanningMultipleRowsTests : ConformanceTestBase
|
|
|
+{
|
|
|
+ protected override Document GetDocumentUnderTest()
|
|
|
+ {
|
|
|
+ return Document
|
|
|
+ .Create(document =>
|
|
|
+ {
|
|
|
+ document.Page(page =>
|
|
|
+ {
|
|
|
+ page.Margin(60);
|
|
|
+
|
|
|
+ page.Content()
|
|
|
+ .Shrink()
|
|
|
+ .Border(1)
|
|
|
+ .BorderColor(Colors.Grey.Darken1)
|
|
|
+ .Table(table =>
|
|
|
+ {
|
|
|
+ table.ApplySemanticTags();
|
|
|
+
|
|
|
+ table.ColumnsDefinition(columns =>
|
|
|
+ {
|
|
|
+ columns.RelativeColumn();
|
|
|
+ columns.RelativeColumn();
|
|
|
+ columns.RelativeColumn();
|
|
|
+ columns.RelativeColumn();
|
|
|
+ });
|
|
|
+
|
|
|
+ table.Header(header =>
|
|
|
+ {
|
|
|
+ header.Cell().Element(HeaderCellStyle).Text("Year");
|
|
|
+ header.Cell().Element(HeaderCellStyle).Text("Quarter");
|
|
|
+ header.Cell().Element(HeaderCellStyle).Text("Outcome");
|
|
|
+ header.Cell().Element(HeaderCellStyle).Text("Income");
|
|
|
+ });
|
|
|
+
|
|
|
+ table.Cell().RowSpan(4).AsSemanticHorizontalHeader().Element(HeaderCellStyle).Text("2024");
|
|
|
+
|
|
|
+ table.Cell().AsSemanticHorizontalHeader().Element(HeaderCellStyle).Text("Q1");
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+
|
|
|
+ table.Cell().AsSemanticHorizontalHeader().Element(HeaderCellStyle).Text("Q2");
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+
|
|
|
+ table.Cell().AsSemanticHorizontalHeader().Element(HeaderCellStyle).Text("Q3");
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+
|
|
|
+ table.Cell().AsSemanticHorizontalHeader().Element(HeaderCellStyle).Text("Q4");
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+
|
|
|
+ table.Cell().RowSpan(2).AsSemanticHorizontalHeader().Element(HeaderCellStyle).Text("2025");
|
|
|
+
|
|
|
+ table.Cell().AsSemanticHorizontalHeader().Element(HeaderCellStyle).Text("Q1");
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+
|
|
|
+ table.Cell().AsSemanticHorizontalHeader().Element(HeaderCellStyle).Text("Q2");
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+ table.Cell().Element(CellStyle).Text(Placeholders.Price());
|
|
|
+
|
|
|
+ IContainer HeaderCellStyle(IContainer container) =>
|
|
|
+ container
|
|
|
+ .Border(1)
|
|
|
+ .BorderColor(Colors.Grey.Lighten2)
|
|
|
+ .Background(Colors.Grey.Lighten3)
|
|
|
+ .Padding(8)
|
|
|
+ .AlignMiddle()
|
|
|
+ .DefaultTextStyle(x => x.Bold());
|
|
|
+
|
|
|
+ IContainer CellStyle(IContainer container) =>
|
|
|
+ container
|
|
|
+ .Border(1)
|
|
|
+ .BorderColor(Colors.Grey.Lighten2)
|
|
|
+ .Padding(8);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override SemanticTreeNode? GetExpectedSemanticTree()
|
|
|
+ {
|
|
|
+ return ExpectedSemanticTree.DocumentRoot(root =>
|
|
|
+ {
|
|
|
+ root.Child("Table", table =>
|
|
|
+ {
|
|
|
+ table.Child("THead", thead =>
|
|
|
+ {
|
|
|
+ thead.Child("TR", row =>
|
|
|
+ {
|
|
|
+ row.Child("TH", th => th.Id(5).Child("P"));
|
|
|
+ row.Child("TH", th => th.Id(6).Child("P"));
|
|
|
+ row.Child("TH", th => th.Id(7).Child("P"));
|
|
|
+ row.Child("TH", th => th.Id(8).Child("P"));
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ table.Child("TBody", tbody =>
|
|
|
+ {
|
|
|
+ tbody.Child("TR", row =>
|
|
|
+ {
|
|
|
+ row.Child("TH", th => th
|
|
|
+ .Id(15)
|
|
|
+ .Attribute("Table", "RowSpan", 4)
|
|
|
+ .Attribute("Table", "Headers", new[] { 5 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TH", th => th
|
|
|
+ .Id(16)
|
|
|
+ .Attribute("Table", "Headers", new[] { 6, 15 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(17)
|
|
|
+ .Attribute("Table", "Headers", new[] { 7, 15, 16 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(18)
|
|
|
+ .Attribute("Table", "Headers", new[] { 8, 15, 16 })
|
|
|
+ .Child("P"));
|
|
|
+ });
|
|
|
+
|
|
|
+ tbody.Child("TR", row =>
|
|
|
+ {
|
|
|
+ row.Child("TH", th => th
|
|
|
+ .Id(20)
|
|
|
+ .Attribute("Table", "Headers", new[] { 6, 15 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(21)
|
|
|
+ .Attribute("Table", "Headers", new[] { 7, 15, 20 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(22)
|
|
|
+ .Attribute("Table", "Headers", new[] { 8, 15, 20 })
|
|
|
+ .Child("P"));
|
|
|
+ });
|
|
|
+
|
|
|
+ tbody.Child("TR", row =>
|
|
|
+ {
|
|
|
+ row.Child("TH", th => th
|
|
|
+ .Id(24)
|
|
|
+ .Attribute("Table", "Headers", new[] { 6, 15 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(25)
|
|
|
+ .Attribute("Table", "Headers", new[] { 7, 15, 24 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(26)
|
|
|
+ .Attribute("Table", "Headers", new[] { 8, 15, 24 })
|
|
|
+ .Child("P"));
|
|
|
+ });
|
|
|
+
|
|
|
+ tbody.Child("TR", row =>
|
|
|
+ {
|
|
|
+ row.Child("TH", th => th
|
|
|
+ .Id(28)
|
|
|
+ .Attribute("Table", "Headers", new[] { 6, 15 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(29)
|
|
|
+ .Attribute("Table", "Headers", new[] { 7, 15, 28 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(30)
|
|
|
+ .Attribute("Table", "Headers", new[] { 8, 15, 28 })
|
|
|
+ .Child("P"));
|
|
|
+ });
|
|
|
+
|
|
|
+ tbody.Child("TR", row =>
|
|
|
+ {
|
|
|
+ row.Child("TH", th => th
|
|
|
+ .Id(32)
|
|
|
+ .Attribute("Table", "RowSpan", 2)
|
|
|
+ .Attribute("Table", "Headers", new[] { 5 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TH", th => th
|
|
|
+ .Id(33)
|
|
|
+ .Attribute("Table", "Headers", new[] { 6, 32 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(34)
|
|
|
+ .Attribute("Table", "Headers", new[] { 7, 32, 33 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(35)
|
|
|
+ .Attribute("Table", "Headers", new[] { 8, 32, 33 })
|
|
|
+ .Child("P"));
|
|
|
+ });
|
|
|
+
|
|
|
+ tbody.Child("TR", row =>
|
|
|
+ {
|
|
|
+ row.Child("TH", th => th
|
|
|
+ .Id(37)
|
|
|
+ .Attribute("Table", "Headers", new[] { 6, 32 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(38)
|
|
|
+ .Attribute("Table", "Headers", new[] { 7, 32, 37 })
|
|
|
+ .Child("P"));
|
|
|
+
|
|
|
+ row.Child("TD", td => td
|
|
|
+ .Id(39)
|
|
|
+ .Attribute("Table", "Headers", new[] { 8, 32, 37 })
|
|
|
+ .Child("P"));
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|