ایجاد PDF فارسی در ASP.NET توسط #C (با استفاده از iTextSharp)

تصویر مهدی
یکی از مهمترین قالبهای ایجاد خروجی، فایلهای PDF هستند. یکی از بهمترین ویژگی این فایلها (که در فرمتهای مشابه کمتر به چشم می خورد) این است که در تمام سیستم ها بدون توجه به نوع سیستم، سیستم عامل، فونتهای نصب شده و ... یکسان دیده میشوند و همچنین در اکثر سیستمها پشتبانی خوبی از آن شده است. با توجه به تنوع سیستمهای کاربران (مخصوصا در برنامه های تحت وب) این ویژگی بسیار بیشتر اهمیت خود را نشان می دهد. بنابراین چندان عجیب نیست که در حال حاضر یکی از محبوبترین فرمتهای ایجاد خروجی (مثلا در گزارشات) فرمت PDF محسوب میشود. کتابخانه های مختلفی برای ایجاد فایلهای PDF وجود دارد. بهترین کتابخانه ای که من برای زبانهای NET. دیده ام، کتابخانه iTextSharp است. این کتابخانه از روی iText که یکی از معروفترین کتابخانه های ایجاد و مدیریت فایلهای PDF است، نوشته شده است. استفاده از این کتابخانه برای کار کردن با زبان فارسی به سادگی امکان پذیر است ولی نیاز به کمی دقت هنگام استفاده است. در اینجا میخواهم روش ساده استفاده از این کتابخانه برای ایجاد صفحات فارسی را توضیح دهم. اولین کاری که در استفاده از این کتابخانه باید انجام دهید، اضافه کردن فایل itextsharp.dll به رفرنس های پروژه است. آخرین نسخه این کتابخانه در زمان نوشتن این متن نسخه 4.1.6.0 است که از اینجا میتوانید آن را دریافت کنید. برای ایجاد فایل PDF از دو فضای نام زیر استفاده می شود:
using iTextSharp.text;
using iTextSharp.text.pdf;
ایجاد یک فایل PDf با استفاده از iTextSharp شامل 5 مرحله است.
  1. ایجاد یک شئ از کلاس Document
  2. ایجاد یک PdfWriter (که به شئ Document گوش میکند و خروجی را بر روی یک stream مینویسد)
  3. باز کردن شئ Document
  4. اضافه کردن محتوای فایل PDF
  5. بستن شئ Document
  6. در ادامه به بررسی این مراحل می پردازیم.

    1 ایجاد شئ Document

    Document doc = new Document();
    

    2 ایجاد PdfWriter

    ورودی های تابع ایجاد کننده، یک شء از کلاس Document است (که در مرحله قبل ساخته شده است) و یک stream است که خروجی بر روی آن نوشته می شود.
    PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream("sample.pdf", FileMode.Create));
    

    3 باز کردن شئ Document

    doc.Open();
    

    4 اضافه کردن محتوای فایل PDF

    برای اضافه کردن یک متن انگلیسی، به سادگی می توان از دستوری مانند دستور زیر استفاده کرد:
    doc.Add(new Paragraph("Hello World"));
    
    ولی برای استفاده از زبان فارسی، کار کمی بیشتر است و باید حتما جهت نوشته ها را به راست به چپ تبدیل کنیم و فونت مناسب انتخاب کنیم. برای تمرکز بیشتر در مراحل، این موارد را در ادامه (بعد از توضیح مراحل) آورده ام.

    5 بستن Document

                doc.Close();
    


    کار با متون فارسی

    همانطور که گفته شد، برای کار با متون فارسی، باید جهت نوشته ها به صورت راست به چپ شود و همچنین فونت مناسب انتخاب شود. یکی از فونتهایی که برای زبان فارسی به خوبی کار میکند و در اکثر سیستمها موجود است، فونت Tahoma است. نکته قابل توجه اینکه این فونت تنها در کامپیوتری که فایل PDF را ایجاد میکند مورد نیاز است و به علت اینکه در فایل PDF گنجانده خواهد شد، در سایر کامپیوترهایی که فایل PDF را مشاده می کنند، نیازی به وجود این فونت نیست. برای استفاده از فونتها، ابتدا باید پوشه حاوی فونتها را به iTextSharp معرفی کنیم و سپس فونت مورد علاقه خود را توسط تابع FontFactory.GetFont انتخاب کنیم. تنها نکته مهم در اینجا استفاده از encoding مناسب است که برای زبان فارسی (یا به طور کلی یونیکد) از IDENTITY_H استفاده می شود. سایر پارامترهای ورودی این تابع مشخص است و نیازی به توضیح اضافی ندارد.
                FontFactory.RegisterDirectories();
                Font fTahoma = FontFactory.GetFont("Tahoma", BaseFont.IDENTITY_H, 12, Font.NORMAL, Color.BLACK);
    
    برای تبدیل جهت نوشته ها، به طور مستقیم نمیتوانیم عمل کنیم و حتما باید نوشته ها را در یک عنصر دیگر که این قابلیت را داشته باشد قرار دهیم. در iTextSharp تنها دو عنصر هستند که این قابلیت را دارند. یکی ColumnText و دیگری PdfPTable است. در این دو عنصر میتوانیم با تنظیم RunDirection، جهت متون را راست به چپ کنیم و متون فارسی را به خوبی در آنها نمایش دهیم. PdfPTable، مشابه جداول در Html کار میکند و ColumnText هم برای ایجاد ستونهای حاوی متون (به صورت یک مستطیل در صفحه) استفاده می شود. در اینجا برای نمونه استفاده از ColumnText نشان داده می شود. ابتدا یک شئ از کلاس ColumnText با استفاده از محتویات شئ PdfWriter ایجاد میکنیم و مقدار RunDirection آن را تنظیم میکنیم. سپس نوع ستون و ویژگیهای آن را تعیین میکنیم. در اینجا من از ستون ساده استفاده کرده ام که پارامترهای ورودی آن، مختصات گوشه های مستطیل است. بعد از آن، بجای اضافه کردن محتویات به طور مستقیم به Document، محتویات را به شئ ایجاد شده از ColumnText اضافه میکنیم (استفاده از فونت مناسب فراموش نشود). در انتها نیز، با استفاده از متد Go، محتویات ColumnText را در Document می نویسیم.
                ColumnText ct = new ColumnText(writer.DirectContent);
                ct.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
                ct.SetSimpleColumn(20, 20, 555, 800);
    
                ct.AddText(new Phrase(txt, fTahoma));
    
                ct.Go();
    


    دانلود کردن PDF ساخته شده در ASP.NET

    در برنامه های تحت وب، بسیار رایج است که بخواهیم فایل ایجاد شده را در سرور، بر روی هارددیسک ننویسیم و آن را در حافظه ایجاد کرده و مستقیما برای دانلود به کلاینت ارسال کنیم. برای این کار می توانیم بجای stream ایجاد شده در مثال بالا، از MemoryStram استفاده کنیم.
                MemoryStream stream = new MemoryStream();
                PdfWriter writer = PdfWriter.GetInstance(doc, stream);
    
    سپس در پایان کار، برای دانلود PDF ایجاد شده در حافظه، ابتدا آن را به یک بافر منتقل میکنیم، و سپس با استفاده از شئ Response محتوای بافر را مستقیما به کلاینت میفرستیم. در صورتی که بخواهیم فایل حتما دانلود شود و در مرورگر کاربر باز نشود، می توانیم با استفاده از هدر content-disposition این موضوع را به مرورگر اطلاع دهیم. در این صورت حتی در صورت نصب بودن پلاگین مشاهده PDF بر روی مرورگر، بازهم صفحه دانلود فایل باز خواهد شد.
                byte[] buffer = stream.GetBuffer();
                stream.Close();
    
                Response.ClearContent();
                Response.AddHeader("content-disposition", "attachment; filename=test.pdf");
                Response.ContentType = "application/pdf";
                Response.OutputStream.Write(buffer, 0, buffer.Length);
                Response.OutputStream.Flush();
                Response.OutputStream.Close();
                Response.End();
    


    مثال

    در پایان یک مثال از مطالب مطرح شده در این مقال ضمیمه شده است. در این ضمیمه، فایل itextsharp.dll نیز وجود دارد و برای اجرای مستقیم آن نیاز به ابزار خاص دیگری ندارد.

    بروزرسانی

    به خاطر درخواست دوستان، یک نمونه ساده از شیوه گرفتن خروجی PDF از GridView اضافه کردم. بزودی یک مثال کاملتر به همراه توضیح کد در یک پست جدید ارایه خواهم داد ولی تا موقعی که فرصت این کار را پیدا کنم، میتوانید از این مثال ساده که در این پست ضمیمه کردم استفاده کنید.

    بروزرسانی 2

    کتابخانه ای برای گرفتن خروجی PDF از GridView تهیه کرده ام که از اینجا میتوانید آن را مشاهده کنید.
    ضمیمهاندازه
    iTextSharpFarsi.zip1.15 مگابایت
    نمونه ساده خروجی PDF از GridView1.09 مگابایت

نظرات

pdf

سلام مهندس جان
قربان دست و پنجت
فقط اینو بدون که این تیکه کدت توی یه پروژه ملی و بزرگ در خصوص مسکن بکار رفت
مرسی

خروجی گرفتن از کل صفحه

سلام مهندس جان
امروز در یکی از پروژه ها نیاز شد که تمام اطلاعات موجود در صفحه را به صورت pdf ذخیره کنم - از این رو از صبح در پی روشی بودم که این کار را انجام بده. درواقع به جای استفاده کردن از گزارشها در یک صفحه جدید اطلاعات را در لیست ویو و تعدادی لیبل و چند چارت (نمودار های استاندارد دات نت 4 ) و چند تصویر نمایش میده - از کد زیر استفاده کردم :
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
StringWriter stringWriter = new StringWriter();

HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);

this.RenderControl(htmlTextWriter);
Response.Write(stringWriter.ToString());
Response.End();

در واقع این روش شاید آسان ترین و بی مشکل ترین روشی بود که به آن رسیدم - تمام صفحه بدون در نظر گرفتن مسائل دیگه با استایل و رنگ ها البته متون فارسی با تعریف یونی کد و فنت درست میشه همه و همه مرتب ذخیره میشود و کاربر می تواند آن را دانلود کند بدون ایجاد فایل فیزیکی در هاست - منتهی مشکل اصلی این است که تصاویر و نمودارها ذخیره نمی شود - یا فکر می کنم لینک آنها در فایل ذخیر می شود -

روش را تغییر دادم و گفتم از itext استفاده بکنم
منتهی آیا روشی هست که با itext کل صفحه در pdf ذخیره شود ؟

ممنون

آقا واقعا ممنون
نمیدونید چقدر دنبال این بودم که چطور میشه با itextSharp متن فارسی تولید کرد

استفاده در دات نت نیوک

با سلام من وقتی مثال شما را به صورت یک برنامه جداگانه باز می کنم مشکلی نیست اما وقتی در دات نت نیوک از آن استفاده می کنم این خطا را می گیرم :
Request for the permission of type 'System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed
ممنون می شوم اگر راهنمایی کنید

مشکل با متون فارسی طولانی

با عرض سلام

من این پروژه رو با یک متن فارسی طولانی یا بهتر بگم چند صفحه ای امتحان کردم اما اشکالی که وجود داره اینه که پی دی اف تولید شده فقط یک صفحه است. اگه ممکنه بگین اشکال از کجاست و راه حلش چیه؟

با تشکر

تصویر مهدی

مشکل با متون فارسی طولانی

سلام،
در صورتی که متن شما چند صفحه باشه، راحت تره که بجای استفاده از ColumnText از PdfPTable استفاده کنید تا در صورتی که متن طولانی شد، خودش به صفحه بعدی بره.

از بین رفتن محتویات Html table در هنگام استفاده از PdfPTable

با سلام و تشکر از مقاله مفید شما
برنامه من یک فایل html رو با این ابزار به Pdf تبدیل میکنه
چون ممکن است متن فایل html طولانی بشه از PdfPTable استفاده کردم
اما مشکلی که بوجود میاد، از بین رفتن تگهای table است که در فایل html به کار رفته. در واقع اگر از PdfPTable استفاده کنیم دیگر نمیتوانیم جداول Html رو در فایل Pdf بزاریم.

لطفا جهت حل این مشکل راهنمایی بفرمایید

Table Tag

سلام دوست عزیز
سوال من در مورد اینه که آیا این کامپوننت میتونه تگ جدول HTML (Table) را هم تفسیر کنه یا با این تگ دچار مشکل می شود؟
با تشکر

تصویر مهدی

تبدیل از HTML

سلام،

اصولا iTextSharp (و iText) برای تبدیل فرمتهای دیگه به HTML ساخته نشده و هدف ایجاد PDF از پایه بوده. البته با استفاده از کلاس HtmlWorker موجود در iTextSharp میشه در حالت خیلی خیلی ساده تبدیل HTML به PDF رو انجام داد که متاسفانه برای متون راست به چپ (مثل فارسی) درست کار نمیکنه (که البته میشه تا حدودی درستش کرد)
حالا با توجه به این مطالب، اگر منظور شما ایجاد PDF باشه، ایجاد جدول به طور کامل پشتیبانی میشه ولی اگر منظور تبدیل HTML به PDF باشه، این کار ممکنه ولی بدون مشکل نخواهد بود.

تبدیل Html شامل گریدویو

با تشکر فراوان لطفا در مورد تبدیل Html که شامل 1 گریدویو نیز به pdf هست راهنمایی بفرمایین.

تصویر مهدی

تبدیل Html شامل گریدویو

در حالت کلی تبدیل Html به PDF فرآیند پیچیده ای داره که iTextSharp به طور خیلی محدود فقط برای Htmlهای چپ به راست میتونه این کار رو انجام بده.

کمک بیشتر

با تشکر از برنامه بسیار مفیدتان.
از حضورتان تقاضا دارم اگر ممکن است یک مثال از طرز کار با HtmlWorker را در سایت قرار دهید.

تصویر مهدی

HtmlWorker

ممنون از پشنهادتون،
این کار رو حتما به زودی انجام خواهم داد.

help

با تشکر از راهنماییتون. من دارم از کریستال ریپورت برای گزارش گیری استفاده می کنم. در دات نت 2008 . مشکلات زیادی با فونتهای فارسی دارم . اگه ممکنه راهنماییم کنین. ممنون میشم

تصویر مهدی

کریستال ریپورت

متاسفانه من در مورد کریستال ریپورت تجربه زیادی ندارم و در این مورد نمیتونم کمکتون کنم.

فونت فارسی

سلام با تشکر از مطالبتون
من در pdf از فونت فارسی Nazanin استفاده کردم که باعث شد تا حروف انگلیسی نمایش داده نشوند می خواستم بدانم برای رفع مشکل چه کنم
قبلا متشکرم

تصویر مهدی

فونت فارسی

ممنون از نظرتون.
همونطور که خودتون هم احتمالا حدس زدین، در اکثر فونتهای فارسی (مثل Nazanin) فقط حروف فارسی تعریف شده و بنابراین برای استفاده از این فونتها، باید حتما یک فونت هم به عنوان فونت دوم تعریف کنید تا برای حروفی که در فونت اول تعریف نشده، از فونت دوم استفاده بشه. این کار با استفاده از FontSelector امکان پذیره. به عنوان نمونه این جوری میتونید ازش استفاده کنید.

            FontSelector fontSelector = new FontSelector();
            fontSelector.AddFont(font1);
            fontSelector.AddFont(font2);
            Phrase phrase = fontSelector.Process("sample text");

مشکل با متون فارسی طولانی

با عرض سلام

من این پروژه رو با یک متن فارسی طولانی یا بهتر بگم چند صفحه ای امتحان کردم اما اشکالی که وجود داره اینه که پی دی اف تولید شده فقط یک صفحه است. اگه ممکنه بگین اشکال از کجاست و راه حلش چیه؟

با تشکر

سلام من خواستم از همین جا

سلام
من خواستم از همین جا ازتون تشکر کنم و بگم که خیلی از این مطلبتون استفاده کردم
خیلی دنباله همچین چیزی می گشتم
خیلی خیلی ممنون

مهدي عزيز

سلام ، ممنونم ان شاءاله كه بزودي فرصت كنيد و ما رو هم خوشحال كنيد ، ضمناً آدرس سايت شما رو جهت اطلاع بروبچ ايميل كردم(دستمريزاد)

خروجي PDF از GridView

سلام و خسته نباشيد .

كار جالبي بود ولي فقط اگر Gridview كه مي خواد Render بشه به PDF بتواند حالت ها ، رنگ‌ها و سايز را حفظ كنه خيلي بدرد مي‌خوره مثل خروجي به Excel هرچند كه كار سختيه و لي اميدوارم شما اين كارو تو نسخه بعدي انجام بدين...خدا نگه دار...

تصویر مهدی

خروجی با استایل

در حقیقت این کار رو قبلا انجام دادم و جایی که براش این کد رو نوشتم، تا حالا خیلی به دردشون خورده. ولی چون اجازه انتشار اون کد رو ندارم، نمیتونم اینجا ارایه بدم و مجبورم دوباره کد رو از اول بنویسم.
پست بعدی که در مورد iTextSharp میخوام بنویسم، دقیقا همین موضوع هست که شما گفتید، ولی متاسفانه هنوز وقت این کار رو پیدا نکردم.

تقدير و تشكر

مهدي عزير از لطف و توجهات شما سپاسگزارم اميدوارم هميشه شاد و شاد و شاد باشي.

تصویر مهدی

نمونه ساده خروجی از GridView

قول داده بودم که طرز خروجی گرفتن از GridView رو توضیح بدم ولی وقت نکردم. برای این که بدقول نشم، فعلا یک مثال ساده آماده کردم و اینجا ضمیمه کردم. فعلا این رو بررسی کنید (خیلی ساده است).
انشالله سر فرصت اولین مطلبی که تو سایت خواهم گذاشت، یک مثال کاملتر به همراه توضحیات خواهد بود.

ممنونم از مطلب خوبتون

ضمن سلام و خسته نباشيد من از مطلب شما استفاده كردم خيلي مفيد بود ولي اگه در خصوص گريد ويو هم توضيح بدبد ممنون ميشم.نازنين ابراهيمي

GridView Farsi Export To Pdf

سلام مهدي عزيز...

همانطور كه خودتون عرض كرديد يكي از سئوالات متداول برنامه نويسان گرفتن خروجي GridView فارسي به Pdf مي‌باشد بنده هم برنامه نويس وب هستم و اين مشكلو نيز دارم اگر بزرگواري كنيد و يك نمونه معرفي كنيد ممنون مي‌شم.ضمناً از مطالب علمي كه مي‌نويسيد كمال تشكر را دارم-- فرهاد

تصویر مهدی

خروجی GridView به PDF

سلام،
فکر کنم تا 2-3 روز دیگه (اگر وقت کنم) یک مطلب در این مورد بنویسم. هرچند اصول کار همینه ولی چون سوال متداولیه، بد نیست به طور خاص روش بحث بشه.

Export GridView To Pdf

سلام
آقاي هاشمي نژاد من از كد شما استفاده كردم و مشكلي نداشت ولي من مي‌خوام Gridview رو به Pdf تبديل كنم و فونت فارسي رو نيز پشتيباني كنه چونكه كدهاي زيادي تو اينترنت هستند كه با فونت فارسي مشكل دارند اگر لطف كنيد در مطالبتون اين كار رو آموزش بديد ممنو.ن مي‌شم.(عباس حامدي دوست اميد)

iTextSharpFarsi

سلام
اگر لطف كنيد روش Export GridView To Pdf را آموزش دهيد ممنون ميشيم.ضمناً از مطالب خوبتون ممنويم

iTextSharpFarsi

سلام
مهندس عزيز ما شديداً نياز به Export to Pdf داريم اگه وقت داريد لينك آنرو بروزرساني كنيد و يك حالي به بروبچه ها بديد.سپاسگزارم.(اميد)

convert text to pdf

سلام expotrtoPdf .dll فارسی رو ساپورت نمی کنه. میشه فایل help ٰ
iTextSharp رو بذازین.چطور میتونم 1 فایل pdf با button توی 1 لینک جدید باز کنم؟ مبشه کمکم کنید. چطور میشه وقتی grid view رو تبدیل به pdf میکنیم عنوان ستون ها رو فارسی کنیم ؟
راستی مطالبتون و فایل ضمیمه عالی بود بی نهایت متشکرم

تشکر و قدردانی

من از حضرتعالی تشکر می کنم و امید وارم موفق باشید در صورت امکان شماره تماس را ایمیل فرمایید برای همکاری آشنا شویم
amir

تبدیل pdf فارسی به text

سلام
من میخواستم بپرسم تا حالا تست کردید که با itext فایل pdf فارسی رو تبدیب کنید به text
مرسی

تصویر مهدی

تبدیل pdf فارسی به text

سلام،
نه. متاسفانه تا بحال در این مورد کاری انجام نداده‌ام.