شرح یک سری سعی و خطا!
سعی اول:
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace iTextSharpTests
{
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();
var chunk = new Chunk("آزمایش");
pdfDoc.Add(chunk);
}
}
}
}
نتیجه:
بله! هیچی!
مشکل از کجاست؟
در iTextSharp بر اساس نوع فونت انتخابی و encoding مرتبط، نحوهی رندر سازی حروف مشخص میشود:
همانطور که ملاحظه میکنید، فونت پایه متنی که قرار است اضافه شود، null است.
سعی دوم:
اینبار فونت را تنظیم میکنیم:
using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace iTextSharpTests
{
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();
var fontPath = Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf";
var baseFont = BaseFont.CreateFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
var tahomaFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.BLACK);
var chunk = new Chunk("آزمایش",tahomaFont);
pdfDoc.Add(chunk);
}
}
}
}
توضیحات:
متد BaseFont.CreateFont میتواند مسیری از فونت مورد نظر را دریافت کند. این حالت خصوصا برای برنامههای وب که ممکن است فونت مورد نظر آنها در سرور نصب نشده باشد، بسیار مفید است و لزومی ندارد که الزاما فونت مورد استفاده در پوشه fonts ویندوز نصب شده باشد.
نکات مهم دیگر بکار گرفته شده در این متد، استفاده از BaseFont.IDENTITY_H و BaseFont.EMBEDDED است. به این صورت encoding متن، جهت نوشتن متون غیر Ansi تنظیم میشود و در این حالت حتما باید فونت را در فایل، مدفون (embed) نمود. از این لحاظ که عموما این نوع فونتها در سیستمهای کاربران نصب نیستند.
نتیجه:
بد نیست! حداقل حروف نمایش داده شدند؛ اما نیاز است تا چرخانده یا معکوس شوند. برای انجام خودکار آن حداقل دو کار را میتوان انجام داد.
الف) استفاده از ColumnText و اعمال تنظیمات راست به چپ آن
using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace iTextSharpTests
{
class Program
{
static void Main(string[] args)
{
using (var pdfDoc = new Document(PageSize.A4))
{
var pdfWriter = PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
pdfDoc.Open();
var fontPath = Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf";
var baseFont = BaseFont.CreateFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
var tahomaFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.BLACK);
ColumnText ct = new ColumnText(pdfWriter.DirectContent);
ct.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
ct.SetSimpleColumn(100, 100, 500, 800, 24, Element.ALIGN_RIGHT);
var chunk = new Chunk("آزمایش", tahomaFont);
ct.AddElement(chunk);
ct.Go();
}
}
}
}
توضیحات:
در اینجا یک ColumnTex جدید تعریف و سپس خصوصیات این ستون تنظیم شده، به همراه RunDirection آن که اصل قضیه است. سپس chunk تعریف شده را به این ستون اضافه کردهایم.
نتیجه:
بله! کار کرد!
ب) استفاده از PdfTable و اعمال تنظیمات راست به چپ آن
using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace iTextSharpTests
{
class Program
{
static void Main(string[] args)
{
using (var pdfDoc = new Document(PageSize.A4))
{
var pdfWriter = PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
pdfDoc.Open();
var fontPath = Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf";
var baseFont = BaseFont.CreateFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
var tahomaFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.BLACK);
PdfPTable table = new PdfPTable(numColumns: 1);
table.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
table.ExtendLastRow = true;
PdfPCell pdfCell = new PdfPCell(new Phrase("آزمایش", tahomaFont));
pdfCell.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
table.AddCell(pdfCell);
pdfDoc.Add(table);
}
}
}
}
در حین استفاده از PdfTable هم لازم است تا RunDirection مربوط به خود جدول و همچنین هر سلول اضافه شده به آن به RTL تنظیم شوند.
این نکات در هر جایی که با این کتابخانه سر و کار داریم باید اعمال شوند. برای مثال:
افزودن Header به صفحات Pdf :
افزودن header در نگارشهای جدید iTextSharp شامل نکته استفاده از کلاس PdfPageEventHelper به شرح زیر است (و مثالهایی را که در وب پیدا خواهید کرد، هیچکدام با آخرین نگارش موجود iTextSharp کار نمیکنند):
using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace iTextSharpTests
{
public class PageEvents : PdfPageEventHelper
{
Font _font;
public PageEvents()
{
var fontPath = Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf";
var baseFont = BaseFont.CreateFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
_font = new Font(baseFont, 10, Font.NORMAL, BaseColor.BLACK);
}
public override void OnStartPage(PdfWriter writer, Document document)
{
base.OnStartPage(writer, document);
PdfPTable table = new PdfPTable(numColumns: 1);
table.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
PdfPCell pdfCell = new PdfPCell(new Phrase("سر صفحه در صفحه: " + writer.PageNumber, _font));
pdfCell.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
pdfCell.HorizontalAlignment = Element.ALIGN_CENTER;
table.AddCell(pdfCell);
document.Add(table);
}
}
class Program
{
static void Main(string[] args)
{
using (var pdfDoc = new Document(PageSize.A4))
{
var pdfWriter = PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
pdfWriter.PageEvent = new PageEvents();
pdfDoc.Open();
var fontPath = Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf";
var baseFont = BaseFont.CreateFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
var tahomaFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.BLACK);
PdfPTable table = new PdfPTable(numColumns: 1);
table.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
table.ExtendLastRow = true;
PdfPCell pdfCell = new PdfPCell(new Phrase("آزمایش", tahomaFont));
pdfCell.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
table.AddCell(pdfCell);
pdfDoc.Add(table);
pdfDoc.NewPage();
}
}
}
}
نتیجه:
تنها نکتهای که اینجا اضافه شده، تعریف کلاس PageEvents است که از کلاس PdfPageEventHelper مشتق شده است. در این کلاس میتوان یک سری متد کلاس پایه را تحریف کرد و header و footer و غیره را اضافه نمود. سپس جهت اضافه کردن آن، pdfWriter.PageEvent باید مقدار دهی شود.
در اینجا هم اگر نوع فونت، encoding و PdfTable به همراه RunDirection آن اضافه نمیشد، یا چیزی در header صفحه قابل مشاهده نبود یا متن مورد نظر معکوس نمایش داده میشد.