TableExamples.cs 20 KB

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