This project has moved and is read-only. For the latest updates, please go here.

Specifying the "MainTableColumns" method and all of its definitions is arbitrary in PdfReport. Just omit this part and then the final report will be created dynamically based on the available columns in the provided data source.
This feature gives us a great flexibility, but after some time we need to customize these kinds of reports: how to format DateTimes, how to add the total number of numeric fields and so on.

Here are some tips about customizing the auto generated columns:


a) Use aliases to specify the header cells:
If you are using the SQL based data sources such as GenericDataReader, to customize the header cells just define the column aliases in your final SQL:

SELECT [NumberOfPosts] as 'Number of posts'
FROM [tblBlogs]
WHERE [NumberOfPosts]>=@p1

b) Specifying the rendering conventions, based on the data types of columns
By using the "MainTableAdHocColumnsConventions" method, it's possible to alter the rendering conditions of the dynamic columns.
In MainTableAdHocColumnsConventions method, We can include the auto generated row column in the final report:

adHocColumns.ShowRowNumberColumn(true);
adHocColumns.RowNumberColumnCaption("#");

Or it's possible to format a cell's value based on its type:

adHocColumns.AddTypeDisplayFormatFormula(
                     typeof(DateTime),
                     data => { return PersianDate.ToPersianDateTime((DateTime)data); }
                 );

Here we are altering the rendering value of all of the "DateTime" columns.

adHocColumns.AddTypeAggregateFunction(
                     typeof(Int64),
                     new AggregateProvider(AggregateFunction.Sum)
                     {
                         DisplayFormatFormula = obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)
                     });

Or we can determine the specific AggregateFunction of the given data type.

c) Using data annotations to define columns properties
If you are using a generic list data source, it's possible to omit the "MainTableColumns" method and all of its definitions by replacing them with data annotations:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using PdfReportSamples.Models;
using PdfRpt.Aggregates.Numbers;
using PdfRpt.ColumnsItemsTemplates;
using PdfRpt.Core.Contracts;
using PdfRpt.Core.Helper;
using PdfRpt.DataAnnotations;

namespace PdfReportSamples.DataAnnotations
{
    public class Person
    {
        [IsVisible(false)]
        public int Id { get; set; }

        [DisplayName("User name")]
        //Note: If you don't specify the ColumnItemsTemplate, a new TextBlockField() will be used automatically.
        [ColumnItemsTemplate(typeof(TextBlockField))]
        public string Name { get; set; }

        [DisplayName("Job title")]
        public JobTitle JobTitle { set; get; }

        [DisplayName("Date of birth")]
        [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
        public DateTime DateOfBirth { get; set; }

        [DisplayName("Date of death")]
        [DisplayFormat(NullDisplayText = "-", DataFormatString = "{0:MM/dd/yyyy}")]
        public DateTime? DateOfDeath { get; set; }

        [DisplayFormat(DataFormatString = "{0:n0}")]
        [CustomAggregateFunction(typeof(Sum))]
        public int Salary { get; set; }

        [IsCalculatedField(true)]
        [DisplayName("Calculated Field")]
        [DisplayFormat(DataFormatString = "{0:n0}")]
        [AggregateFunction(AggregateFunction.Sum)]
        public string CalculatedField { get; set; }

        [CalculatedFieldFormula("CalculatedField")]
        public static Func<IList<CellData>, object> CalculatedFieldFormula =
                                                    list =>
                                                    {
                                                        if (list == null) return string.Empty;
                                                        var salary = (int)list.GetValueOf<Person>(x => x.Salary);
                                                        return salary * 0.8;
                                                    };//Note: It's a static field, not a property.
    }
}

- If you don't want to show a property in the final report, use the [IsVisible(false)] attribute.
- DisplayName attribute will be used to define the header cells of the report.
- Specifying the ColumnItemsTemplate attribute is optional and if it's not defined, TextBlockField will be used automatically.
Other predefined column cell's templates are defined in PdfRpt.ColumnsItemsTemplates namespace.
- To format the displayed dates or numbers, use DisplayFormat attribute.
- To add the total rows, specify the CustomAggregateFunction attribute. There are some built-in aggregate functions in PdfRpt.Aggregates.Numbers namespace.
- To define a calculated field/column, specify the [IsCalculatedField(true)] attribute. And then add a new static field (not a property) to define the related formula. This new field should be decorated with CalculatedFieldFormula attribute to determine the property name of the calculated field.

Here are some full samples about auto generated columns:

AdHocColumns
DataAnnotations

Last edited Nov 5, 2012 at 9:18 AM by VahidN, version 8

Comments

No comments yet.