iTextSharp و استفاده از قلم‌های محدود فارسی
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: دو دقیقه


عموما قلم‌های فارسی، خصوصا مواردی که با B شروع می‌شوند مانند B Zar و امثال آن، فاقد تعاریف حروف مرتبط با glyphs الفبای انگلیسی است. نتیجه این خواهد شد که اگر متن شما مخلوطی از کلمات و حروف فارسی و انگلیسی باشد، فقط قسمت فارسی نمایش داده می‌شود و از قسمت انگلیسی صرفنظر خواهد شد. مرورگرها در این حالت هوشمندانه عمل می‌کنند و به یک قلم پیش فرض مانند Times و همانند آن جهت نمایش اینگونه متون مراجعه خواهند کرد؛ اما اینجا چنین اتفاقی نخواهد افتاد.
برای حل این مشکل، کلاسی به نام FontSelector در کتابخانه‌ی iTextSharp وجود دارد. مثالی در این رابطه:

using System.Diagnostics;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace HeadersAndFooters
{
class Program
{
static void Main(string[] args)
{
using (var pdfDoc = new Document(PageSize.A4))
{
PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
pdfDoc.Open();

FontFactory.Register("c:\\windows\\fonts\\bzar.ttf");
Font bZar = FontFactory.GetFont("b zar", BaseFont.IDENTITY_H);

FontFactory.Register("c:\\windows\\fonts\\tahoma.ttf");
Font tahoma = FontFactory.GetFont("tahoma", BaseFont.IDENTITY_H);

FontSelector fontSelector = new FontSelector();

//قلم اصلی
if (bZar.Familyname != "unknown")
{
fontSelector.AddFont(bZar);
}

//قلم پیش فرض در صورت نبود تعاریف مناسب در قلم اصلی
if (tahoma.Familyname != "unknown")
{
fontSelector.AddFont(tahoma);
}

var table1 = new PdfPTable(1);
table1.WidthPercentage = 100;
table1.RunDirection = PdfWriter.RUN_DIRECTION_RTL;

var pdfCell = new PdfPCell { RunDirection = PdfWriter.RUN_DIRECTION_RTL, Border = 0 };
pdfCell.Phrase = fontSelector.Process("نمایش مخلوطی از متن فارسی و English با هم توسط قلمی که کاراکترهای انگلیسی را پشتیبانی نمی‌کند");

table1.AddCell(pdfCell);
pdfDoc.Add(table1);

}

//open the final file with adobe reader for instance.
Process.Start("Test.pdf");
}
}
}

در این مثال از قلم B Zar استفاده شده است. اولین قلمی که به یک FontSelector اضافه می‌شود، قلم اصلی خواهد بود. قلم‌ بعدی اضافه شده، قلم پیش فرض نام خواهد گرفت؛ به این معنا که در مثال فوق اگر قلم B Zar توانایی نمایش حرف جاری را داشت که خیلی هم خوب، در غیراینصورت به قلم بعدی مراجعه خواهد کرد و همینطور الی آخر. بنابراین این ترتیب اضافه کردن قلم‌ها به FontSelector مهم است. نحوه استفاده نهایی از FontSelector تعریف شده هم در قسمت pdfCell.Phrase = fontSelector.Process مشخص است.



  • #
    ‫۱۳ سال و ۱ ماه قبل، چهارشنبه ۲۳ شهریور ۱۳۹۰، ساعت ۰۳:۵۸
    سلام آقای مهندس
    شما برای نمایش PDF در سایت چه روشی رو پیشنهاد میدید؟ نمایش در مرورگر ، دانلود فایل و...
  • #
    ‫۱۳ سال و ۱ ماه قبل، چهارشنبه ۲۳ شهریور ۱۳۹۰، ساعت ۰۴:۱۱
    روش متداول، نصب Adobe reader در سمت کاربر است. اکتیوایکس آن سال‌ها است که با اکثر مرورگرها کار می‌کند و امکان مشاهده فایل pdf را درون خود مرورگر به صورت یکپارچه میسر کرده.
    https://www.dntips.ir/2011/07/pdf-winforms-wpf.html
  • #
    ‫۱۱ سال و ۴ ماه قبل، شنبه ۱۱ خرداد ۱۳۹۲، ساعت ۱۹:۳۸
    با سلام
    می‌خواستم برای حل این مشکل در RDLC چه راهی وجود داره
    چون من تمام گزارشات سیستم رو با این ساختم و کلی دردسر برای ساختش کشیدم
    البته یه راه حل گیر آوردم و این بود که اومدم با یه نرم افزار فونت هایی که می‌خواستم را ویرایش کردم و مثلا قسمت‌های تعاریف حروف مرتبط با glyphs الفبای انگلیسی را خودم از یه فونت دیگه مثل تایم اضافه کردم عملی هم بود ولی ساخت هر فونت با مشتقاتش 5-6 ساعت وقت میگیره
    با تشکر

    • #
      ‫۱۱ سال و ۴ ماه قبل، شنبه ۱۱ خرداد ۱۳۹۲، ساعت ۲۱:۰۴
      با توجه به غیرسورس باز بودن PDF سازی که یاد کردید، بجز ویرایش فونت و افزودن دستی glyphs مفقود در آن‌ها، راه دیگری وجود ندارد. در iTextSharp برای اینکار FontSelector طراحی شده. طراحان گزارش ساز مدنظر شما هم باید چنین کاری رو انجام بدن و اضافه کنند. ضمن اینکه در iTextSharp هم اگر کسی این نکته رو ندونه، به صورت پیش فرض از FontSelector استفاده نمیشه و مدتی سردرگم خواهد بود.
      در PdfReport این مسایل به صورت توکار در همه جا اعمال شده و استفاده کننده با خیلی از جزئیات و نکات ریز درگیر نخواهد شد.
  • #
    ‫۱۱ سال و ۴ ماه قبل، سه‌شنبه ۲۱ خرداد ۱۳۹۲، ساعت ۱۲:۴۶
    با سلام
    چون من از HTMLWorker استفاده می‌کنم و به کمک کد زیر فونت BNazanin را بکار گرفتم
    styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.FONTFAMILY, "BNazanin");
    لازم بود تا کلمات انگلیسی هم نمایش داده شوند در نتیجه از فونت کامل tahoma بایستی استفاده می‌کردم.اما این فونت مورد پسند نیست. در نتیجه از روش زیر (که شاید هم نا متعارف باشد) استفاده کردم

    1.ابتدا استایل زیر را اضافه نمودم
    styles.LoadStyle("english", HtmlTags.FONTFAMILY, "tahoma");
    2.و سپس تمامی کلمات انگلیسی را به کمک کد زیر یافته و استایل english را به آن نسبت دادم
                var cleanTagsContent = Regex.Replace(content, @"<[^>]*>", String.Empty);
                var regex = new Regex("[a-zA-Z0-9]*");
                foreach (var word in cleanTagsContent.Split(' '))
                    if (regex.Match(word).Value == word && word.Length > 0)
                    {
                        content = content.Replace("<" + word, "#!#");
                        content = content.Replace(word + ">", "#^#");
    
                        content = content.Replace(word, string.Format("<span class='english'>{0}</span>", word));
    
                        content = content.Replace("#!#", "<" + word);
                        content = content.Replace("#^#", word + ">");
                    }





    نکته : کدهای به صورت زیر را برای زمانی گذاشتیم که کلمه انگلیسی شامل td,table,div,... باشد

    content = content.Replace("<" + word, "#!#");
    باز هم مرا به خاطر این کار نامتعارف ببخشید :)


  • #
    ‫۹ سال و ۴ ماه قبل، پنجشنبه ۷ خرداد ۱۳۹۴، ساعت ۱۶:۲۵
    یک نکته‌ی تکمیلی
    اگر از PDF Report استفاده می‌کنید، نکته‌ی FontSelector فوق، به صورت توکار در آن لحاظ شده‌است. بنابراین اولین قلم را در اینجا یک قلم فارسی تعریف کنید:
                .DefaultFonts(fonts =>
                {
                    fonts.Path(System.IO.Path.Combine(AppPath.ApplicationPath, "fonts\\irsans.ttf"),
                               System.IO.Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), "fonts\\verdana.ttf"));
                    fonts.Size(9);
                    fonts.Color(System.Drawing.Color.Black);
                })
    و دومین قلم را یک قلم کامل انگلیسی. این دو مورد مکمل هم خواهند شد؛ چون قلم فارسی استفاده شده، گلیف‌های انگلیسی را ندارد.