StatementTable.cs
  1. //
  2. // This code is part of Document Solutions for PDF demos.
  3. // Copyright (c) MESCIUS inc. All rights reserved.
  4. //
  5. using System;
  6. using System.IO;
  7. using System.Drawing;
  8. using System.Numerics;
  9. using System.Collections.Generic;
  10. using GrapeCity.Documents.Pdf;
  11. using GrapeCity.Documents.Drawing;
  12. using GrapeCity.Documents.Text;
  13. using GrapeCity.Documents.Layout;
  14. using GCTEXT = GrapeCity.Documents.Text;
  15. using GCDRAW = GrapeCity.Documents.Drawing;
  16.  
  17. namespace DsPdfWeb.Demos
  18. {
  19. // This example shows how to use the GrapeCity.Documents.Drawing.TableRenderer
  20. // class to render a document with a layout typically used in account statements or invoices.
  21. public class StatementTable
  22. {
  23. public int CreatePDF(Stream stream)
  24. {
  25. var doc = new GcPdfDocument();
  26. var p = doc.NewPage();
  27. p.Size = new SizeF(p.Size.Height, p.Size.Width);
  28. var g = p.Graphics;
  29.  
  30. DrawTable(g, g.CanvasSize.Width, g.CanvasSize.Height);
  31.  
  32. // Save the PDF:
  33. doc.Save(stream);
  34. return doc.Pages.Count;
  35. }
  36.  
  37. class InfoLine
  38. {
  39. public InfoLine(int indent, string text, int sum2021, int sum2020, int sum2019, bool boldText = false,
  40. bool captionOnly = false, bool drawSign = false, bool thinLine = false, bool boldLine = false)
  41. {
  42. Indent = indent;
  43. Text = text;
  44. Sum2021 = sum2021;
  45. Sum2020 = sum2020;
  46. Sum2019 = sum2019;
  47. BoldText = boldText;
  48. CaptionOnly = captionOnly;
  49. DrawSign = drawSign;
  50. ThinLine = thinLine;
  51. BoldLine = boldLine;
  52. }
  53. public int Indent { get; }
  54. public string Text { get; }
  55. public int Sum2021 { get; }
  56. public int Sum2020 { get; }
  57. public int Sum2019 { get; }
  58. public bool BoldText { get; }
  59. public bool CaptionOnly { get; }
  60. public bool DrawSign { get; }
  61. public bool ThinLine { get; }
  62. public bool BoldLine { get; }
  63. }
  64.  
  65. static void DrawTable(GcGraphics g, float pageWidth, float pageHeight)
  66. {
  67. var items = new InfoLine[]
  68. {
  69. new InfoLine(0, "Net sales:", 0, 0, 0, captionOnly: true),
  70. new InfoLine(1, "Products", 297392, 220747, 213883, drawSign: true),
  71. new InfoLine(1, "Services", 68425, 53768, 46291, thinLine: true),
  72. new InfoLine(2, "Total net sales", 365817, 274515, 260174, boldText: true),
  73. new InfoLine(0, "Cost of sales:", 0, 0, 0, captionOnly: true),
  74. new InfoLine(1, "Products", 192266, 151286, 144996),
  75. new InfoLine(1, "Services", 20715, 18273, 16786, thinLine: true),
  76. new InfoLine(2, "Total cost of sales", 212981, 169559, 161782, boldText: true, thinLine: true),
  77. new InfoLine(3, "Gross margin", 152836, 104956, 98392, boldText: true, thinLine: true),
  78. new InfoLine(0, "Operating expenses:", 0, 0, 0, captionOnly: true),
  79. new InfoLine(1, "Research and development", 21914, 18752, 16217),
  80. new InfoLine(1, "Selling, general and administrative", 21973, 19916, 18245, thinLine: true),
  81. new InfoLine(2, "Total operating expenses", 43887, 38668, 34462, boldText: true, thinLine: true),
  82. new InfoLine(0, " ", 0, 0, 0, captionOnly: true),
  83. new InfoLine(0, "Operating income", 108949, 66288, 63930),
  84. new InfoLine(0, "Other income/(expense), net", 258, 803, 1807, thinLine: true),
  85. new InfoLine(0, "Income before provision for income taxes", 109207, 67091, 65737, boldText: true),
  86. new InfoLine(0, "Provision for income taxes", 14527, 9680, 10481, thinLine: true),
  87. new InfoLine(0, "Net income", 94680, 57411, 55256, boldText: true, drawSign: true, boldLine: true),
  88. };
  89.  
  90. var host = new LayoutHost();
  91. var view = host.CreateView(pageWidth, pageHeight);
  92.  
  93. var rt = view.CreateRect();
  94. // rt.AnchorTopLeft(null, 30, 50);
  95. rt.AnchorTopLeft(null, 36, 36);
  96.  
  97. var ta = new TableRenderer(g,
  98. rt, FixedTableSides.TopLeft,
  99. rowCount: items.Length + 3,
  100. columnCount: 7,
  101. gridLineColor: Color.Transparent,
  102. gridLineWidth: 0);
  103.  
  104. var columns = ta.ColumnRects;
  105. columns[0].SetWidth(320);
  106. columns[1].SetWidth(25);
  107. columns[2].SetWidth(100);
  108. columns[3].SetWidth(25);
  109. columns[4].SetWidth(100);
  110. columns[5].SetWidth(25);
  111. columns[6].SetWidth(100);
  112.  
  113. var fmt = new TextFormat
  114. {
  115. Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "consola.ttf")),
  116. ForeColor = Color.FromArgb(38, 38, 38),
  117. FontSize = 11,
  118. FontSizeInGraphicUnits = true,
  119. };
  120. var fmtCaptionBold = new TextFormat(fmt)
  121. {
  122. FontBold = true,
  123. FontSize = 12
  124. };
  125. var fmtCaptionLight = new TextFormat(fmt)
  126. {
  127. ForeColor = Color.FromArgb(142, 142, 142),
  128. FontSize = 12
  129. };
  130. var fmtBold = new TextFormat(fmt)
  131. {
  132. FontBold = true
  133. };
  134.  
  135. var csHeader1 = new CellStyle
  136. {
  137. TextAlignment = TextAlignment.Center,
  138. PaddingBottom = 25,
  139. CreateTextLayout = (g, cs, data) =>
  140. {
  141. var tl = g.CreateTextLayout();
  142. tl.AppendLine("ACME Inc.\n\nCONSOLIDATED STATEMENTS OF OPERATIONS", fmtCaptionBold);
  143. tl.Append("(in millions, except number of shares which are reflected in thousands and per share amounts)", fmtCaptionLight);
  144. return tl;
  145. }
  146. };
  147. ta.AddCell(csHeader1, 0, 0, 1, 7, null);
  148.  
  149. var csThinLine = new CellStyle
  150. {
  151. Background = true,
  152. Borders = FrameBorders.BottomBorder,
  153. LinePaddingBottom = -1,
  154. LineWidth = 1
  155. };
  156. var csBoldLine = new CellStyle(csThinLine)
  157. {
  158. LinePaddingBottom = -3,
  159. LineWidth = 3
  160. };
  161.  
  162. var csHeader2 = new CellStyle(csThinLine)
  163. {
  164. PaddingBottom = 5,
  165. TextAlignment = TextAlignment.Center,
  166. TextFormat = fmtBold
  167. };
  168. ta.AddCell(csHeader2, 1, 1, 1, 6, "Years ended");
  169. ta.SetHorizontalGridLineWidth(2, 1);
  170.  
  171. var csHeader3 = new CellStyle
  172. {
  173. PaddingTopBottom = 5,
  174. TextAlignment = TextAlignment.Center,
  175. TextFormat = fmtBold
  176. };
  177. ta.AddCell(csHeader3, 2, 1, 1, 2, "September 25,\n2021");
  178. ta.AddCell(csHeader3, 2, 3, 1, 2, "September 26,\n2020");
  179. ta.AddCell(csHeader3, 2, 5, 1, 2, "September 28,\n2019");
  180. ta.AddCell(csThinLine, 2, 1, 1, 6);
  181. ta.SetHorizontalGridLineWidth(3, 1);
  182.  
  183. var csText = new CellStyle
  184. {
  185. TextFormat = fmt,
  186. TextAlignment = TextAlignment.Leading,
  187. PaddingTopBottom = 4
  188. };
  189. var csBoldText = new CellStyle(csText)
  190. {
  191. TextFormat = fmtBold
  192. };
  193. var csNum = new CellStyle
  194. {
  195. TextFormat = fmt,
  196. TextAlignment = TextAlignment.Trailing,
  197. PaddingTopBottom = 4,
  198. PaddingRight = 10
  199. };
  200. var csBoldNum = new CellStyle(csNum)
  201. {
  202. TextFormat = fmtBold
  203. };
  204. var csBand = new CellStyle
  205. {
  206. FillColor = Color.FromArgb(245, 245, 245),
  207. Background = true
  208. };
  209.  
  210. for (int i = 0; i < items.Length; i++)
  211. {
  212. var item = items[i];
  213. int rowIndex = i + 3;
  214.  
  215. if ((i & 1) != 0)
  216. {
  217. ta.AddCell(csBand, rowIndex, 0, 1, 7);
  218. }
  219.  
  220. var tc = ta.AddCell(item.BoldText ? csBoldText : csText, rowIndex, 0, item.Text);
  221. tc.TextLayout.FirstLineIndent = item.Indent * 8 + 10;
  222.  
  223. var csCurrNum = item.BoldText ? csBoldNum : csNum;
  224. if (item.DrawSign)
  225. {
  226. ta.AddCell(csCurrNum, rowIndex, 1, "$");
  227. ta.AddCell(csCurrNum, rowIndex, 3, "$");
  228. ta.AddCell(csCurrNum, rowIndex, 5, "$");
  229. }
  230. if (!item.CaptionOnly)
  231. {
  232. ta.AddCell(csCurrNum, rowIndex, 2, item.Sum2021.ToString("n0"));
  233. ta.AddCell(csCurrNum, rowIndex, 4, item.Sum2020.ToString("n0"));
  234. ta.AddCell(csCurrNum, rowIndex, 6, item.Sum2019.ToString("n0"));
  235. }
  236.  
  237. if (item.ThinLine)
  238. {
  239. ta.AddCell(csThinLine, rowIndex, 1, 1, 6);
  240. ta.SetHorizontalGridLineWidth(rowIndex + 1, 1);
  241. }
  242. else if (item.BoldLine)
  243. {
  244. ta.AddCell(csBoldLine, rowIndex, 1, 1, 6);
  245. ta.SetHorizontalGridLineWidth(rowIndex + 1, 3);
  246. }
  247. }
  248.  
  249. ta.Render();
  250. }
  251. }
  252. }
  253.