EF Code First #14
شما شیء Context رو در سطح فرم تعریف میکنید (چون میتونید؛ چون برنامههای ویندوزی متفاوتاند از برنامههای وب بدون حالت که در آنها پس از نمایش صفحه، کلیه اشیاء تخریب میشوند)، حالا هر شیءایی که اضافه بشه، به Context جاری اضافه شده، حذف بشه از این مرجع حذف شده یا اگر ویرایش شود باز هم به صورت خودکار، تحت نظر Context تعریف شده در سطح فرم است. نهایتا با فراخوانی یک SaveChanges تمام این تغییرات بدون نیاز به محاسبه خاصی در کدهای ما، توسط EF اعمال میشوند. سیستم Tracking به صورت خودکار، کوئریهای insert، update و delete رو محاسبه و اجرا میکنه. نیازی به مدیریت خاصی بجز تعریف Context در سطح فرم نداره.
به صورت خلاصه مرسوم نیست در مثلا WinForms «متداول»، منقطع از Context کار کرد، چون اساسا میشود به سادگی، تا زمانیکه یک فرم در حال نمایش است، Context و سیستم ردیابی خودکار آنرا زنده نگه داشت و از آن استفاده کرد.
- برجسته سازی قسمتی از عبارت جستجو شده در لیست نمایش داده شده توسط افزونه auto-complete. این مورد خودکار است و توسط افزونه انجام میشود.
- برجسته سازی قسمتی از عبارت جستجو شده در نتایج یک جستجوی کامل بعدی که قرار است highlight آن توسط ما با کدنویسی خاصی انجام شود. مراجعه کنید به این مطلب برای توضیحات بیشتر.
اکثر کنترلهای تعیین اعتبار ASP.Net بر اساس جاوا اسکریپت کار میکنند (مانند RangeValidator و امثال آن). حال اگر کاربری افزونه no script فایرفاکس را نصب کرده بود چه باید کرد؟
با استفاده از این افزونه، این نوع کنترلها از کار خواهند افتاد (چون دیگر کدهای جاوا اسکریپتی آنها اجرا نخواهند شد).
خوشبختانه برای بررسی صحت عملکرد این کنترلها در ASP.Net امکان بررسی خاصیت Page.IsValid نیز وجود دارد که در ادامه به آن خواهیم پرداخت.
صفحهی بسیار ساده ASP.Net زیر را در نظر بگیرید:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm3.aspx.cs" Inherits="testWebForms87.WebForm3" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtData" runat="server"></asp:TextBox>
<asp:RangeValidator ID="RangeValidator1" runat="server" ControlToValidate="txtData"
ErrorMessage="لطفا یک عدد وارد کنید" MaximumValue="100000" MinimumValue="0" SetFocusOnError="True"
Type="Integer"></asp:RangeValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtData"
ErrorMessage="لطفا مقداری را وارد نمائید" SetFocusOnError="True"></asp:RequiredFieldValidator>
<br />
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" />
<br />
<asp:Label ID="lblValue" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
سپس برای بررسی سمت سرور عملکرد کنترلهای تعیین اعتبار در ASP.Net میتوان به صورت زیر عملکرد:
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (btnSubmit.CausesValidation)
{
// Validate the Page
Page.Validate();
// Ensure Page is Valid
if (!Page.IsValid)
{
lblValue.Text = "لطفا جاوا اسکریپت را در مرورگر خود فعال نمائید";
return;
}
}
lblValue.Text = txtData.Text;
}
راه دیگر بررسی غیرفعال بودن جاوا اسکریپت در یک صفحه استفاده از روش سنتی تگ noscript است:
<noscript>
<meta http-equiv="refresh" content="0;url=http://www.google.com">
</noscript>
در پایان باید خاطر نشان کرد که هیچگاه به کنترلهای تعیین اعتبار سمت کاربر اطمینان نکنید و حتما یا از روش فوق استفاده نمائید، یا در روال submit صفحه به سرور، یکبار دیگر دادهها را به صورت دستی نیز بررسی کنید. برای مثال اگر کاربر قرار است آدرس ایمیلی را وارد کند، حتما یکبار دیگر با استفاده از regular expressions ، در سمت سرور نیز عبارت ورودی را بررسی کنید.
بوت استرپ (نگارش 3) چیست؟
تازههای بوت استرپ 3 کدامند؟
- بوت استرپ 3 جهت کار با صفحههای نمایش کوچک دستگاههای موبایل به شدت بهینه سازی شده است و به همین جهت به آن mobile-first CSS framework نیز میگویند.
- در نگارش 2 بوت استرپ، حداقل دو نوع گرید واکنشگرا و غیر واکنشگرا قابل تعریف بودند. در نگارش سوم آن، تنها یک نوع گرید جدید واکنشگرا در این فریم ورک وجود دارد که میتواند چهار نوع سایز از بزرگ تا کوچک را شامل شود.
- بوت استرپ 3 با IE7 به قبل و همچنین فایرفاکس 3.6 و پایینتر دیگر سازگار نیست. البته برای پشتیبانی از IE8، نیاز به اندکی تغییرات نیز وجود خواهد داشت که در قسمتهای بعد این جزئیات را بیشتر بررسی خواهیم کرد. به عبارت دیگر بدون این تغییرات، بوت استرپ 3 در حالت پیش فرض با IE9 به بعد سازگار است.
- در بوت استرپ 3 برخلاف نگارش قبلی آن که لیستی از آیکنهای خود را در قالب چند فایل PNG image sprite که آیکنها را به صورت فشرده در کنار هم قرار داده بود، اینبار تنها از Font icons استفاده میکند. به این ترتیب تغییر اندازه این آیکنها با توجه به برداری بودن نمایش قلمها و همچنین قابلیت اعمال رنگ به آنها نیز بسیار سادهتر میگردد.
سؤال: آیا نیاز است از یک فریم ورک CSS واکنشگرا استفاده شود؟
در سالهای قبل، عموما طراحی وب بر اساس تهیه یا خرید یک سری قالبهای از پیش آماده شده، شکیل صورت میگرفتهاست. این قالبها به سرعت با برنامه، یکپارچه شده و حداکثر قلم یا رنگهای آنهارا اندکی تغییر میدادیم و یا اینکه خودمان کل این مسیر را از صفر طی میکردیم. این پروسه سفارشی، بسیار سنگین بوده و مشکل مهم آن، عدم امکان استفاده مجدد از طراحیهای انجام شده میباشد که نهایتا در دراز مدت هزینهی بالایی را برای ما به همراه خواهند داشت. اما با استفاده از فریم ورکهای CSS واکنشگرا به این مزایا خواهیم رسید:
- قسمت عمدهای از کار پیشتر برای شما انجام شده است.
برای مثال نیازی نیست تا حتما برای طرحبندی صفحه، سیستم گرید خاص خودتان را طراحی کنید و یا اینکه مانند سالهای دور، به استفاده از HTML tables پناه ببرید.
- قابلیت سفارشی سازی بسیار بالایی دارند.
برای مثال با استفاده از فناوریهایی مانند less میتوان بوت استرپ را تا حد بسیار زیادی سفارشی سازی کرد. به این ترتیب دیگر یک سایت بوت استرپ، شبیه به بوت استرپ به نظر نخواهد رسید! شاید عدهای عنوان کنند که تمام سایتهای بوت استرپ یک شکل هستند، اما واقعیت این است که این سایتها تنها از قابلیتهای سفارشی سازی بوت استرپ و less استفاده نکردهاند.
دریافت بوت استرپ 3
سایت رسمی دریافت بوت استرپ، آدرس ذیل میباشد:
البته ما از این نگارش خام استفاده نخواهیم کرد و نیاز است برای کارهای سایتهای فارسی، از نگارش راست به چپ آن استفاده کنیم. بنابراین اگر از ویژوال استودیو استفاده میکنید، میتوانید به یکی از دو بسته نیوگت ذیل مراجعه نمائید:
https://www.nuget.org/packages/Twitter.Bootstrap.RTL.Less/3.0.0
https://www.nuget.org/api/v2/package/Twitter.Bootstrap.RTL.Less/3.0.0
اگر بوت استرپ اصل را از سایت اصلی آن دریافت کنید، شامل تعداد فایلها و پوشههای بسیار بیشتری است نسبت به نمونه RTL فوق. اما فایلهای نهایی آن که مورد استفاده قرار خواهند گرفت، درون پوشه dist یا توزیع آن قرار گرفتهاند و آنچنان تفاوتی با نگارش RTL ندارند. فقط در نگارش اصل، فایلهای min و فشرده شده نیز همراه این بسته هستند که در نگارش RTL لحاظ نشدهاند. این موضوع در آینده به نفع ما خواهد بود. از این لحاظ که اگر از سیستم bundling & minification مربوط بهASP.NET استفاده کنید (جهت تولید خودکار فایلهای min در زمان اجرا)، این سیستم به صورت پیش فرض از فایلهای min موجود استفاده میکند و ممکن است مدتی سردرگم باشید که چرا تغییراتی را که به فایل CSS بوت استرپ اعمال کردهام، در سایت اعمال نمیشوند. به علاوه امکان اعمال تغییرات و حتی دیباگ فایلهای غیرفشرده خصوصا جاوا اسکریپتی آن نیز بسیار سادهتر و مفهومتر است.
جهت مطالعه مباحث تکمیلی در مورد نحوه فشرده سازی فایلهای CSS یا JS میتوانید به مقالات ذیل، در سایت جاری مراجعه نمائید:
علاوه بر اینها در نگارش سوم بوت استرپ، تعدادی فایل CSS جدید به نام قالب یا theme نیز اضافه شدهاند که همراه نسخه RTL نیست. برای مثال اگر به پوشه bootstrap-3.0.0.zip\bootstrap-3.0.0\dist\css مراجعه کنید، فایل bootstrap-theme.css نیز قابل مشاهده است. به این ترتیب قالبی و لایهای بر روی مقادیر پیش فرض موجود در فایل bootstrap.css اعمال خواهند شد؛ برای مثال اعمال طراحی تخت یا flat مدرن آن به دکمهها و عناصر دیگر این مجموعه.
شروع یک فایل HTML با بوت استرپ
تا اینجا فرض بر این است که فایلهای بوت استرپ را دریافت کردهاید. در ادامه قصد داریم، نحوه معرفی این فایلها را در یک فایل ساده HTML بررسی کنیم.
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My Website</title> <link href="Content/css/bootstrap-rtl.css" rel="stylesheet"> <link href="Content/css/custom.css" rel="stylesheet"> </head> <body> </body> </html>
اگر سایت شما از تعاریف CSS سفارشی دیگری نیز استفاده میکند، تعاریف آنها باید پس از بوت استرپ، ذکر گردند.
افزودن اسکریپتهای بوت استرپ 3
برای کار با اسکریپتهای بوت استرپ 3 نیاز است ابتدا jQuery را به صورت جداگانه دریافت کنیم. در حال حاضر اگر به سایت جیکوئری مراجعه کنید با دو نگارش 1.x و 2.x این کتابخانه مواجه خواهید شد. اگر نیاز به پشتیبانی از IE 8 را در محل کار خود دارید، باید از نگارش 1.x استفاده کنید. نگارش آخر 1.x کتابخانه جیکوئری را از طریق CDN آن همواره میتوان مورد استفاده قرار داد:
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
پس از تعریف جیکوئری، تعریف اسکریپتهای بوت استرپ قرار میگیرد (چون وابسته است به جیکوئری). فایل bootstrap-rtl.js شامل تمام زیر فایلهای مورد نیاز نیز میباشد:
<script src="Scripts/bootstrap-rtl.js"></script>
این فایل 4 کیلوبایتی را نیز باید به تعاریف اسکریپتهای مورد نیاز، اضافه کرد:
<script src="Scripts/respond.min.js"></script>
تا اینجا ساختار صفحه HTML تهیه شده جهت استفاده از امکانات بوت استرپ 3، شکل زیر را خواهد داشت:
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My Website</title> <link href="Content/css/bootstrap-rtl.css" rel="stylesheet"> <link href="Content/css/custom.css" rel="stylesheet"> <script src="Scripts/respond.min.js"></script> </head> <body> <script src="http://code.jquery.com/jquery-latest.min.js"></script> <script src="Scripts/bootstrap-rtl.js"></script> </body> </html>
فایلهای نهایی این قسمت را از اینجا نیز میتوانید دریافت کنید:
bs3-sample01.zip
SignalR برای برنامه نویسهای جاوا
// Disable all menus tinymce.init({ menubar : false }); // Configure different order tinymce.init({ menubar: "tools table format view insert edit" });
CKEditor
Tinymce
در نسخههای پیشین tiny این دیالوگها به صورت پنجرههای popup باز میشدند، ولی در تمامی نسخههای ck بسیاری از این پنجرهها بدین صورت باز نشده و سفارشی هستند. درست است که در ظاهر مثل هم باز میشوند ولی مکانیزم و روش باز شدن آنها با یکدیگر متفاوت است و در واقع ck با روشی هوشمندانه و با استفاده از کدهای جاوا اسکریپت و ترکیب لایههای html این روش را پیاده سازی میکند.
شاید بگویید خوب چه فرقی میکند که از چه روشی برای پیاده سازی استفاده شود؟ این مورد از دو جنبه مورد بررسی قرار میگیرد:
1 - اگر به مرورگرهایی چون IE دقت کرده باشید، میبینید که موقعیکه یک popup باز میشود، به عنوان یک پنجرهی جدید باز میشود و باعث شلوغ شدن صفحه میگردد و بیشتر موجب آزار کاربر میگردد.
2- ساخت واقعی یک صفحه popup منجر شدن به ایجاد یک پنجره ای جدید و طی شدن فرآیندهای مربوط به بارگذاری و رندر شدن یک صفحهی جدید میباشد؛ ولی در مورد پنجرههای سفارشی این فرآیندها صورت نمیگیرد. این مورد بر روی بسیاری از هاستها خود را به وضوح نمایش میدهد و ck در صرفه جویی از زمان، به مراتب بهتر عمل میکند.
از نسخه tinymce 4 به بعد مکانیزم سفارشی بودن دیالوگها بر روی این ادیتور نیز صورت گرفته است.
کپی و پیست Copy - Paste
بسیاری از کاربران گاهی اوقات مطالب خود را از جایی یا از یک صفحهی وب دیگر به ادیتور کپی میکنند. برای مثال در اینجا صفحهی گوگل را به داخل ادیتورها کپی میکنیم و به نظر میرسد ckeditor در این مواقع رفتار بهتری نسبت به tiny از خود نشان میدهد.
در تاینی لوگوی گوگل دقیقا در وسط قرار گرفته و بعضی موارد خاص مانند فرمها به خوبی نمایش داده میشوند؛ ولی در ck شما متن تمیزتری دارید و طوری نشان داده میشود که یک css کاربرپسند به آن اضافه شده است.
Ckeditor
انعطاف پذیری Flexibility
هر دو ادیتور در این زمینه به خوبی طراحی شدهاند و با استفاده از جاوا اسکریپت میتوان آنها را به سادگی توسعه داد و امکانات دلخواهتان را به آن اضافه کنید ولی در کل ckeditor در زمینه apiهای برنامه نویسی، پیشروتر از رقیبش tinymce است.
حجم یا سایز ادیتورها Size
با توجه به رشد اینترنت در گوشیهای همراه و دیگر وسایل همراه، حجم منابع اینترنتی بیش از قبل مورد توجه قرار میگیرد. در این زمینه tinymce برگ برندهای داشته و بهتر است بدانید که حجم این ویرایشگر تقریبا نصف رقیبش یعنی ckeditor میباشد.
حالا شما با توجه به موارد بالا میتوانید ادیتور خود را انتخاب کنید.
در اینجا هم میتوانید فایلهای مربوط به زبان را نیز دانلود کنید که هر دو از زیان فارسی پشتیبانی میکنند.
منابع:
window.onbeforeunload = function (e) { $.connection.hub.stop(); };
کتابخانه PdfReport به عمد جهت دات نت 3.5 تهیه شده است تا بازه وسیعی از سیستم عاملها را پوشش دهد.
این کتابخانه علاوه بر تبدیل اطلاعات شما به گزارشات مبتنی بر PDF، امکان تهیه خروجی خودکار اکسل (2007 به بعد) را نیز دارد. فایل خروجی آن، به صورت پیوست درون فایل PDF تهیه شده قرار میگیرد و جزئی از آن میشود.
بدیهی است اینبار با کتابخانه گزارش سازی روبرو هستید که با راست به چپ مشکلی ندارد!
کتابخانه PdfReport بر پایه کتابخانههای معروف سورس باز iTextSharp و EPPlus تهیه شده است. حداقل مزیت استفاده از آن، صرفه جویی در وقت شما جهت آموختن ریزه کاریهای مرتبط با هر کدام از کتابخانههای یاده شده است. برای نمونه جهت فراگیری کار با iTextSharp نیاز است یک کتاب 600 صفحهای به نام iText in action را مطالعه و تمرین کنید. این مورد منهای مسایل و نکات متعدد مرتبط با زبان فارسی است که در این کتاب به آنها اشارهای نشده است.
برای تهیه آن، مشکلات متداولی که کاربران مدام در انجمنهای برنامه نویسی مطرح میکنند و ابزارهای موجود عاجز از ارائه راه حلی ساده برای حل آنها هستند، مد نظر بوده و امید است نگارش یک این کتابخانه بتواند بسیاری از این دردها را کاهش دهد.
کار با این کتابخانه صرفا با کدنویسی میسر است (code first) و همین مساله انعطاف پذیری قابل توجهی را ایجاد کرده که در طی روزهای آینده با جزئیات بیشتر آن آشنا خواهید شد.
اما چرا PDF؟
استفاده از قالب PDF برای تهیه گزارشات، این مزایا را به همراه دارد:
- دقیقا همان چیزی که مشاهده میشود، در هر مکانی قابل چاپ است. با همان کیفیت، همان اندازه صفحه، همان فونت و غیره. به این ترتیب به صفحه بندی بسیار مناسب و بهینهای میتوان رسید و مشکلات گزارشات HTML ایی وب را ندارد.
- امکان استفاد از فونتهای شکیلتر در آن بدون مشکل و بدون نیاز به نصب بر روی کامپیوتری میسر است؛ چون فونت را میتوان در فایل PDF نیز قرار داد.
- این فایل در تمام سیستم عاملها پشتیبانی میشود. خصوصا اینکه فایل نهایی در تمام کامپیوترها و در انواع و اقسام سیستم عاملها به یک شکل و اندازه نمایش داده خواهد شد. برای مثال اینطور نیست که در ویندوز XP ،اعداد آن فارسی نمایش داده شوند و در ویندوز 7 با تنظیمات محلی خاصی، دیگر اینطور نباشد. حتی تحت لینوکس هم اعداد آن فارسی نمایش داده خواهد شد چون فونت مخصوص بکار رفته، در خود فایل PDF قابل قرار دادن است.
- برنامه معروف و رایگان Adobe reader برای خواندن و مشاهده آن کفایت میکند و البته کلاینت یکبار باید این برنامه را نصب کند. همچنین از این نوع برنامههای رایگان برای مشاهده فایلهای PDF زیاد است.
- تمام صفحات گزارش را در یک فایل میتوان داشت و به یکباره تمام آن نیز به سادگی قابل چاپ است. این مشکلی است که با گزارشات تحت وب وجود دارد که نمیشود مثلا یک گزارش 100 صفحهای را به یکباره به چاپگر ارسال کرد. به همین جهت عموما کاربران درخواست میدهند تا کل گزارش را در یک صفحه HTML نمایش دهید تا ما راحت آنرا چاپ کنیم یا راحت از آن خروجی بگیریم. اما زمانیکه فایل PDF تهیه میشود این مشکلات وجود نخواهد داشت و جهت Print بسیار بهینه سازی شده است. تا حدی که الان فرمت برگزیده تهیه کتابهای الکترونیکی نیز PDF است. مثلا سایت معروف آمازون امکان فروش نسخه PDF کتابها را هم پیش بینی کرده است.
-امکان صفحه بندی دقیق به همراه مشخص سازی landscape یا portrait بودن صفحه نهایی میسر است. چیزی که در گزارشات صفحات وب آنچنان معنایی ندارد.
- امکان رمزنگاری اطلاعات در آن پیش بینی شده است. همچنین میتوان به فایلهای PDF امضای دیجیتال نیز اضافه کرد. به این ترتیب هرگونه تغییری در محتوای فایل توسط برنامههای PDF خوان معتبر گزارش داده شده و میتوان از صحت اطلاعات ارائه شده توسط آن اطمینان حاصل کرد.
- از فشرده سازی مطالب، فایلها و تصاویر قرار داده شده در آن پشتیبانی میکند.
- از گرافیک برداری پشتیبانی میکند.
مجوز استفاده از این کتابخانه:
کار من مبتنی بر LGPL است. به این معنا که به صورت باینری (فایل dll) در هر نوع پروژهای قابل استفاده است.
اما ... PdfReport از دو کتابخانه دیگر نیز استفاده میکند:
- کتابخانه iTextSharp که دارای مجوز AGPL است. این مجوز رایگان نیست.
- کتابخانه EPPlus برای تولید فایلهای اکسل با کیفیت. مجوز استفاده از این کتابخانه LGPL است و تا زمانیکه به صورت باینری از آن استفاده میکنید، محدودیتی را برای شما ایجاد نخواهد کرد.
کتابخانه PdfReport به صورت سورس باز در CodePlex قرار گرفته ؛ اما جهت پرسیدن سؤالات، پیشنهادات، ارائه بهبود و غیره میتوانید (و بهتر است) از قسمت مدیریت پروژه مرتبط در سایت جاری نیز استفاده کنید.
نحوه تهیه اولین گزارش، با کتابخانه PdfReport
الف) یک پروژه Class library جدید را شروع کنید. از این جهت که گزارشات PdfReport در انواع و اقسام پروژههای VS.NET قابل استفاده است، میتوان از این پروژه Class library به عنوان کلاسهای پایه قابل استفاده در انواع و اقسام پروژههای مختلف، بدون نیاز به تغییری در کدهای آن استفاده کرد.
ب) آخرین نگارش فایلهای مرتبط با PdfReport را از اینجا دریافت کنید و سپس ارجاعاتی را به اسمبلیهای موجود در بسته آن به پروژه خود اضافه نمائید (ارجاعاتی به PdfReport، iTextSharp و EPPlus). فایل XML راهنمای کتابخانه نیز به همراه بسته آن میباشد که در حین استفاده از متدها و خواص PdfReport کمک بزرگی خواهد بود.
ج) کلاسهای زیر را به آن اضافه کنید:
using System.Web; using System.Windows.Forms; namespace PdfReportSamples { public static class AppPath { public static string ApplicationPath { get { if (isInWeb) return HttpRuntime.AppDomainAppPath; return Application.StartupPath; } } private static bool isInWeb { get { return HttpContext.Current != null; } } } }
همانطور که مشاهده میکنید ارجاعاتی را به System.Windows.Forms.dll و System.Web.dll نیاز دارد.
در ادامه کلاس User را جهت ساخت یک منبع داده درون حافظهای تعریف خواهیم کرد:
using System; namespace PdfReportSamples.IList { public class User { public int Id { set; get; } public string Name { set; get; } public string LastName { set; get; } public long Balance { set; get; } public DateTime RegisterDate { set; get; } } }
using System; using System.Collections.Generic; using PdfRpt.Core.Contracts; using PdfRpt.FluentInterface; namespace PdfReportSamples.IList { public class IListPdfReport { 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(Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf", Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\verdana.ttf"); }) .PagesFooter(footer => { footer.DefaultFooter(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.ClassicTemplate); }) .MainTablePreferences(table => { table.ColumnsWidthsType(TableColumnWidthType.Relative); table.NumberOfDataRowsPerPage(5); }) .MainTableDataSource(dataSource => { var listOfRows = new List<User>(); for (int i = 0; i < 200; i++) { listOfRows.Add(new User { Id = i, LastName = "نام خانوادگی " + i, Name = "نام " + i, Balance = i + 1000 }); } dataSource.StronglyTypedList<User>(listOfRows); }) .MainTableSummarySettings(summarySettings => { summarySettings.OverallSummarySettings("جمع کل"); summarySettings.PerviousPageSummarySettings("نقل از صفحه قبل"); summarySettings.PageSummarySettings("جمع صفحه"); }) .MainTableColumns(columns => { columns.AddColumn(column => { column.PropertyName("rowNo"); column.IsRowNumber(true); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(0); column.Width(1); column.HeaderCell("#"); }); columns.AddColumn(column => { column.PropertyName<User>(x => x.Id); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(1); column.Width(2); column.HeaderCell("شماره"); }); columns.AddColumn(column => { column.PropertyName<User>(x => x.Name); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(2); column.Width(3); column.HeaderCell("نام"); }); columns.AddColumn(column => { column.PropertyName<User>(x => x.LastName); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(3); column.Width(3); column.HeaderCell("نام خانوادگی"); }); columns.AddColumn(column => { column.PropertyName<User>(x => x.Balance); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(4); column.Width(2); column.HeaderCell("موجودی"); column.ColumnItemsTemplate(template => { template.TextBlock(); template.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)); }); column.AggregateFunction(aggregateFunction => { aggregateFunction.NumericAggregateFunction(AggregateFunction.Sum); aggregateFunction.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)); }); }); }) .MainTableEvents(events => { events.DataSourceIsEmpty(message: "رکوردی یافت نشد."); }) .Export(export => { export.ToExcel(); export.ToCsv(); export.ToXml(); }) .Generate(data => data.AsPdfFile(AppPath.ApplicationPath + "\\Pdf\\RptIListSample.pdf")); } } }
var rpt = new IListPdfReport().CreatePdfReport(); // rpt.FileName
برای نمونه، جهت مشاهده نمایش این خروجی در یک برنامه ویندوزی، به مثالهای همراه سورس پروژه در مخزن کد آن مراجعه نمائید.
توضیحات بیشتر:
- در قسمت DocumentPreferences، جهت راست به چپ (PdfRunDirection)، اندازه صفحه (PdfPageSize)، جهت صفحه (PageOrientation) و امثال آن تنظیم میشوند.
- سپس نیاز است قلمهای مورد استفاده در گزارش مشخص شوند. در متد DefaultFonts باید دو قلم را معرفی کنید. قلم اول، قلم پیش فرض خواهد بود و قلم دوم برای رفع نواقص قلم اول مورد استفاده قرار میگیرد. برای مثال اگر قلم اول فاقد حروف انگلیسی است، به صورت خودکار به قلم دوم رجوع خواهد شد.
- در ادامه در متد PagesFooter، تاریخ درج شده در پایین تمام صفحات مشخص میشود. در مورد ساخت Footer سفارشی در قسمتهای بعدی بحث خواهد شد.
- در متد PagesHeader، متن و تصویر قرار گرفته در Header تمام صفحات گزارش قابل تنظیم است. این مورد نیز قابل سفارشی سازی است که در قسمتهای بعد به آن خواهیم پرداخت.
- توسط MainTableTemplate، قالب ظاهری ردیفهای گزارش مشخص میشود. یک سری قالب پیش فرض در کتابخانه PdfReport موجود است که توسط متد BasicTemplate آن قابل دسترسی است. در مورد نحوه تعریف قالبهای سفارشی به مرور در قسمتهای بعد، بحث خواهد شد.
- در قسمت MainTablePreferences تنظیمات جدول اصلی گزارش تعیین میشود. برای مثال چه تعداد ردیف در صفحه نمایش داده شود. اگر این مورد را تنظیم نکنید، به صورت خودکار محاسبه خواهد شد. نحوه تعیین عرض ستونهای گزارش به کمک متد ColumnsWidthsType مشخص میشود که در اینجا حالت نسبی درنظر گرفته شده است.
- منبع داده مورد استفاده توسط متد MainTableDataSource مشخص میشود که در اینجا یک لیست جنریک تعیین شده و سپس توسط متد StronglyTypedList در اختیار گزارش ساز جاری قرار میگیرد. تعدادی منبع داده پیش فرض در PdfReport وجود دارند که هر کدام را در قسمتهای بعدی بررسی خواهیم کرد. همچنین امکان تعریف منابع داده سفارشی نیز وجود دارد.
- با کمک متد MainTableSummarySettings، برچسبهای جمعهای پایین صفحات مشخص میشود.
- در قسمت MainTableColumns، ستونهایی را که علاقمندیم در گزارش ظاهر شوند، قید میکنیم. هر ستون باید با یک فیلد یا خاصیت منبع داده متناظر باشد. همچنین همانطور که مشاهده میکنید امکان تعیین Visibility، عرض و غیره آن نیز مهیا است (قابلیت ساخت گزارشاتی که به انتخاب کاربر، ستونهای آن ظاهر یا مخفی شوند). در اینجا توسط callbackهایی که در متد ColumnItemsTemplate قابل دسترسی هستند، میتوان اطلاعات را پیش از نمایش فرمت کرد. برای مثال سه رقم جدا کننده به اعداد اضافه کرد (برای نمونه در خاصیت موجودی فوق) و یا توسط متد AggregateFunction، میتوان متد تجمعی مناسبی را جهت ستون جاری مشخص کرد.
- توسط متد MainTableEvents به بسیاری از رخدادهای داخلی PdfReport دسترسی خواهیم یافت. برای مثال اگر در اینجا رکوردی موجود نباشد، رخداد DataSourceIsEmpty صادر خواهد شد.
- به کمک متد Export، خروجیهای دلخواه مورد نظر را میتوان مشخص کرد. تعدادی خروجی، مانند اکسل، XML و CSV در این کتابخانه موجود است. امکان سفارشی سازی آنها نیز پیش بینی شده است.
- و نهایتا توسط متد Generate مشخص خواهیم کرد که فایل گزارش کجا ذخیره شود.
لطفا برای طرح مشکلات و سؤالات خود در رابطه با کتابخانه PdfReport از این قسمت سایت استفاده کنید.