استفاده از PDF در پروژه های ASP.NET CORE
برای توسعهدهندگان ASP.NET Core، ابزارها و کتابخانههای متعددی برای این منظور وجود دارد. بسیاری از این کتابخانهها مانند IronPDF، Syncfusion، و Telerik امکانات فوقالعادهای را ارائه میدهند، اما تجاری بوده و نیازمند خرید لایسنس هستند که میتواند برای پروژههای کوچک یا تیمهای با بودجه محدود، یک مانع بزرگ باشد.
خوشبختانه، جامعه متن-باز (Open-Source) راهحلهای رایگان و قدرتمندی را نیز فراهم کرده است که به توسعهدهندگان اجازه میدهد بدون هیچ هزینهای، قابلیت تولید PDF را به اپلیکیشنهای ASP.NET Core خود اضافه کنند. در این مقاله، به بررسی جامع و عملی چندین روش محبوب برای ساخت PDF در ASP.NET Core با استفاده از کتابخانههای رایگان میپردازیم و مزایا و معایب هرکدام را تشریح خواهیم کرد.
روش اول: استفاده از کتابخانه QuestPDF (رویکرد مدرن و روان)
QuestPDF یک کتابخانه مدرن و متن-باز برای .NET است که با یک API روان (Fluent API) و مبتنی بر کد، به شما اجازه میدهد اسناد PDF را به صورت اعلانی (Declarative) طراحی کنید. این رویکرد شباهت زیادی به طراحی UI در فریمورکهایی مانند Flutter دارد و به شما امکان میدهد ساختار سند خود را به صورت سلسلهمراتبی و خوانا تعریف کنید.
چرا QuestPDF؟
-
API مدرن و خوانا: کدنویسی با QuestPDF بسیار لذتبخش و ساده است. به جای کار با مختصات X و Y، شما با مفاهیمی مانند ستون، ردیف، پدینگ و کانتینر کار میکنید.
-
پیشنمایش زنده: یکی از قابلیتهای برجسته QuestPDF، امکان پیشنمایش زنده سند در حین توسعه است که فرآیند طراحی را بسیار سرعت میبخشد.
-
پشتیبانی کامل از .NET: این کتابخانه با نسخههای مختلف .NET از جمله .NET Core و .NET 5/6/7/8 سازگاری کامل دارد.
-
عملکرد بالا: QuestPDF با تمرکز بر بهینهسازی و مدیریت حافظه، عملکرد بسیار خوبی در تولید اسناد حتی با حجم بالا دارد.
-
رایگان برای استفاده تجاری: این کتابخانه تحت لایسنس MIT منتشر شده و استفاده از آن در پروژههای تجاری کاملاً رایگان است.
پیادهسازی گام به گام با QuestPDF
قدم اول: نصب پکیج
ابتدا پکیج NuGet مربوط به QuestPDF را در پروژه ASP.NET Core خود نصب کنید:
dotnet add package QuestPDF
قدم دوم: ساخت کلاس سند
یک کلاس جدید برای تعریف ساختار سند PDF خود ایجاد کنید. این کلاس باید اینترفیس IDocument را پیادهسازی کند.
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
public class InvoiceDocument : IDocument
{
// میتوانید دادههای مورد نیاز برای فاکتور را از طریق سازنده دریافت کنید
public InvoiceDocument() { }
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
public void Compose(IDocumentContainer container)
{
container
.Page(page =>
{
page.Margin(50);
page.Header().Element(ComposeHeader);
page.Content().Element(ComposeContent);
page.Footer().AlignCenter().Text(x =>
{
x.Span("Page ");
x.CurrentPageNumber();
});
});
}
void ComposeHeader(IContainer container)
{
container.Row(row =>
{
row.RelativeItem().Column(column =>
{
column.Item().Text("فاکتور فروش").SemiBold().FontSize(20);
column.Item().Text("شماره فاکتور: 12345");
column.Item().Text("تاریخ: 1403/07/04");
});
row.ConstantItem(100).Height(50).Placeholder(); // لوگو
});
}
void ComposeContent(IContainer container)
{
container.PaddingVertical(40).Column(column =>
{
column.Spacing(20);
column.Item().Text("اینجا محتوای اصلی فاکتور، جدول محصولات و قیمتها قرار میگیرد.");
// در اینجا میتوانید یک جدول برای محصولات اضافه کنید
// ...
});
}
}
قدم سوم: تولید PDF در کنترلر
حالا در یک اکشن کنترلر، یک نمونه از سند خود ساخته و آن را به صورت یک فایل PDF به کاربر برگردانید.
using Microsoft.AspNetCore.Mvc;
using QuestPDF.Fluent;
[ApiController]
[Route("[controller]")]
public class InvoiceController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var document = new InvoiceDocument();
var pdfBytes = document.GeneratePdf();
return File(pdfBytes, "application/pdf", "invoice.pdf");
}
}
با اجرای این کد و فراخوانی آدرس /invoice/generate، یک فایل PDF ساده تولید و دانلود میشود. QuestPDF برای طراحیهای پیچیدهتر مانند جداول، لیستها، تصاویر و کامپوننتهای قابل استفاده مجدد، امکانات بسیار گستردهای را فراهم میکند.
روش دوم: استفاده از کتابخانههای PdfSharp و MigraDoc (رویکرد کلاسیک و قدرتمند)
PdfSharp و MigraDoc دو کتابخانه متن-باز بسیار قدیمی و شناختهشده در اکوسیستم .NET هستند که سالهاست برای تولید PDF استفاده میشوند.
-
PdfSharp: یک کتابخانه سطح پایین است که به شما اجازه میدهد با اشیاء پایهای PDF مانند صفحات، گرافیکها و فونتها به صورت مستقیم کار کنید. این کتابخانه برای کارهایی مانند ترسیم اشکال، نوشتن متن در موقعیتهای دقیق و دستکاری اسناد PDF موجود، ایدهآل است.
-
MigraDoc Foundation: یک کتابخانه سطح بالا است که بر روی PdfSharp ساخته شده و یک مدل شیءگرای سند (Document Object Model) ارائه میدهد. با MigraDoc شما به جای کار با گرافیک، با مفاهیمی مانند پاراگراف، جدول، بخش (Section) و استایل کار میکنید که فرآیند ساخت اسناد متنی را بسیار سادهتر میکند.
چرا PdfSharp/MigraDoc؟
-
کنترل کامل: PdfSharp به شما کنترل دقیقی بر روی تمام جزئیات سند میدهد.
-
بلوغ و پایداری: این کتابخانهها سالهاست که توسعه داده شده و در پروژههای بیشماری استفاده شدهاند.
-
رایگان: هر دو کتابخانه تحت لایسنس MIT منتشر شده و کاملاً رایگان هستند.
-
انعطافپذیری: ترکیب این دو کتابخانه به شما اجازه میدهد هم اسناد ساختاریافته و هم اسنادی با طراحیهای گرافیکی سفارشی ایجاد کنید.
پیادهسازی گام به گام با MigraDoc
قدم اول: نصب پکیج
برای کار با MigraDoc، باید پکیج مربوط به آن را نصب کنید. توجه داشته باشید که نسخههای سازگار با .NET Core توسط جامعه توسعه داده شدهاند.
dotnet add package PdfSharp.MigraDoc.Core
قدم دوم: ساخت سند با MigraDoc
کد زیر نحوه ساخت یک سند ساده با یک عنوان و یک پاراگراف را نشان میدهد.
using MigraDocCore.DocumentObjectModel;
using MigraDocCore.Rendering;
public class MigraDocGenerator
{
public byte[] CreateSimplePdf()
{
// 1. Create a new document
Document document = new Document();
document.Info.Title = "سند تستی MigraDoc";
document.Info.Author = "Gemini";
// 2. Add a section
Section section = document.AddSection();
// 3. Add a paragraph for the title
Paragraph title = section.AddParagraph("گزارش نمونه");
title.Format.Font.Size = 20;
title.Format.Font.Bold = true;
title.Format.Alignment = ParagraphAlignment.Center;
title.Format.SpaceAfter = "1cm";
// 4. Add a content paragraph
Paragraph paragraph = section.AddParagraph();
paragraph.AddText("این یک پاراگراف نمونه است که با استفاده از کتابخانه MigraDoc در ASP.NET Core ساخته شده است. این کتابخانه امکانات خوبی برای ساخت اسناد متنی فراهم میکند.");
paragraph.Format.Font.Name = "Arial"; // توجه: فونت باید در دسترس باشد
paragraph.Format.Alignment = ParagraphAlignment.Right;
// 5. Render the document
var renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
// 6. Save the document to a memory stream
using (var stream = new System.IO.MemoryStream())
{
renderer.PdfDocument.Save(stream);
return stream.ToArray();
}
}
}
قدم سوم: استفاده در کنترلر
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]")]
public class ReportController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var generator = new MigraDocGenerator();
var pdfBytes = generator.CreateSimplePdf();
return File(pdfBytes, "application/pdf", "report.pdf");
}
}
نکته مهم: کار با فونتهای فارسی در PdfSharp/MigraDoc نیازمند تنظیمات بیشتری است. شما باید فایل فونت (مثلاً Vazir.ttf) را در پروژه خود قرار داده و آن را به صورت دستی بارگذاری و استفاده کنید که این موضوع میتواند کمی چالشبرانگیز باشد.
روش سوم: تبدیل HTML به PDF با Puppeteer Sharp (رویکرد مبتنی بر مرورگر)
این روش رویکردی کاملاً متفاوت دارد. به جای ساخت سند PDF از پایه، شما ابتدا یک صفحه HTML با استفاده از CSS و دادههای داینامیک خود طراحی میکنید (مثلاً با استفاده از Razor Pages یا یک موتور رندرینگ دیگر) و سپس از یک مرورگر بدون رابط کاربری (Headless Browser) برای "چاپ" این صفحه به صورت PDF استفاده میکنید.
Puppeteer Sharp یک پورت .NET از کتابخانه محبوب Puppeteer برای Node.js است که به شما اجازه میدهد مرورگر Chromium (موتور اصلی گوگل کروم) را به صورت برنامهنویسی کنترل کنید.
چرا تبدیل HTML به PDF؟
-
سهولت در طراحی: شما میتوانید از تمام قدرت HTML و CSS برای طراحی ظاهر سند خود استفاده کنید. این روش برای توسعهدهندگان وب بسیار آشنا و راحت است.
-
پشتیبانی کامل از استایلهای پیچیده: هر طرحی که در مرورگر قابل نمایش باشد، قابل تبدیل به PDF نیز هست، از جمله نمودارها، انیمیشنهای CSS (در لحظه رندر) و فونتهای سفارشی.
-
پشتیبانی عالی از زبان فارسی: از آنجایی که مرورگرها به خوبی از زبان فارسی و راستچیننویسی پشتیبانی میکنند، چالشهای مربوط به فونت و چیدمان به سادگی حل میشود.
-
دقت بالا: خروجی PDF دقیقاً همان چیزی خواهد بود که در مرورگر مشاهده میکنید.
پیادهسازی گام به گام با Puppeteer Sharp
قدم اول: نصب پکیج
dotnet add package PuppeteerSharp
قدم دوم: دانلود مرورگر
Puppeteer Sharp برای کار کردن نیاز به یک نسخه از Chromium دارد. اولین بار که برنامه را اجرا میکنید، این کتابخانه به صورت خودکار نسخه مورد نیاز را دانلود میکند. این فرآیند ممکن است کمی زمانبر باشد.
قدم سوم: تبدیل HTML به PDF در کد
فرض کنید یک اکشن در کنترلر دارید که یک صفحه HTML (مثلاً یک فاکتور) را با استفاده از Razor View Engine رندر میکند. حالا میخواهیم این صفحه را به PDF تبدیل کنیم.
using Microsoft.AspNetCore.Mvc;
using PuppeteerSharp;
using PuppeteerSharp.Media;
[ApiController]
[Route("[controller]")]
public class HtmlToPdfController : ControllerBase
{
[HttpGet("generate")]
public async Task GeneratePdfFromUrl()
{
// آدرس صفحهای که میخواهید به PDF تبدیل شود
// این میتواند یک آدرس داخلی در اپلیکیشن شما باشد
string url = "https://www.google.com";
await new BrowserFetcher().DownloadAsync(); // دانلود کرومیوم در صورت نیاز
var launchOptions = new LaunchOptions { Headless = true };
await using var browser = await Puppeteer.LaunchAsync(launchOptions);
await using var page = await browser.NewPageAsync();
await page.GoToAsync(url);
var pdfOptions = new PdfOptions
{
Format = PaperFormat.A4,
PrintBackground = true // برای چاپ پسزمینه و رنگها
};
var pdfBytes = await page.PdfDataAsync(pdfOptions);
return File(pdfBytes, "application/pdf", "from-html.pdf");
}
}
این رویکرد بسیار قدرتمند است، اما باید به چند نکته توجه داشت:
-
وابستگی به مرورگر: این روش نیازمند وجود فایلهای مرورگر Chromium بر روی سرور است که حجم نسبتاً بالایی دارند.
-
مصرف منابع: اجرای یک نمونه کامل از مرورگر میتواند منابع بیشتری (CPU و حافظه) نسبت به کتابخانههای مبتنی بر کد مصرف کند، خصوصاً تحت بار زیاد.
مقایسه و نتیجهگیری
| ویژگی / کتابخانه | QuestPDF | PdfSharp / MigraDoc | Puppeteer Sharp (HTML to PDF) |
| سهولت استفاده | بسیار بالا (API روان و مدرن) | متوسط (API قدیمیتر) | بالا (طراحی با HTML/CSS) |
| کنترل بر خروجی | بالا (مبتنی بر کامپوننت) | بسیار بالا (کنترل سطح پایین) | وابسته به رندر مرورگر |
| عملکرد | عالی | خوب | متوسط (به دلیل سربار مرورگر) |
| وابستگیها | حداقل | حداقل | سنگین (نیاز به Chromium) |
| پشتیبانی از فارسی | خوب (با تنظیمات فونت) | چالشبرانگیز | عالی (ذاتی) |
| بهترین کاربرد | گزارشها، فاکتورها، اسناد ساختاریافته | دستکاری PDF، اسناد متنی ساده | اسناد با طراحی بصری پیچیده |
کدام روش را انتخاب کنیم؟
-
برای اکثر پروژههای جدید، QuestPDF بهترین انتخاب است. API مدرن، عملکرد عالی و سهولت استفاده، آن را به گزینهای ایدهآل برای ساخت انواع اسناد تجاری تبدیل میکند.
-
اگر نیاز به کنترل بسیار دقیق و سطح پایین بر روی ساختار PDF دارید یا میخواهید فایلهای PDF موجود را ویرایش کنید، PdfSharp ابزار مناسبی است. برای ساخت اسناد متنی ساده نیز MigraDoc همچنان یک گزینه قابل اتکا است.
-
اگر ظاهر بصری سند برای شما در اولویت اول قرار دارد و میخواهید از مهارتهای طراحی وب خود (HTML/CSS) برای ساخت PDFهای زیبا و پیچیده استفاده کنید، روش تبدیل HTML به PDF با Puppeteer Sharp قدرتمندترین و انعطافپذیرترین گزینه خواهد بود، به شرطی که مصرف منابع بیشتر و وابستگی به مرورگر برای شما مشکلی ایجاد نکند.
در نهایت، انتخاب ابزار مناسب به نیازهای خاص پروژه شما بستگی دارد. خوشبختانه اکوسیستم ASP.NET Core راهحلهای رایگان و توانمندی را برای هر سناریویی فراهم کرده است.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.