TableExamples.cs 20 KB

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