StatementTable.cs
// 完毕:
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);
// 保存 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", "consola.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();
}
}
}