public static void Main(string[] args) { Report r = new Report (); //---------------------- // report header section //---------------------- var invTextTb = new TextBlock (){ Text = "Invoice", Width = r.Width, FontWeight = FontWeight.Bold, FontSize = 14, HorizontalAlignment = HorizontalAlignment.Center, }; r.ReportHeaderSection.Controls.Add (invTextTb); var invNumberTb = new TextBlock (){ FieldName ="invoice.Number", FieldKind = FieldKind.Parameter, Text = "Invoice", Width = r.Width, FontSize = 14, Top = 5.mm(), HorizontalAlignment = HorizontalAlignment.Center, FontColor = Color.White }; r.ReportHeaderSection.Height = 30.mm (); r.ReportHeaderSection.Controls.Add (invNumberTb); r.ReportHeaderSection.BackgroundColor = Color.Silver; //------------------- //page header section //------------------- var phLine = new Line (){ Location = new Point(0,10.mm()), End = new Point(r.Width,10.mm()), ExtendToBottom = true}; r.PageHeaderSection.Controls.Add (phLine); //index label var indhTb = new TextBlock () {FontWeight = FontWeight.Bold, Text = "Ind", Width = 10.mm()}; r.PageHeaderSection.Controls.Add (indhTb); // description label var deschTb = new TextBlock () {FontWeight = FontWeight.Bold,Text = "Description", Left = 12.mm(), Width = 20.mm()}; r.PageHeaderSection.Controls.Add (deschTb); // quantity label var qnthTb = new TextBlock () {FontWeight = FontWeight.Bold, Text = "Quantity", Left = 42.mm()}; r.PageHeaderSection.Controls.Add (qnthTb); // price field var prthTb = new TextBlock () {FontWeight = FontWeight.Bold,Text = "Price", Left = 60.mm(),Width = 30.mm()}; r.PageHeaderSection.Controls.Add (prthTb); //--------------- //details section //--------------- //do not allow break detail section across page r.DetailSection.KeepTogether = true; r.DetailSection.Height = 6.mm (); //index field var indTb = new TextBlock () { FieldName = "Index", FieldKind = FieldKind.Data, Text = "00", Left = 1.2.mm(), Width = 10.mm()}; r.DetailSection.Controls.Add (indTb); // description field var descTb = new TextBlock () { FieldName = "Description", FieldKind = FieldKind.Data, Text = "Desc", Left = 12.mm(), Width = 35.mm()}; r.DetailSection.Controls.Add (descTb); // quantity field var qntTb = new TextBlock () { FieldName = "Quantity", FieldKind = FieldKind.Data, Text = "0", Left = 47.mm(), Width = 5.mm(), }; r.DetailSection.Controls.Add (qntTb); // price field var prtTb = new TextBlock () { FieldName = "PricePerUnitGross", FieldTextFormat = "{0:C}", FieldKind = FieldKind.Data, Text = "0", Left = 62.mm(),Width = 20.mm()}; r.DetailSection.Controls.Add (prtTb); var line = new Line (){ Location = new Point(0,2.mm()), End = new Point(r.Width,2.mm()), ExtendToBottom = true}; r.DetailSection.Controls.Add (line); //just before processing we can change section properties r.DetailSection.OnBeforeControlProcessing += delegate(ReportContext rc, Control c) { if (rc.RowIndex % 2 == 0) { c.BackgroundColor = Color.LightGray; } else { ((TextBlock)(c as Section).Controls [1]).FontColor = Color.PaleVioletRed; } }; var lv0 = new Line (){ Location = new Point(1,0), End = new Point(1,2.mm()), ExtendToBottom = true}; r.DetailSection.Controls.Add (lv0); var lineV = new Line (){ Location = new Point(r.Width,2.mm()), End = new Point(r.Width,2.mm()), LineType = LineType.Dash, ExtendToBottom = true}; r.DetailSection.Controls.Add (lineV); //--------------- //Report footer //--------------- // price field var prtTotalLabelTb = new TextBlock () { FontWeight = FontWeight.Bold, HorizontalAlignment = HorizontalAlignment.Right, FontSize = 12, FieldKind = FieldKind.Parameter, Text = "Total: ", Left = 50.mm(), Width = 10.mm() }; r.ReportFooterSection.Controls.Add (prtTotalLabelTb); var prtTotalTb = new TextBlock () { FontWeight = FontWeight.Bold, FieldName = "invoice.TotalGross", FieldTextFormat = "{0:C}", FontSize = 12, FieldKind = FieldKind.Parameter, Text = "0", Left = 62.mm(), Width = 40.mm() }; r.ReportFooterSection.Controls.Add (prtTotalTb); //--------------- //Page footer //--------------- var fl = new Line (){ Location = new Point(0,1), End = new Point(r.Width,1)}; r.PageFooterSection.Controls.Add (fl); var pnTb = new TextBlock () { FieldName = "#PageNumber", FieldTextFormat = "{0:C}", FieldKind = FieldKind.Expression, Text = "0", Left = (r.Width-30).mm(), Width = 10.mm(), HorizontalAlignment = HorizontalAlignment.Right, Top = 2.mm()}; r.PageFooterSection.Controls.Add (pnTb); r.PageFooterSection.BackgroundColor = Color.LightBlue; #region example invoice datasource //example invoice class... Invoice invoice = new Invoice () { Number = "01/12/2010", CreationDate = DateTime.Now, Positions = new List<InvoicePosition>() }; for (int i = 0; i < 82; i++) { invoice.Positions.Add ( new InvoicePosition () { Index = i+1, Quantity = 1, Description = "Reporting services " + (i + 1).ToString(), PricePerUnitGross = ((i * 50) / (i + 1)) + 1 } ); } invoice.Positions [4].Description = "here comes longer position text to see if position will extend section height"; invoice.Positions [11].Description = "another longer position text to see if position will extend section height"; //Total gross ... invoice.TotalGross = invoice.Positions.Sum (p => p.PricePerUnitGross * p.Quantity); #endregion ObjectDataSource<InvoicePosition> objectDataSource = new ObjectDataSource<InvoicePosition>(invoice.Positions); objectDataSource.AddField ("Index",x=>x.Index); objectDataSource.AddField ("Description",x=>x.Description); objectDataSource.AddField ("Quantity",x=>x.Quantity); objectDataSource.AddField ("PricePerUnitGross",x=>x.PricePerUnitGross); r.DataSource = objectDataSource; //we can get cairo context before and after rendering each page //to draw custom shapes, texts (e.g watermarks etc) //here modified example from http://www.mono-project.com/Mono.Cairo r.OnAfterPageRender += delegate(ReportContext rc, Page p) { if (rc.CurrentPageIndex % 2 > 0) { Cairo.Context gr = rc.RendererContext as Cairo.Context; gr.MoveTo (50.mm (), 100.mm ()); gr.CurveTo (50.mm (), 50.mm (), 50.mm (), 50.mm (), 100.mm (), 50.mm ()); gr.CurveTo (100.mm (), 100.mm (), 100.mm (), 100.mm (), 50.mm (), 100.mm ()); gr.ClosePath (); // Save the state to restore it later. That will NOT save the path gr.Save (); Cairo.Gradient pat = new Cairo.LinearGradient (50.mm (),100.mm (), 100.mm (),50.mm ()); pat.AddColorStop (0, new Cairo.Color (0,0,0,0.3)); pat.AddColorStop (1, new Cairo.Color (1,0,0,0.2)); gr.Pattern = pat; // Fill the path with pattern gr.FillPreserve (); // We "undo" the pattern setting here gr.Restore (); // Color for the stroke gr.Color = new Cairo.Color (0,0,0); gr.LineWidth = 1.px (); gr.Stroke (); } }; var parameters = new Dictionary<string,object>{ {"invoice.Number",invoice.Number}, {"invoice.CreationDate",invoice.CreationDate}, {"invoice.TotalGross",invoice.TotalGross}, }; r.ExportToPdf ("invoice.pdf", parameters); r.Save ("report.mrp"); }