private void button2_Click(object sender, EventArgs e) { doc.Clear(); doc.Style.Font = new Font("Tahoma", 20); doc.Body.Children.Add(new RenderText("Some rows of header and footer are hidden")); RenderTable rt = CreateTable(doc, 3, 50, "Cell {0} : {1}"); rt.Style.GridLines.All = new LineDef("1mm", Color.Blue); // build table header TableVectorGroup ph = rt.RowGroups[0, 3]; ph.PageHeader = true; ph.Style.BackColor = Color.LightSlateGray; ph.Style.Font = new Font("Verdana", 25); // hide row in table header rt.Rows[0].Visible = false; // build table footer TableVectorGroup pf = rt.RowGroups[rt.Rows.Count - 3, 3]; pf.PageFooter = true; pf.Style.BackColor = Color.CornflowerBlue; pf.Style.Font = new Font("Tahoma", 25); // hide row in table footer rt.Rows[rt.Rows.Count - 1].Visible = false; doc.Body.Children.Add(rt); doc.Generate(); }
/// <summary> /// Builds a document with a RenderTable bound to a list of objects in memory. /// The list consists of objects of type Customer (see above). For each customer, /// several records are created representing different orders (OrderId) of that customer. /// In the document, an outer RenderTable contains a row group bound to that list of /// customers/orders, with grouping on customer Ids. /// For each unique customer in the outer table, a row group (2 rows) is created. /// The first row lists customer's Id and Name. /// The 2nd row contains a nested RenderTable that is also bound to the customers/orders, /// and represents the detail - OrderId's for the current customer. /// Unlike the outer table, in the nested detail table a COLUMN GROUP is bound to the customers/orders list. /// As the result, for each OrderId of the current customer, a new COLUMN is created, showing the OrderId. /// </summary> private void btnBindToListHorizontalDetail_Click(object sender, RoutedEventArgs e) { UpdateButtons(btnBindToListHorizontalDetail); // build sample list of customers, // for each customer create several order ID's for master/detail: Random rnd = new Random(DateTime.Now.Second); List <Customer> customerOrders = new List <Customer>(); for (int i = 0; i < 100; i++) { // create up to 12 dummy orders for each customer, with order Ids in the 1-200 range: int orderCount = rnd.Next(1, 12); for (int orderIdx = 0; orderIdx < orderCount; ++orderIdx) { customerOrders.Add(new Customer(i + 1, "Customer " + (i + 1).ToString(), rnd.Next(1, 200))); } } // make the document: C1PrintDocument doc = new C1PrintDocument(); doc.Style.FontName = "Verdana"; doc.Style.FontSize = 12; // document title: doc.Body.Children.Add(new RenderText("List of Customer orders, customers are listed vertically, orders horizontally")); doc.Body.Children.Add(new RenderEmpty("5mm")); // empty space after title // outer render table will loop through master records: RenderTable rt = new RenderTable(); rt.Style.GridLines.All = LineDef.Default; // group master by Id. // Each master group will contain 2 rows: // - header row with customer Id and Name; // - detail row, with customer's OrderId's IN A ROW (spread horizontally in a nested table). TableVectorGroup gMaster = rt.RowGroups[0, 2]; gMaster.DataBinding.DataSource = customerOrders; gMaster.DataBinding.Grouping.Expressions.Add("Fields!Id.Value"); // 1st row: rt.Cells[0, 0].Text = "Id: [Fields!Id.Value]"; rt.Cells[0, 1].Text = "Name: [Fields!Name.Value]"; // 2nd row: a nested table: RenderTable rt2 = new RenderTable(); rt2.Style.BackColor = Colors.BlanchedAlmond; rt2.Style.GridLines.Vert = new LineDef("1pt", Colors.DarkOliveGreen); rt2.Style.FontSize = rt.Style.FontSize - 2; rt2.CellStyle.Padding.All = "1mm"; TableVectorGroup dDetail = rt2.ColGroups[1, 1]; dDetail.DataBinding.DataSource = customerOrders; rt2.Cells[0, 0].Text = "[Fields!Name.Value]'s orders: "; rt2.Cells[0, 1].Text = "[Fields!OrderId.Value]"; // auto-size the first column (with customer's name), spread the rest: rt2.Cols[0].SizingMode = TableSizingModeEnum.Auto; rt.Cells[1, 0].RenderObject = rt2; rt.Cells[1, 0].SpanCols = 2; doc.Body.Children.Add(rt); this.c1DocumentViewer1.Document = doc.FixedDocumentSequence; }
/// <summary> /// Builds a document with a data bound table, with two levels of master-detail relations. /// </summary> private void btnBoundTable_Click(object sender, RoutedEventArgs e) { UpdateButtons(btnBoundTable); this.Cursor = Cursors.Wait; C1PrintDocument doc = new C1PrintDocument(); // Set up some styles: doc.Style.FontName = "Verdana"; doc.Style.FontSize = 10; C1.C1Preview.Style boldFontStyle = doc.Style.Children.Add(); boldFontStyle.FontName = "Verdana"; boldFontStyle.FontSize = 10; boldFontStyle.FontBold = true; C1.C1Preview.Style smallFontStyle = doc.Style.Children.Add(); smallFontStyle.FontName = "Verdana"; smallFontStyle.FontSize = 7; C1.C1Preview.Style detailCaptionStyle = doc.Style.Children.Add(); detailCaptionStyle.TextAlignHorz = AlignHorzEnum.Center; detailCaptionStyle.TextAlignVert = AlignVertEnum.Center; detailCaptionStyle.FontName = "Verdana"; detailCaptionStyle.FontSize = 8; detailCaptionStyle.FontUnderline = true; C1.C1Preview.Style detailStyle = doc.Style.Children.Add(); detailStyle.FontName = "Verdana"; detailStyle.FontSize = 11; C1.C1Preview.Style dateStyle = detailStyle.Children.Add(); dateStyle.TextAlignHorz = AlignHorzEnum.Center; C1.C1Preview.Style descriptionStyle = detailStyle.Children.Add(); descriptionStyle.TextAlignHorz = AlignHorzEnum.Left; C1.C1Preview.Style currencyStyle = detailStyle.Children.Add(); currencyStyle.TextAlignHorz = AlignHorzEnum.Right; C1.C1Preview.Style quantityStyle = detailStyle.Children.Add(); quantityStyle.TextAlignHorz = AlignHorzEnum.Right; // define data schema: // orders sorted by customer sorted by customer country: DataSource ds = CreateDemoDataSource(); DataSet dsCities = new DataSet(ds, "select o.*, c.Country, c.CompanyName, p.ProductName, od.* from orders o, customers c, products p, `order details` od " + "where o.CustomerID = c.CustomerID and o.OrderID = od.OrderID and od.ProductID = p.ProductID " + "order by c.Country, c.CompanyName, o.OrderDate"); // add data source and data set to the document - this will preserve the data binding // if the document is saved as c1d/c1dx: doc.DataSchema.DataSources.Add(ds); doc.DataSchema.DataSets.Add(dsCities); // document caption: RenderText txt = new RenderText(); txt.Text = "List of orders grouped by country and customer"; txt.Style.FontName = "Tahoma"; txt.Style.FontSize = 16; txt.Style.FontBold = true; doc.Body.Children.Add(txt); // main body of the document is a data bound table, with 3 nested data bound row groups: RenderTable rt = new RenderTable(); // the following two lines make table and table columns auto-sized: rt.Width = Unit.Auto; rt.ColumnSizingMode = TableSizingModeEnum.Auto; // spread out data a bit: rt.CellStyle.Padding.All = "0.5mm"; // turn lines on for structure clarity: rt.Style.GridLines.All = new LineDef("0.5pt", Colors.Silver); // top level master: country: rt.Cells[0, 0].Text = "Country:"; rt.Cells[0, 1].SpanCols = 2; rt.Cells[0, 1].Text = "[Fields!Country.Value]"; rt.Cells[0, 1].Style.Parents = boldFontStyle; // top level master: orders count for country: rt.Cells[0, 3].RenderObject = CreateAggregate1("Total orders:", "CountryOrderCount", smallFontStyle, boldFontStyle, false); // top level master: orders total for country: rt.Cells[0, 4].RenderObject = CreateAggregate1("Country total:", "CountryTotal", smallFontStyle, boldFontStyle, true); // country header back color: rt.Rows[0].Style.BackColor = Colors.LightGoldenrodYellow; // second level master: company: rt.Cells[1, 0].Text = "Company:"; rt.Cells[1, 1].Text = "[Fields!CompanyName.Value]"; rt.Cells[1, 1].Style.Parents = boldFontStyle; rt.Cells[1, 1].SpanCols = 2; // second level master: orders count for company: rt.Cells[1, 3].RenderObject = CreateAggregate1("Total orders:", "CompanyOrderCount", smallFontStyle, boldFontStyle, false); // second level master: orders total for company: rt.Cells[1, 4].RenderObject = CreateAggregate1("Company total:", "CompanyTotal", smallFontStyle, boldFontStyle, true); // company header back color: rt.Rows[1].Style.BackColor = Colors.Lavender; // detail: column captions: rt.Cells[2, 0].Text = "Date"; rt.Cells[2, 0].Style.Parents = detailCaptionStyle; rt.Cells[2, 1].Text = "Product"; rt.Cells[2, 1].Style.Parents = detailCaptionStyle; rt.Cells[2, 2].Text = "Unit Price"; rt.Cells[2, 2].Style.Parents = detailCaptionStyle; rt.Cells[2, 3].Text = "Quantity"; rt.Cells[2, 3].Style.Parents = detailCaptionStyle; rt.Cells[2, 4].Text = "Total"; rt.Cells[2, 4].Style.Parents = detailCaptionStyle; // detail: data: // 1) detail: order date: rt.Cells[3, 0].Text = "[FormatDateTime(Fields!OrderDate.Value, DateFormat.ShortDate)]"; rt.Cells[3, 0].Style.Parents = dateStyle; // 2) detail: product name: rt.Cells[3, 1].Text = "[Fields!ProductName.Value]"; rt.Cells[3, 1].Style.Parents = descriptionStyle; // 3) detail: unit price: rt.Cells[3, 2].Text = "[string.Format(\"{0:C}\",Fields!UnitPrice.Value)]"; rt.Cells[3, 2].Style.Parents = currencyStyle; // 4) detail: quantity: rt.Cells[3, 3].Text = "[Fields!Quantity.Value]"; rt.Cells[3, 3].Style.Parents = quantityStyle; // 5) detail: order total: rt.Cells[3, 4].Text = "[string.Format(\"{0:C}\",Fields!UnitPrice.Value * Fields!Quantity.Value)]"; rt.Cells[3, 4].Style.Parents = currencyStyle; // New in 2009 v3 release of C1Report - style expressions. // Use it to highlight orders worth $1000 or more: rt.Cells[3, 4].Style.TextColorExpr = "iif(Fields!UnitPrice.Value * Fields!Quantity.Value >= 1000, Colors.Blue, Colors.Black)"; // top-level master footer: country total (duplicated in cell (0,4)): rt.Cells[5, 0].SpanCols = 3; rt.Cells[5, 0].Text = "Total of all orders for [Fields!Country.Value]:"; rt.Cells[5, 0].Style.TextAlignHorz = AlignHorzEnum.Right; rt.Cells[5, 3].SpanCols = 2; rt.Cells[5, 3].Style.Parents = currencyStyle; rt.Cells[5, 3].Text = "[string.Format(\"{0:C}\", Aggregates!CountryTotal.Value)]"; // Rows 6-8 create a visual break in the table after each country. // The 2 extra rows (6 & 8) are needed to make sure no extra grid lines // appear if this break is immediately followed by a page break. rt.Cells[6, 0].SpanCols = 5; rt.Cells[6, 0].RenderObject = new RenderEmpty("1pt"); rt.Cells[6, 0].Style.Borders.Left = rt.Cells[6, 0].Style.Borders.Right = LineDef.Empty; rt.Cells[6, 0].Style.Borders.Bottom = LineDef.Empty; rt.RowGroups[6, 1].MinVectorsBefore = 1; // rt.Cells[7, 0].SpanCols = 5; rt.Cells[7, 0].RenderObject = new RenderEmpty("3mm"); rt.Cells[7, 0].Style.Borders.All = LineDef.Empty; // rt.Cells[8, 0].SpanCols = 5; rt.Cells[8, 0].RenderObject = new RenderEmpty("1pt"); rt.Cells[8, 0].Style.Borders.Left = rt.Cells[8, 0].Style.Borders.Right = LineDef.Empty; rt.Cells[8, 0].Style.Borders.Top = LineDef.Empty; rt.RowGroups[8, 1].MinVectorsAfter = 1; // grand total for all countries: rt.Cells[9, 0].SpanCols = 2; rt.Cells[9, 0].Text = "Grand Total:"; rt.Cells[9, 0].Style.TextAlignHorz = AlignHorzEnum.Right; rt.Cells[9, 2].SpanCols = 3; rt.Cells[9, 2].Text = "[string.Format(\"{0:C}\", Aggregates!GrandTotal.Value)]"; rt.Cells[9, 2].Style.Parents = currencyStyle; // define databinding within table: // top level master row group - country - includes all defined rows (0-9): TableVectorGroup g = rt.RowGroups[0, 9]; g.DataBinding.DataSource = dsCities; // group by country: g.DataBinding.Grouping.Expressions.Add("Fields!Country.Value"); // add outline group header for each contry: g.DataBinding.OutlineText = "[Fields!Country.Value]"; g.SplitBehavior = SplitBehaviorEnum.SplitIfNeeded; // make sure country header is followed by company and at least one detail row: rt.RowGroups[0, 1].MinVectorsAfter = 3; // add country level aggregates (attached to top level master DataBinding): // (because there are several OrderID fields in the 'select' we must qualify it) doc.DataSchema.Aggregates.Add(new Aggregate("CountryOrderCount", "Fields(\"o.OrderID\").Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Count)); doc.DataSchema.Aggregates.Add(new Aggregate("CountryTotal", "Fields!UnitPrice.Value * Fields!Quantity.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Sum)); // document level aggregate for the grand total: doc.DataSchema.Aggregates.Add(new Aggregate("GrandTotal", "Fields!UnitPrice.Value * Fields!Quantity.Value", g.DataBinding, RunningEnum.Document, AggregateFuncEnum.Sum)); // second level master row group - company - includes rows 1-4: g = rt.RowGroups[1, 4]; g.DataBinding.DataSource = dsCities; // group by company: g.DataBinding.Grouping.Expressions.Add("Fields!CompanyName.Value"); // add outline group header for each company: g.DataBinding.OutlineText = "[Fields!CompanyName.Value]"; g.SplitBehavior = SplitBehaviorEnum.SplitIfNeeded; // ensure company header is followed by at least one detail row: rt.RowGroups[1, 2].MinVectorsAfter = 1; rt.RowGroups[1, 2].SplitBehavior = SplitBehaviorEnum.SplitIfLarge; // add company level aggregates (attached to second level master DataBinding): doc.DataSchema.Aggregates.Add(new Aggregate("CompanyTotal", "Fields!UnitPrice.Value * Fields!Quantity.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Sum)); // see note about OrderID above; but really, because we are just counting, any field would do here - e.g. CustomerID doc.DataSchema.Aggregates.Add(new Aggregate("CompanyOrderCount", "Fields(\"o.OrderID\").Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Count)); // finally, detail level data binding (just one row): g = rt.RowGroups[3, 1]; g.DataBinding.DataSource = dsCities; // add outline entry for each product name: g.DataBinding.OutlineText = "[Fields!ProductName.Value]"; // add table to the document: doc.Body.Children.Add(rt); // set up a progress window: ProgressWindow pw = new ProgressWindow(); pw.Owner = this; doc.Body.Children[0].UserData = pw; pw.Show(); doc.LongOperation += new LongOperationEventHandler(doc_LongOperation); // preview the document (this will cause the document to generate): c1DocumentViewer1.Document = doc.FixedDocumentSequence; // we're done; reset cursor: this.Cursor = null; }
private void button4_Click(object sender, EventArgs e) { doc.Clear(); // initialize styles doc.Style.Font = new Font("Verdana", 12); Style boldFontStyle = doc.Style.Children.Add(); boldFontStyle.Font = new Font("Verdana", 12, FontStyle.Bold); Style smallFontStyle = doc.Style.Children.Add(); smallFontStyle.Font = new Font("Verdana", 7); Style detailCaptionStyle = doc.Style.Children.Add(); detailCaptionStyle.TextAlignHorz = AlignHorzEnum.Center; detailCaptionStyle.TextAlignVert = AlignVertEnum.Center; detailCaptionStyle.Font = new Font("Verdana", 12, FontStyle.Underline); Style detailStyle = doc.Style.Children.Add(); detailStyle.Font = new Font("Verdana", 11); Style dateStyle = detailStyle.Children.Add(); dateStyle.TextAlignHorz = AlignHorzEnum.Center; Style timeStyle = detailStyle.Children.Add(); timeStyle.TextAlignHorz = AlignHorzEnum.Center; Style paymentAmountStyle = detailStyle.Children.Add(); paymentAmountStyle.TextAlignHorz = AlignHorzEnum.Right; Style quantityStyle = detailStyle.Children.Add(); quantityStyle.TextAlignHorz = AlignHorzEnum.Right; Style descriptionStyle = detailStyle.Children.Add(); descriptionStyle.TextAlignHorz = AlignHorzEnum.Left; // define data schema DataSource ds = CreateDemoDataSource(); DataSet dsCities = new DataSet(ds, "SELECT Customer_demo.Company, [Order].* FROM (Customer_demo INNER JOIN[Order] ON Customer_demo.ID = [Order].CustomerID) ORDER BY Customer_demo.Company, [Order].PaymentType"); doc.DataSchema.DataSources.Add(ds); doc.DataSchema.DataSets.Add(dsCities); RenderText txt = new RenderText(); txt.Text = "List of orders grouped by customers and payment type"; txt.Style.Font = new Font("Tahoma", 16, FontStyle.Bold); doc.Body.Children.Add(txt); RenderTable rt = new RenderTable(); rt.Style.GridLines.All = LineDef.Default; // info about Company rt.Cells[0, 0].Text = "Company:"; rt.Cells[0, 1].SpanCols = 3; rt.Cells[0, 1].Text = "[Fields!Company.Value]"; rt.Cells[0, 1].Style.Parents = boldFontStyle; rt.Cells[0, 1].Style.BackColor = Color.LightCyan; rt.Cells[0, 4].RenderObject = CreateAggregate1("Sum:", "CompanySum", smallFontStyle, boldFontStyle);; rt.Cells[0, 4].Style.BackColor = Color.LightGray; // info about PaymentType rt.Cells[1, 0].Text = "Payment type:"; rt.Cells[1, 1].Text = "[Fields!PaymentType.Value]"; rt.Cells[1, 1].Style.Parents = boldFontStyle; rt.Cells[1, 2].RenderObject = CreateAggregate1("Sum amount:", "PaymentTypeSum", smallFontStyle, boldFontStyle); rt.Cells[1, 2].Style.BackColor = Color.LightGray; rt.Cells[1, 3].RenderObject = CreateAggregate1("Sum quantity:", "PaymentTypeQuantity", smallFontStyle, boldFontStyle); rt.Cells[1, 3].Style.BackColor = Color.LightGray; rt.Cells[1, 4].RenderObject = CreateAggregate1("Item count:", "PaymentTypeCount", smallFontStyle, boldFontStyle); rt.Cells[1, 4].Style.BackColor = Color.LightGray; // captions of details rt.Cells[2, 0].Text = "Date"; rt.Cells[2, 0].Style.Parents = detailCaptionStyle; rt.Cells[2, 1].Text = "Time"; rt.Cells[2, 1].Style.Parents = detailCaptionStyle; rt.Cells[2, 2].Text = "Amount"; rt.Cells[2, 2].Style.Parents = detailCaptionStyle; rt.Cells[2, 3].Text = "Quantity"; rt.Cells[2, 3].Style.Parents = detailCaptionStyle; rt.Cells[2, 4].Text = "Description"; rt.Cells[2, 4].Style.Parents = detailCaptionStyle; // details rt.Cells[3, 0].Text = "[FormatDateTime(Fields!PurchaseDate.Value, DateFormat.ShortDate)]"; rt.Cells[3, 0].Style.Parents = dateStyle; rt.Cells[3, 1].Text = "[FormatDateTime(Fields!Time.Value, DateFormat.ShortTime)]"; rt.Cells[3, 1].Style.Parents = timeStyle; rt.Cells[3, 2].Text = "[Fields!PaymentAmount.Value]"; rt.Cells[3, 2].Style.Parents = paymentAmountStyle; rt.Cells[3, 3].Text = "[Fields!Quantity.Value]"; rt.Cells[3, 3].Style.Parents = quantityStyle; rt.Cells[3, 4].Text = "[Fields!Description.Value]"; rt.Cells[3, 4].Style.Parents = descriptionStyle; // summary by Payment type rt.Cells[4, 0].SpanCols = 2; rt.Cells[4, 2].Text = "[Aggregates!PaymentTypeSum.Value]"; rt.Cells[4, 3].SpanCols = 2; // summary by Company rt.Cells[5, 0].SpanCols = 4; rt.Cells[5, 0].Text = "Sum for company [Fields!Company.Value]:"; rt.Cells[5, 0].Style.TextAlignHorz = AlignHorzEnum.Right; rt.Cells[5, 4].Text = "[Aggregates!CompanySum.Value]"; // itogo rt.Cells[6, 0].SpanCols = 4; rt.Cells[6, 0].Text = "Summary:"; rt.Cells[6, 0].Style.TextAlignHorz = AlignHorzEnum.Right; rt.Cells[6, 4].Text = "[Aggregates!Sum.Value]"; // define databinding within table TableVectorGroup g = rt.RowGroups[0, 6]; g.DataBinding.DataSource = dsCities; g.DataBinding.Grouping.Expressions.Add("Fields!Company.Value"); g.CanSplit = true; doc.DataSchema.Aggregates.Add(new Aggregate("CompanySum", "Fields!PaymentAmount.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Sum)); doc.DataSchema.Aggregates.Add(new Aggregate("Sum", "Fields!PaymentAmount.Value", g.DataBinding, RunningEnum.Document, AggregateFuncEnum.Sum)); g = rt.RowGroups[1, 4]; g.DataBinding.DataSource = dsCities; g.DataBinding.Grouping.Expressions.Add("Fields!PaymentType.Value"); g.CanSplit = true; doc.DataSchema.Aggregates.Add(new Aggregate("PaymentTypeCount", "Fields!PaymentAmount.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Count)); doc.DataSchema.Aggregates.Add(new Aggregate("PaymentTypeSum", "Fields!PaymentAmount.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Sum)); doc.DataSchema.Aggregates.Add(new Aggregate("PaymentTypeQuantity", "Fields!Quantity.Value", g.DataBinding, RunningEnum.Group, AggregateFuncEnum.Sum)); g = rt.RowGroups[3, 1]; g.DataBinding.DataSource = dsCities; // create aggregates doc.Body.Children.Add(rt); doc.Generate(); }