۱۳۹۰/۰۴/۲۰

نمايش يك فايل PDF در WinForms ، WPF و سيلورلايت


شايد PDF را بشود تنها فرمت گزارشگيري دانست كه همه‌جا و در تمام سيستم عامل‌ها پشتيباني مي‌شود. از ويندوز تا لينوكس از وب تا WPF تا سيلورلايت تا همه جا و از همه مهم‌تر اينكه خروجي آن دقيقا همان چيزي است كه كاربر نهايي مي‌خواهد: من مي‌خوام اون چيزي رو كه مي‌بينم، دقيقا همان را، بدون كم و كاست و با همان صفحه بندي، بتوانم چاپ كنم.
براي توليد PDF مي‌شود از كتابخانه‌ي iTextSharp استفاده كرد اما براي نمايش آن حداقل در ويندوز بهترين راه حل استفاده از COM Components‌ شركت Adobe است كه به همراه برنامه رايگان Adobe PDF reader ارائه مي‌شود. در ادامه نحوه‌ي استفاده از اين Active-X را بررسي خواهيم كرد.

نمايش PDF در WPF
در تمام حالت‌ها هدف اين است كه به نحوي به اكتيوايكس شركت Adobe دسترسي پيدا كنيم؛ يا با اضافه كردن آن به پروژه يا استفاده از امكانات يكپارچه مرورگرها. در WPF از زمان ارائه سرويس پك يك دات نت سه و نيم (به بعد)، كنترل مرورگر وب هم به جمع كنترل‌هاي قابل استفاده در آن اضافه شده است. در اينجا به سادگي چند سطر زير مي‌شود يك فايل PDF را در WPF نمايش داد:
<Window x:Class="WpfAppTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Pdf Report" Height="495" WindowState="Maximized"
WindowStartupLocation="CenterScreen" Width="703">
<Grid>
<WebBrowser x:Name="WebBrowser1"/>
</Grid>
</Window>
و بعد هم در كدهاي برنامه تنها كافي است كه مقدار Source كنترل WebBrowser را مقدار دهي كرد:
WebBrowser1.Source = new Uri(PdfFilePath);


نمايش PDF در WinForms
اكتيوايكس نمايش دهنده PDF شركت Adobe اساسا در فايل ذيل قرار گرفته است:
C:\Program Files\Common Files\Adobe\Acrobat\ActiveX\AcroPDF.dll
بنابراين براي استفاده از آن در يك برنامه‌ي WinForms بايد مراحل ذيل طي شود:
الف) در VS.NET‌ از طريق منوي Tools گزينه‌ي Choose toolbox items ، برگه‌ي Com components را انتخاب كنيد.
ب) سپس گزينه‌ي Adobe PDF reader كه به همان مسير dll فوق اشاره مي‌كند را انتخاب نمائيد و بر روي دكمه‌ي OK‌ كليك كنيد.
ج) اكنون اين كنترل جديد را بر روي فرم برنامه قرار دهيد. به صورت خودكار COMReference هاي متناظر به پروژه اضافه مي‌شوند.

اكنون نحوه‌ي استفاده از اين شيء COM به همراه آزاد سازي منابع مرتبط به شرح زير خواهند بود:
using System.Windows.Forms;

namespace WindowsFormsAppTests
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
this.FormClosing += Form1_FormClosing;
}

void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
axAcroPDF1.Dispose();
}

void Form1_Load(object sender, System.EventArgs e)
{
axAcroPDF1.LoadFile(PdfFilePath);
axAcroPDF1.setShowToolbar(true);
axAcroPDF1.Show();
}
}
}

نمايش PDF در Silverlight

در Silverlight هم از نسخه‌ي 4 به بعد كنترل WebBrowser همانند آنچه كه در WPF موجود است، اضافه شده است؛ اما اين كنترل فقط در حالت اجراي در خارج از مرورگر برنامه Silverlight در دسترس مي‌باشد. بنابراين روش ديگري را بايد انتخاب كرد. اين روش بر اساس تعامل سيلورلايت با كدهاي HTML صفحه كار مي‌كند. يك IFrame مخفي را در صفحه بالاي شيء مرتبط با سيلورلايت قرار خواهيم داد. سپس در سيلورلايت Src اين IFrame را به مسير فايل PDF تنظيم مي‌كنيم و همين. به اين ترتيب فايل PDF نمايش داده مي‌شود.
اين IFrame به صورت زير در همان صفحه‌ي aspx ايي كه object مرتبط با Silverlight نمايش داده مي‌شود قرار مي‌گيرد:
<iframe id="pdfFrame" style="visibility:hidden; position:absolute"><b>No Content</b></iframe>
<div id="silverlightControlHost">
سپس در كدهاي سيلورلايت، ابتدا اين IFrame يافت شده:
var iFrame = HtmlPage.Document.GetElementById("pdfFrame");
در ادامه بر اساس اطلاعات مكاني يك Grid ساده به نام pdfHost كه در صفحه قرار گرفته، اين iFrame بالاتر از سطح Grid (بر اساس z-index تنظيم شده) نمايش داده مي‌شود:
var gt = pdfHost.TransformToVisual(Application.Current.RootVisual);
var offset = gt.Transform(new Point(0, 0));
var controlLeft = (int)offset.X;
var controlTop = (int)offset.Y;
iFrame.SetStyleAttribute("left", string.Format("{0}px", controlLeft));
iFrame.SetStyleAttribute("top", string.Format("{0}px", controlTop));
iFrame.SetStyleAttribute("visibility", "visible");
iFrame.SetStyleAttribute("height", string.Format("{0}px", pdfHost.ActualHeight));
iFrame.SetStyleAttribute("width", string.Format("{0}px", pdfHost.ActualWidth));
iFrame.SetStyleAttribute("z-index", "1000");
و در آخر نام فايلي را كه مي‌خواهيم مشاهده كنيم به يك صفحه‌ي aspx در همان سايت ارسال مي‌كنيم:
iFrame.SetProperty("src", "ShowPdf.aspx?file=" + fileName);
كدهاي اين صفحه در حد يك Response.Redirect ساده براي نمايش دادن فايل pdf در مرورگر كافي هستند. در كل در اينجا سيلورلايت تنها نقش انتخاب فايل را به عهده دارد و كار اصلي را خود مرورگر انجام مي‌دهد.