TableExamples.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Diagnostics;
  5. using System.Drawing;
  6. using System.Linq;
  7. using NUnit.Framework;
  8. using QuestPDF.Drawing;
  9. using QuestPDF.Examples.Engine;
  10. using QuestPDF.Fluent;
  11. using QuestPDF.Helpers;
  12. using QuestPDF.Infrastructure;
  13. using IContainer = QuestPDF.Infrastructure.IContainer;
  14. namespace QuestPDF.Examples
  15. {
  16. public class TableExamples
  17. {
  18. [Test]
  19. public void BasicPlacement()
  20. {
  21. RenderingTest
  22. .Create()
  23. .ProduceImages()
  24. .PageSize(220, 220)
  25. .ShowResults()
  26. .Render(container =>
  27. {
  28. container
  29. .Padding(10)
  30. .MinimalBox()
  31. .Border(1)
  32. .Table(table =>
  33. {
  34. table.ColumnsDefinition(columns =>
  35. {
  36. columns.RelativeColumn();
  37. columns.RelativeColumn();
  38. columns.RelativeColumn();
  39. columns.RelativeColumn();
  40. });
  41. // by using custom 'Element' method, we can reuse visual configuration
  42. table.Cell().Row(1).Column(4).Element(Block).Text("A");
  43. table.Cell().Row(2).Column(2).Element(Block).Text("B");
  44. table.Cell().Row(3).Column(3).Element(Block).Text("C");
  45. table.Cell().Row(4).Column(1).Element(Block).Text("D");
  46. });
  47. });
  48. }
  49. [Test]
  50. public void DefaultCellStyle()
  51. {
  52. RenderingTest
  53. .Create()
  54. .ProduceImages()
  55. .PageSize(220, 120)
  56. .ShowResults()
  57. .Render(container =>
  58. {
  59. container
  60. .Padding(10)
  61. .MinimalBox()
  62. .Border(1)
  63. .DefaultTextStyle(TextStyle.Default.Size(16))
  64. .Table(table =>
  65. {
  66. table.ColumnsDefinition(columns =>
  67. {
  68. columns.RelativeColumn();
  69. columns.RelativeColumn();
  70. columns.RelativeColumn();
  71. columns.RelativeColumn();
  72. });
  73. table.Cell().Row(1).Column(1).Element(Block).Text("A");
  74. table.Cell().Row(2).Column(2).Element(Block).Text("B");
  75. table.Cell().Row(1).Column(3).Element(Block).Text("C");
  76. table.Cell().Row(2).Column(4).Element(Block).Text("D");
  77. });
  78. });
  79. }
  80. [Test]
  81. public void ColumnsDefinition()
  82. {
  83. RenderingTest
  84. .Create()
  85. .ProduceImages()
  86. .PageSize(320, 80)
  87. .ShowResults()
  88. .Render(container =>
  89. {
  90. container
  91. .Padding(10)
  92. .Table(table =>
  93. {
  94. table.ColumnsDefinition(columns =>
  95. {
  96. columns.ConstantColumn(50);
  97. columns.ConstantColumn(100);
  98. columns.RelativeColumn(2);
  99. columns.RelativeColumn(3);
  100. });
  101. table.Cell().ColumnSpan(4).LabelCell("Total width: 300px");
  102. table.Cell().ValueCell("50px");
  103. table.Cell().ValueCell("100px");
  104. table.Cell().ValueCell("100px");
  105. table.Cell().ValueCell("150px");
  106. });
  107. });
  108. }
  109. [Test]
  110. public void PartialAutoPlacement()
  111. {
  112. RenderingTest
  113. .Create()
  114. .ProduceImages()
  115. .PageSize(220, 220)
  116. .ShowResults()
  117. .Render(container =>
  118. {
  119. container
  120. .Padding(10)
  121. .MinimalBox()
  122. .Border(1)
  123. .Table(table =>
  124. {
  125. table.ColumnsDefinition(columns =>
  126. {
  127. columns.RelativeColumn();
  128. columns.RelativeColumn();
  129. columns.RelativeColumn();
  130. columns.RelativeColumn();
  131. });
  132. table.Cell().Element(Block).Text("A");
  133. table.Cell().Row(2).Column(2).Element(Block).Text("B");
  134. table.Cell().Element(Block).Text("C");
  135. table.Cell().Row(3).Column(3).Element(Block).Text("D");
  136. table.Cell().ColumnSpan(2).Element(Block).Text("E");
  137. });
  138. });
  139. }
  140. [Test]
  141. public void ExtendLastCellsToTableBottom()
  142. {
  143. RenderingTest
  144. .Create()
  145. .ProduceImages()
  146. .PageSize(220, 170)
  147. .ShowResults()
  148. .Render(container =>
  149. {
  150. container
  151. .Padding(10)
  152. .MinimalBox()
  153. .Border(1)
  154. .Table(table =>
  155. {
  156. table.ColumnsDefinition(columns =>
  157. {
  158. columns.RelativeColumn();
  159. columns.RelativeColumn();
  160. columns.RelativeColumn();
  161. columns.RelativeColumn();
  162. });
  163. table.ExtendLastCellsToTableBottom();
  164. table.Cell().Row(1).Column(1).Element(Block).Text("A");
  165. table.Cell().Row(3).Column(1).Element(Block).Text("B");
  166. table.Cell().Row(2).Column(2).Element(Block).Text("C");
  167. table.Cell().Row(3).Column(3).Element(Block).Text("D");
  168. table.Cell().Row(2).RowSpan(2).Column(4).Element(Block).Text("E");
  169. });
  170. });
  171. }
  172. [Test]
  173. public void Overlapping()
  174. {
  175. RenderingTest
  176. .Create()
  177. .ProduceImages()
  178. .PageSize(170, 170)
  179. .ShowResults()
  180. .Render(container =>
  181. {
  182. container
  183. .Padding(10)
  184. .MinimalBox()
  185. .Border(1)
  186. .Table(table =>
  187. {
  188. table.ColumnsDefinition(columns =>
  189. {
  190. columns.RelativeColumn();
  191. columns.RelativeColumn();
  192. columns.RelativeColumn();
  193. });
  194. table.Cell().Row(1).RowSpan(3).Column(1).ColumnSpan(3).Background(Colors.Grey.Lighten3).MinHeight(150);
  195. table.Cell().Row(1).RowSpan(2).Column(1).ColumnSpan(2).Background(Colors.Grey.Lighten1).MinHeight(100);
  196. table.Cell().Row(3).Column(3).Background(Colors.Grey.Darken1).MinHeight(50);
  197. });
  198. });
  199. }
  200. [Test]
  201. public void Spans()
  202. {
  203. RenderingTest
  204. .Create()
  205. .ProduceImages()
  206. .PageSize(220, 220)
  207. .ShowResults()
  208. .Render(container =>
  209. {
  210. container
  211. .Padding(10)
  212. .Table(table =>
  213. {
  214. table.ColumnsDefinition(columns =>
  215. {
  216. columns.RelativeColumn();
  217. columns.RelativeColumn();
  218. columns.RelativeColumn();
  219. columns.RelativeColumn();
  220. });
  221. table.Cell().RowSpan(2).ColumnSpan(2).Element(Block).Text("1");
  222. table.Cell().ColumnSpan(2).Element(Block).Text("2");
  223. table.Cell().Element(Block).Text("3");
  224. table.Cell().Element(Block).Text("4");
  225. table.Cell().RowSpan(2).Element(Block).Text("5");
  226. table.Cell().ColumnSpan(2).Element(Block).Text("6");
  227. table.Cell().RowSpan(2).Element(Block).Text("7");
  228. table.Cell().Element(Block).Text("8");
  229. table.Cell().Element(Block).Text("9");
  230. });
  231. });
  232. }
  233. [Test]
  234. public void Stability()
  235. {
  236. RenderingTest
  237. .Create()
  238. .ProduceImages()
  239. .PageSize(300, 300)
  240. .ShowResults()
  241. .Render(container =>
  242. {
  243. container
  244. .Padding(10)
  245. .Table(table =>
  246. {
  247. table.ColumnsDefinition(columns =>
  248. {
  249. columns.RelativeColumn();
  250. columns.RelativeColumn();
  251. columns.RelativeColumn();
  252. columns.RelativeColumn();
  253. });
  254. table.Cell().RowSpan(4).Element(Block).Text("1");
  255. table.Cell().RowSpan(2).Element(Block).Text("2");
  256. table.Cell().RowSpan(1).Element(Block).Text("3");
  257. table.Cell().RowSpan(1).Element(Block).Text("4");
  258. table.Cell().RowSpan(2).Element(Block).Text("5");
  259. table.Cell().RowSpan(1).Element(Block).Text("6");
  260. table.Cell().RowSpan(1).Element(Block).Text("7");
  261. });
  262. });
  263. }
  264. [Test]
  265. public void TableHeader()
  266. {
  267. RenderingTest
  268. .Create()
  269. .ProduceImages()
  270. .PageSize(500, 200)
  271. .ShowResults()
  272. .EnableDebugging()
  273. .Render(container =>
  274. {
  275. var pageSizes = new List<(string name, double width, double height)>()
  276. {
  277. ("Letter (ANSI A)", 8.5f, 11),
  278. ("Legal", 8.5f, 14),
  279. ("Ledger (ANSI B)", 11, 17),
  280. ("Tabloid (ANSI B)", 17, 11),
  281. ("ANSI C", 22, 17),
  282. ("ANSI D", 34, 22),
  283. ("ANSI E", 44, 34)
  284. };
  285. const int inchesToPoints = 72;
  286. container
  287. .Padding(10)
  288. .MinimalBox()
  289. .Border(1)
  290. .Table(table =>
  291. {
  292. IContainer DefaultCellStyle(IContainer container, string backgroundColor)
  293. {
  294. return container
  295. .Border(1)
  296. .BorderColor(Colors.Grey.Lighten1)
  297. .Background(backgroundColor)
  298. .PaddingVertical(5)
  299. .PaddingHorizontal(10)
  300. .AlignCenter()
  301. .AlignMiddle();
  302. }
  303. table.ColumnsDefinition(columns =>
  304. {
  305. columns.RelativeColumn();
  306. columns.ConstantColumn(75);
  307. columns.ConstantColumn(75);
  308. columns.ConstantColumn(75);
  309. columns.ConstantColumn(75);
  310. });
  311. table.Header(header =>
  312. {
  313. header.Cell().RowSpan(2).Element(CellStyle).ExtendHorizontal().AlignLeft().Text("Document type");
  314. header.Cell().ColumnSpan(2).Element(CellStyle).Text("Inches");
  315. header.Cell().ColumnSpan(2).Element(CellStyle).Text("Points");
  316. header.Cell().Element(CellStyle).Text("Width");
  317. header.Cell().Element(CellStyle).Text("Height");
  318. header.Cell().Element(CellStyle).Text("Width");
  319. header.Cell().Element(CellStyle).Text("Height");
  320. // you can extend already existing styles by creating additional methods
  321. IContainer CellStyle(IContainer container) => DefaultCellStyle(container, Colors.Grey.Lighten3);
  322. });
  323. foreach (var page in pageSizes)
  324. {
  325. table.Cell().Element(CellStyle).ExtendHorizontal().AlignLeft().Text(page.name);
  326. // inches
  327. table.Cell().Element(CellStyle).Text(page.width);
  328. table.Cell().Element(CellStyle).Text(page.height);
  329. // points
  330. table.Cell().Element(CellStyle).Text(page.width * inchesToPoints);
  331. table.Cell().Element(CellStyle).Text(page.height * inchesToPoints);
  332. IContainer CellStyle(IContainer container) => DefaultCellStyle(container, Colors.White);
  333. }
  334. });
  335. });
  336. }
  337. [Test]
  338. public void PerformanceText_TemperatureReport()
  339. {
  340. RenderingTest
  341. .Create()
  342. .ProducePdf()
  343. .PageSize(PageSizes.A4)
  344. .MaxPages(10_000)
  345. .EnableCaching()
  346. .EnableDebugging(false)
  347. .ShowResults()
  348. .Render(container => GeneratePerformanceStructure(container, 1000));
  349. }
  350. public static void GeneratePerformanceStructure(IContainer container, int repeats)
  351. {
  352. container
  353. .Padding(25)
  354. //.Background(Colors.Blue.Lighten2)
  355. .MinimalBox()
  356. .Border(1)
  357. //.Background(Colors.Red.Lighten2)
  358. .Table(table =>
  359. {
  360. table.ColumnsDefinition(columns =>
  361. {
  362. columns.ConstantColumn(100);
  363. columns.RelativeColumn();
  364. columns.ConstantColumn(100);
  365. columns.RelativeColumn();
  366. });
  367. table.ExtendLastCellsToTableBottom();
  368. foreach (var i in Enumerable.Range(0, repeats))
  369. {
  370. table.Cell().RowSpan(3).LabelCell("Project");
  371. table.Cell().RowSpan(3).ShowEntire().ValueCell(Placeholders.Sentence());
  372. table.Cell().LabelCell("Report number");
  373. table.Cell().ValueCell(i.ToString());
  374. table.Cell().LabelCell("Date");
  375. table.Cell().ValueCell(Placeholders.ShortDate());
  376. table.Cell().LabelCell("Inspector");
  377. table.Cell().ValueCell("Marcin Ziąbek");
  378. table.Cell().ColumnSpan(2).LabelCell("Morning weather");
  379. table.Cell().ColumnSpan(2).LabelCell("Evening weather");
  380. table.Cell().ValueCell("Time");
  381. table.Cell().ValueCell("7:13");
  382. table.Cell().ValueCell("Time");
  383. table.Cell().ValueCell("18:25");
  384. table.Cell().ValueCell("Description");
  385. table.Cell().ValueCell("Sunny");
  386. table.Cell().ValueCell("Description");
  387. table.Cell().ValueCell("Windy");
  388. table.Cell().ValueCell("Wind");
  389. table.Cell().ValueCell("Mild");
  390. table.Cell().ValueCell("Wind");
  391. table.Cell().ValueCell("Strong");
  392. table.Cell().ValueCell("Temperature");
  393. table.Cell().ValueCell("17°C");
  394. table.Cell().ValueCell("Temperature");
  395. table.Cell().ValueCell("32°C");
  396. table.Cell().LabelCell("Remarks");
  397. table.Cell().ColumnSpan(3).ValueCell(Placeholders.Paragraph());
  398. }
  399. });
  400. }
  401. // this method uses a higher order function to define a custom and dynamic style
  402. static IContainer Block(IContainer container)
  403. {
  404. return container
  405. .Border(1)
  406. .Background(Colors.Grey.Lighten3)
  407. .MinWidth(50)
  408. .MinHeight(50)
  409. .AlignCenter()
  410. .AlignMiddle();
  411. }
  412. }
  413. }