StatementTable.cs
// // This code is part of Document Solutions for PDF demos. // Copyright (c) MESCIUS inc. All rights reserved. // using System; using System.IO; using System.Drawing; using System.Numerics; using System.Collections.Generic; using GrapeCity.Documents.Pdf; using GrapeCity.Documents.Drawing; using GrapeCity.Documents.Text; using GrapeCity.Documents.Layout; using GCTEXT = GrapeCity.Documents.Text; using GCDRAW = GrapeCity.Documents.Drawing; namespace DsPdfWeb.Demos { // This example shows how to use the GrapeCity.Documents.Drawing.TableRenderer // class to render a document with a layout typically used in account statements or invoices. public class StatementTable { public int CreatePDF(Stream stream) { var doc = new GcPdfDocument(); var p = doc.NewPage(); p.Size = new SizeF(p.Size.Height, p.Size.Width); var g = p.Graphics; DrawTable(g, g.CanvasSize.Width, g.CanvasSize.Height); // Save the PDF: doc.Save(stream); return doc.Pages.Count; } class InfoLine { public InfoLine(int indent, string text, int sum2021, int sum2020, int sum2019, bool boldText = false, bool captionOnly = false, bool drawSign = false, bool thinLine = false, bool boldLine = false) { Indent = indent; Text = text; Sum2021 = sum2021; Sum2020 = sum2020; Sum2019 = sum2019; BoldText = boldText; CaptionOnly = captionOnly; DrawSign = drawSign; ThinLine = thinLine; BoldLine = boldLine; } public int Indent { get; } public string Text { get; } public int Sum2021 { get; } public int Sum2020 { get; } public int Sum2019 { get; } public bool BoldText { get; } public bool CaptionOnly { get; } public bool DrawSign { get; } public bool ThinLine { get; } public bool BoldLine { get; } } static void DrawTable(GcGraphics g, float pageWidth, float pageHeight) { var items = new InfoLine[] { new InfoLine(0, "Net sales:", 0, 0, 0, captionOnly: true), new InfoLine(1, "Products", 297392, 220747, 213883, drawSign: true), new InfoLine(1, "Services", 68425, 53768, 46291, thinLine: true), new InfoLine(2, "Total net sales", 365817, 274515, 260174, boldText: true), new InfoLine(0, "Cost of sales:", 0, 0, 0, captionOnly: true), new InfoLine(1, "Products", 192266, 151286, 144996), new InfoLine(1, "Services", 20715, 18273, 16786, thinLine: true), new InfoLine(2, "Total cost of sales", 212981, 169559, 161782, boldText: true, thinLine: true), new InfoLine(3, "Gross margin", 152836, 104956, 98392, boldText: true, thinLine: true), new InfoLine(0, "Operating expenses:", 0, 0, 0, captionOnly: true), new InfoLine(1, "Research and development", 21914, 18752, 16217), new InfoLine(1, "Selling, general and administrative", 21973, 19916, 18245, thinLine: true), new InfoLine(2, "Total operating expenses", 43887, 38668, 34462, boldText: true, thinLine: true), new InfoLine(0, " ", 0, 0, 0, captionOnly: true), new InfoLine(0, "Operating income", 108949, 66288, 63930), new InfoLine(0, "Other income/(expense), net", 258, 803, 1807, thinLine: true), new InfoLine(0, "Income before provision for income taxes", 109207, 67091, 65737, boldText: true), new InfoLine(0, "Provision for income taxes", 14527, 9680, 10481, thinLine: true), new InfoLine(0, "Net income", 94680, 57411, 55256, boldText: true, drawSign: true, boldLine: true), }; var host = new LayoutHost(); var view = host.CreateView(pageWidth, pageHeight); var rt = view.CreateRect(); // rt.AnchorTopLeft(null, 30, 50); rt.AnchorTopLeft(null, 36, 36); var ta = new TableRenderer(g, rt, FixedTableSides.TopLeft, rowCount: items.Length + 3, columnCount: 7, gridLineColor: Color.Transparent, gridLineWidth: 0); var columns = ta.ColumnRects; columns[0].SetWidth(320); columns[1].SetWidth(25); columns[2].SetWidth(100); columns[3].SetWidth(25); columns[4].SetWidth(100); columns[5].SetWidth(25); columns[6].SetWidth(100); var fmt = new TextFormat { Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeMono.ttf")), ForeColor = Color.FromArgb(38, 38, 38), FontSize = 11, FontSizeInGraphicUnits = true, }; var fmtCaptionBold = new TextFormat(fmt) { FontBold = true, FontSize = 12 }; var fmtCaptionLight = new TextFormat(fmt) { ForeColor = Color.FromArgb(142, 142, 142), FontSize = 12 }; var fmtBold = new TextFormat(fmt) { FontBold = true }; var csHeader1 = new CellStyle { TextAlignment = TextAlignment.Center, PaddingBottom = 25, CreateTextLayout = (g, cs, data) => { var tl = g.CreateTextLayout(); tl.AppendLine("ACME Inc.\n\nCONSOLIDATED STATEMENTS OF OPERATIONS", fmtCaptionBold); tl.Append("(in millions, except number of shares which are reflected in thousands and per share amounts)", fmtCaptionLight); return tl; } }; ta.AddCell(csHeader1, 0, 0, 1, 7, null); var csThinLine = new CellStyle { Background = true, Borders = FrameBorders.BottomBorder, LinePaddingBottom = -1, LineWidth = 1 }; var csBoldLine = new CellStyle(csThinLine) { LinePaddingBottom = -3, LineWidth = 3 }; var csHeader2 = new CellStyle(csThinLine) { PaddingBottom = 5, TextAlignment = TextAlignment.Center, TextFormat = fmtBold }; ta.AddCell(csHeader2, 1, 1, 1, 6, "Years ended"); ta.SetHorizontalGridLineWidth(2, 1); var csHeader3 = new CellStyle { PaddingTopBottom = 5, TextAlignment = TextAlignment.Center, TextFormat = fmtBold }; ta.AddCell(csHeader3, 2, 1, 1, 2, "September 25,\n2021"); ta.AddCell(csHeader3, 2, 3, 1, 2, "September 26,\n2020"); ta.AddCell(csHeader3, 2, 5, 1, 2, "September 28,\n2019"); ta.AddCell(csThinLine, 2, 1, 1, 6); ta.SetHorizontalGridLineWidth(3, 1); var csText = new CellStyle { TextFormat = fmt, TextAlignment = TextAlignment.Leading, PaddingTopBottom = 4 }; var csBoldText = new CellStyle(csText) { TextFormat = fmtBold }; var csNum = new CellStyle { TextFormat = fmt, TextAlignment = TextAlignment.Trailing, PaddingTopBottom = 4, PaddingRight = 10 }; var csBoldNum = new CellStyle(csNum) { TextFormat = fmtBold }; var csBand = new CellStyle { FillColor = Color.FromArgb(245, 245, 245), Background = true }; for (int i = 0; i < items.Length; i++) { var item = items[i]; int rowIndex = i + 3; if ((i & 1) != 0) { ta.AddCell(csBand, rowIndex, 0, 1, 7); } var tc = ta.AddCell(item.BoldText ? csBoldText : csText, rowIndex, 0, item.Text); tc.TextLayout.FirstLineIndent = item.Indent * 8 + 10; var csCurrNum = item.BoldText ? csBoldNum : csNum; if (item.DrawSign) { ta.AddCell(csCurrNum, rowIndex, 1, "$"); ta.AddCell(csCurrNum, rowIndex, 3, "$"); ta.AddCell(csCurrNum, rowIndex, 5, "$"); } if (!item.CaptionOnly) { ta.AddCell(csCurrNum, rowIndex, 2, item.Sum2021.ToString("n0")); ta.AddCell(csCurrNum, rowIndex, 4, item.Sum2020.ToString("n0")); ta.AddCell(csCurrNum, rowIndex, 6, item.Sum2019.ToString("n0")); } if (item.ThinLine) { ta.AddCell(csThinLine, rowIndex, 1, 1, 6); ta.SetHorizontalGridLineWidth(rowIndex + 1, 1); } else if (item.BoldLine) { ta.AddCell(csBoldLine, rowIndex, 1, 1, 6); ta.SetHorizontalGridLineWidth(rowIndex + 1, 3); } } ta.Render(); } } }