تولید پویای ستون‌ها در PdfReport
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه

همانطور که در نکته انتهای قسمت قبل «کار با بانک‌های اطلاعاتی مختلف در PdfReport» عنوان شد، ذکر قسمت MainTableColumns و تمام تعاریف مرتبط با آن در PdfReports اختیاری است. برای تهیه یک گزارش توسط PdfReport فقط کافی است تا منبع داده را جهت تولید ستون‌های گزارش مشخص کنید.
این مورد انعطاف پذیری زیادی را به همراه خواهد داشت؛ اما ... پس از مدتی این سؤالات مطرح می‌شوند: آیا می‌شود در این ستون‌های خودکار، فیلدهای DateTime، با تاریخ شمسی نمایش داده شوند؟ آیا امکانپذیر است که ستونهای عددی، جمع پایین صفحه داشته باشند؟ و مواردی از این دست که در مورد نحوه مدیریت این نوع ستون‌های خودکار در ادامه بحث خواهد شد.

ابتدا سورس کامل مثال جاری را در ادامه ملاحظه خواهید کرد. تقریبا همان مثال قسمت قبل است که تعاریف ستون‌های آن حذف شده است:
using System;
using PdfRpt;
using PdfRpt.Core.Contracts;
using PdfRpt.Core.Helper;
using PdfRpt.FluentInterface;

namespace PdfReportSamples.AdHocColumns
{
    public class AdHocColumnsPdfReport
    {
        public IPdfReportData CreatePdfReport()
        {
            return new PdfReport().DocumentPreferences(doc =>
            {
                doc.RunDirection(PdfRunDirection.RightToLeft);
                doc.Orientation(PageOrientation.Portrait);
                doc.PageSize(PdfPageSize.A4);
                doc.DocumentMetadata(new DocumentMetadata { Author = "Vahid", Application = "PdfRpt", Keywords = "Test", Subject = "Test Rpt", Title = "Test" });
            })
             .DefaultFonts(fonts =>
             {
                 fonts.Path(AppPath.ApplicationPath + "\\fonts\\irsans.ttf",
                            Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\verdana.ttf");
             })
             .PagesFooter(footer =>
             {
                 footer.DefaultFooter(printDate: DateTime.Now.ToString("MM/dd/yyyy"));
             })
             .PagesHeader(header =>
             {
                 header.DefaultHeader(defaultHeader =>
                 {
                     defaultHeader.ImagePath(AppPath.ApplicationPath + "\\Images\\01.png");
                     defaultHeader.Message("گزارش جدید ما");
                 });
             })
             .MainTableTemplate(template =>
             {
                 template.BasicTemplate(BasicTemplate.SilverTemplate);
             })
             .MainTablePreferences(table =>
             {
                 table.ColumnsWidthsType(TableColumnWidthType.Relative);
             })
             .MainTableDataSource(dataSource =>
             {
                 dataSource.GenericDataReader(
                    providerName: "System.Data.SQLite",
                    connectionString: "Data Source=" + AppPath.ApplicationPath + "\\data\\blogs.sqlite",
                    sql: @"SELECT [url] as 'آدرس', [name] as 'نام', [NumberOfPosts] as 'تعداد مطالب', [AddDate] as 'تاریخ ارسال'
                           FROM [tblBlogs]
                           WHERE [NumberOfPosts]>=@p1",
                    parametersValues: new object[] { 10 }
                );
             })
             .MainTableSummarySettings(summary =>
             {
                 summary.OverallSummarySettings("جمع کل");
                 summary.PreviousPageSummarySettings("نقل از صفحه قبل");
                 summary.PageSummarySettings("جمع صفحه");
             })
             .MainTableAdHocColumnsConventions(adHocColumns =>
             {
                 //We want sum of the int columns
                 adHocColumns.AddTypeAggregateFunction(
                     typeof(Int64),
                     new AggregateProvider(AggregateFunction.Sum)
                     {
                         DisplayFormatFormula = obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)
                     });

                 //We want to dispaly all of the dateTimes as ShamsiDateTime
                 adHocColumns.AddTypeDisplayFormatFormula(
                     typeof(DateTime),
                     data => { return PersianDate.ToPersianDateTime((DateTime)data); }
                 );
                 adHocColumns.ShowRowNumberColumn(true);
                 adHocColumns.RowNumberColumnCaption("ردیف");
             })
             .MainTableEvents(events =>
             {
                 events.DataSourceIsEmpty(message: "There is no data available to display.");
             })
             .Export(export =>
             {
                 export.ToExcel();
                 export.ToXml();
             })
             .Generate(data => data.AsPdfFile(AppPath.ApplicationPath + "\\Pdf\\AdHocColumnsSampleRpt.pdf"));
        }
    }
}

توضیحات:

- با توجه به اینکه تعاریف ستون‌ها را حذف کرده‌ایم و به این ترتیب ستون‌ها به صورت خودکار بر اساس فیلدهای معرفی شده در منبع داده تشکیل می‌شوند، نیاز است سر ستون‌ها را بتوانیم فارسی نمایش دهیم. به همین جهت اینبار کوئری SQL ما با استفاده از aliasها، نامی فارسی را جهت فیلدها تدارک دیده است:
SELECT [url] as 'آدرس', [name] as 'نام', [NumberOfPosts] as 'تعداد مطالب', [AddDate] as 'تاریخ ارسال'
FROM [tblBlogs]
WHERE [NumberOfPosts]>=@p1
- در مرحله بعد توسط متد MainTableAdHocColumnsConventions، یک سری روال را جهت پردازش و نمایش این ستون‌های پویا مشخص می‌کنیم. برای مثال علاقمندیم در این نوع گزارشات هم ستون خودکار ردیف ظاهر شود:
adHocColumns.ShowRowNumberColumn(true);
adHocColumns.RowNumberColumnCaption("ردیف");
همچنین هر ستونی که نوع داده‌اش DateTime بود، از طریق فرمولی که مشخص می‌کنیم، به صورت شمسی نمایش داده شود:
adHocColumns.AddTypeDisplayFormatFormula(
                     typeof(DateTime),
                     data => { return PersianDate.ToPersianDateTime((DateTime)data); }
                 );
به علاوه می‌خواهیم تمام ستون‌هایی از نوع Int64، دارای جمع پایین صفحه هم باشند:
adHocColumns.AddTypeAggregateFunction(
                     typeof(Int64),
                     new AggregateProvider(AggregateFunction.Sum)
                     {
                         DisplayFormatFormula = obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)
                     });
نوع int در بانک اطلاعاتی SQLite معادل نوع Int64 در دات نت است.
  • #
    ‫۱۱ سال و ۱۲ ماه قبل، یکشنبه ۱۶ مهر ۱۳۹۱، ساعت ۰۰:۴۸
    با سلام
    مهندس اگه یکمی دیگه ادامه بدید دیگه خود من از استفاده از این گزارش سازها مثل StimulReport و ... بی خیال می‌شم و مثل همیشه کارهاتون عالیه . با تشکر
  • #
    ‫۱۱ سال و ۱۲ ماه قبل، شنبه ۲۹ مهر ۱۳۹۱، ساعت ۰۳:۵۲
    سلام آقای نصیری ، با تشکر از این pdfReport بسیار عالی ، میخواستم یک راهنمایی در باره چگونگی استفاده از یک بانک اطلاعاتی sqlServer در این این سیستم گزارش گیری بفرمایید 
    با تشکر و سپاس فراوان .
  • #
    ‫۱۱ سال و ۱۲ ماه قبل، شنبه ۲۹ مهر ۱۳۹۱، ساعت ۲۰:۱۶
    سلام آقای نصیری 
    من تنطیمات اتصال بانک اطلاعاتی را انجام داده ام . اما باز با مشکل مواجه هستم .
    کد‌های خودم رو خدمت شما ارسال میکنم . منو راهنمایی بفرمایید.
    با تشکر

    ..MainTableDataSource(dataSource =>
                 {
                     dataSource.SqlDataReader(
                        providerName: "System.Data.SqlClient",
                        connectionString: "Data Source=.\SQLEXPRESS;Initial Catalog=EFDB;Integrated Security=True",
                        sql: @"SELECT [id] as 'شماره', [Title] as 'نام', [Content] as 'تعداد مطالب', [Date] as 'تاریخ ارسال'
                               FROM [posts]
                               WHERE [NumberOfPosts]>=@p1",
                        parametersValues: new object[] { 10 }
                    );
                 })
    • #
      ‫۱۱ سال و ۱۲ ماه قبل، شنبه ۲۹ مهر ۱۳۹۱، ساعت ۲۰:۲۲
      - لطفا جهت پرسش و پاسخ ویژه این پروژه، از قسمت مرتبط با آن در سایت استفاده کنید: (^)
      - امضای متد ویژه SqlDataReader به صورت زیر است:
      public void SqlDataReader(string connectionString, string sql, params object[] parametersValues)
      همانطور که مشاهده می‌کنید نیازی به ذکر providerName ندارد.
      - در دفعات بعد (چه در این سایت یا هر جای دیگری)، قسمت «با مشکل مواجه هستم» را بیشتر توضیح دهید. چون در این حالت کلی، اشخاص باید حدس بزنند که مشکل یاد شده چه چیزی بوده.
  • #
    ‫۱۱ سال و ۹ ماه قبل، جمعه ۲۲ دی ۱۳۹۱، ساعت ۲۲:۰۵
    آقای نصیری با سلام.
    آیا امکان دارد برخی از ستون‌ها را استاتیک و برخی دیگر را adhoc تعریف کنیم البته به غیر از rowNumber ؟
    با تشکر.
    • #
      ‫۱۱ سال و ۹ ماه قبل، جمعه ۲۲ دی ۱۳۹۱، ساعت ۲۳:۰۹
      سلام؛ ستون‌های استاتیک را هم در دیتاسورس قرار بدید و در حالت adhoc استفاده کنید.
      • #
        ‫۱۱ سال و ۹ ماه قبل، جمعه ۲۲ دی ۱۳۹۱، ساعت ۲۳:۲۳
        سلام .
        منبع داده من Strongly type می‌باشد . چگونه می‌توانم برای آنها alias name بگذارم. با تشکر.
        • #
          ‫۱۱ سال و ۹ ماه قبل، شنبه ۲۳ دی ۱۳۹۱، ساعت ۰۰:۱۳
          در این حالت می‌تونید از data annotations استفاده کنید. به صورت خودکار اعمال خواهند شد.
          • #
            ‫۱۱ سال و ۹ ماه قبل، شنبه ۲۳ دی ۱۳۹۱، ساعت ۰۲:۵۲
            سپاس مهندس. عالی .