مقاله فنی

خروجی گرفتن از کاربرگ‌های اکسل به PDF در دلفی بدون نیاز به آفیس

برای خروجی گرفتن از یک کاربرگ اکسل به PDF در دلفی یا سی‌پلاس‌پلاس‌بیلدر بدون نیاز به نصب آفیس، متد SaveAsPDF را روی یک کاربرگ یا کارپوشه HotXLS فراخوانی کنید. HotXLS یک کامپوننت بومی VCL اکسل است، و خروجی کاربرگ به PDF آن، محدوده استفاده‌شده (used range) شیت را به یک فایل مستقل PDF 1.4 رندر می‌کند، و عرض ستون‌های اکسل و متن نمایشی سلول‌ها را روی صفحات A4 با صفحه‌بندی خودکار چندصفحه‌ای نگاشت می‌نماید. هیچ نسخه‌ای از اکسل، هیچ درایور پرینتری و هیچ DLL خارجی در این فرآیند رندر شرکت ندارد

ابزار HotXLS با PDF به عنوان یک قالب نمایش داده‌ها رفتار می‌کند، قالبی هم‌خانواده با مسیرهای خروجی CSV، TSV و HTML، تا اینکه آن را یک موتور رندر دقیق پیکسلی بداند. این خروجی محتوا و طرح‌بندی جدول را بازتولید می‌کند: مقادیری که در شبکه سلول‌ها می‌بینید، نسبت‌های ستون، و خطوط جدول (gridlines) در اطراف سلول‌ها. این نوع طراحی اهمیت دارد زیرا از همان ابتدا یک انتظار واقعی ایجاد می‌کند، و بقیه این مقاله درباره این است که این مرز دقیقاً در کجا قرار دارد

چگونه بدون نیاز به آفیس اکسل را در دلفی به PDF تبدیل کنیم؟

کوتاه‌ترین مسیر یک فراخوانی واحد است. کلاس TXLSWorksheet متدهای SaveAsPDF(FileName) و SaveAsPDF(Stream) را ارائه می‌دهد، و TXLSWorkbook نیز همان دو سرریزی (overloads) را ارائه می‌دهد که درخواست را به شیت فعال ارسال می‌کنند. هر کدام یک عدد صحیح (Integer) برمی‌گردانند، 1 در صورت موفقیت و -1 در صورت شکست، بنابراین می‌توانید بر اساس نتیجه تصمیم‌گیری کنید بدون اینکه نیاز باشد فراخوانی را در مدیریت استثنای خود قرار دهید

uses
  lxHandle;

var
  Book: TXLSWorkbook;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('sales-june.xlsx');
    // Render the active sheet's used range straight to report.pdf.
    if Book.SaveAsPDF('report.pdf') = 1 then
      Writeln('PDF written');
  finally
    Book.Free;
  end;
end;

هنگامی که متد SaveAsPDF را روی یک کاربرگ فراخوانی می‌کنید، HotXLS محدوده UsedRange آن شیت، یعنی کادر مرزی هر سلول پرشده را صادر می‌کند. سرریزی کارپوشه یک متد کمکی است که وظیفه را به شیت فعال واگذار می‌کند، بنابراین یک گزارش چندشیتی یا روی شیت‌های مورد نیاز خود حلقه می‌زند یا شیت فعال را قبل از فراخوانی انتخاب می‌کند. هیچ حالتی برای کل کارپوشه به صورت «همه در یک مرحله» وجود ندارد که هر تب را به هم متصل کند: هر فراخوانی یک شیت یا یک محدوده را رندر می‌نماید

چگونه HotXLS یک محدوده استفاده‌شده را به صفحات PDF تبدیل می‌کند؟

ابزار HotXLS محدوده استفاده‌شده را سلول به سلول پیمایش کرده و آن را به صورت یک شبکه صفحه‌بندی‌شده چیدمان می‌کند. ساختار هندسی ستون‌ها مستقیماً از اکسل می‌آید: عرض هر ستون از واحد عرض اکسل به نقاط تایپوگرافی تبدیل می‌شود، با یک حداقل کف مشخص تا هیچ ستونی به یک باریکه ناچیز تبدیل نشود. هنگامی که کل ستون‌ها با هم عریض‌تر از صفحه قابل استفاده باشند، HotXLS اندازه آنها را به طور یکنواخت برای تناسب با صفحه کوچک می‌کند؛ و زمانی که از قبل متناسب باشند، آنها را در عرض طبیعی خود رها می‌کند به جای اینکه آنها را در سراسر صفحه بکشد

ردیف‌ها به سمت پایین صفحه حرکت می‌کنند تا زمانی که ردیف بعدی از حاشیه پایینی عبور کند، در این نقطه HotXLS یک صفحه جدید باز می‌کند و ادامه می‌دهد، بنابراین یک شیت هزار ردیفی بدون نیاز به مدیریت شکستگی صفحه از طرف شما، به طور خودکار صفحه‌بندی می‌شود. هر سلول عبارت FormattedText خود را چاپ می‌کند، یعنی همان رشته نمایشی که پس از اعمال فرمت عدد تولید می‌شود، بنابراین یک تاریخ همان‌گونه نشان داده می‌شود که شیت نشان می‌دهد و یک سلول ارز، جداکننده‌های هزارگان و نماد خود را حفظ می‌کند. متنی که از ستون خود فراتر رود، به جای سرریز شدن به ستون مجاور، به اندازه عرض سلول برش می‌خورد

کنترل جهت صفحه، حاشیه‌ها و اندازه فونت

برای هر چیزی فراتر از طرح‌بندی پیش‌فرض، صادرکننده را به طور مستقیم مدیریت کنید. کلاس TXLSPDFExport کلاس پشتیبان متدهای کمکی تک‌خطی است و سه ویژگی را ارائه می‌دهد: Orientation (شامل xlsPdfPortrait یا xlsPdfLandscape که به طور پیش‌فرض عمودی یا portrait است)، Margin (به واحد نقطه، پیش‌فرض ۴۰)، و FontSize (به واحد نقطه، پیش‌فرض ۹). آنها را قبل از فراخوانی SaveAsPDF تنظیم کنید تا کل سند آنها را اعمال کند

uses
  lxHandle, lxPDF;

var
  Book: TXLSWorkbook;
  Exporter: TXLSPDFExport;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('wide-ledger.xlsx');
    Exporter := TXLSPDFExport.Create;
    try
      Exporter.Orientation := xlsPdfLandscape;  // fit wide sheets on the page
      Exporter.Margin := 28;                     // tighter page margin, in points
      Exporter.FontSize := 8;                    // denser rows
      Exporter.SaveAsPDF(Book.ActiveSheet, 'ledger.pdf');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

کلاس TXLSPDFExport همچنین از طریق متد SaveAsPDF(Range: IXLSRange; ...) یک محدوده را به جای یک شیت کامل می‌پذیرد، که روشی است برای صادر کردن یک بلوک خلاصه از شیتی که حاوی محاسبات موقت نیز می‌باشد. آن سرریزی محدوده، همان متدی است که ابزار کمکی کاربرگ در داخل خود به آن تکیه می‌کند، بنابراین طرح‌بندی، مقیاس‌بندی و صفحه‌بندی به طور یکسان رفتار می‌کنند، چه یک محدوده استفاده‌شده کامل به آن بدهید و چه یک انتخاب دستی

var
  Book: TXLSWorkbook;
  Exporter: TXLSPDFExport;
  Summary: IXLSRange;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('quarter.xlsx');
    // Export only the summary block, not the scratch columns beside it.
    Summary := Book.Sheets[1].Range['A1', 'F20'];
    Exporter := TXLSPDFExport.Create;
    try
      Exporter.SaveAsPDF(Summary, 'summary.pdf');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

چرا HotXLS فونتی تعبیه نمی‌کند: موازنه بین Helvetica و WinAnsi

ابزار HotXLS متن را با فونت Helvetica داخلی PDF و با انکودینگ WinAnsiEncoding می‌نویسد، انتخابی آگاهانه برای عدم وابستگی با یک محدودیت واقعی. از آنجا که Helvetica یکی از ۱۴ فونت استاندارد است که هر خواننده PDF استانداردی از قبل به همراه دارد، صادرکننده اصلاً فایل فونتی را تعبیه نمی‌کند: حجم فایل کوچک می‌ماند و در هر جایی باز می‌شود، بدون اینکه نیازی به مجوز یا ارسال فایلی همراه آن باشد. هزینه این انتخاب، مجموعه کاراکترهایی است که صفحه می‌تواند نشان دهد

انکودینگ WinAnsiEncoding مجموعه Windows-1252 را پوشش می‌دهد، بنابراین متن‌های لاتین، علائم نگارشی رایج، و لهجه‌های معمول اروپای غربی به درستی رندر می‌شوند، و HotXLS تعداد انگشت‌شماری از کاراکترهای تایپوگرافی، نقل‌قول‌های فرورفته، خطوط تیره کوتاه و بلند، و نماد یورو را در بخش‌های CP1252 خود جای می‌دهد. کاراکترهای خارج از آن محدوده، مانند خطوط چینی/ژاپنی/کره‌ای، سیریلیک، یونانی و عربی، به یک علامت سؤال روی صفحه تبدیل می‌شوند. اگر شیت‌های شما حاوی متن غیرلاتین است، این صادرکننده ابزار مناسبی نیست، و رندرکننده PDF با استایل‌دهی کامل همان چیزی است که نیاز دارید

جایی که خروجی کاربرگ به PDF متوقف می‌شود

ابزار HotXLS محتوا و ساختار را رندر می‌کند، نه سبک بصری کامل شیت را. رنگ‌های پرکننده سلول، استایل‌های حاشیه برای هر لبه، فونت‌ها و رنگ‌ها برای هر سلول، نمودارها و تصاویر تعبیه‌شده خارج از چیزی هستند که صادرکننده رسم می‌کند؛ آنچه دریافت می‌کنید شبکه متنی با خطوط جدول یکنواخت است. این همان قراردادی است که صادرکننده‌های HTML و RTF از آن پیروی می‌کنند، و برای یک گزارش یا تحویل داده که در آن اعداد مفهوم را منتقل می‌کنند و ظاهر اهمیت ندارد، انتخاب درستی است

هنگامی که هدف یک سند با استایل و هماهنگ با برند است، الگوی معمول این است که ابتدا اعداد را در یک قالب صفحه‌گسترده جمع‌آوری کنید، که بخش گردش کار تولید گزارش مبتنی بر قالب آن را به تفصیل پوشش می‌دهد. و از آنجا که هیچ‌کدام از این مراحل با COM یا یک نسخه در حال اجرای اکسل ارتباطی ندارد، این مسیر با همان مدل اتوماسیون بدون نیاز به آفیس که HotXLS در سراسر سیستم استفاده می‌کند مطابقت دارد: کدهای خالص پاسکال، قابل اجرا روی سرورهای بدون سر، بدون نیاز به مجوز یا نگهداری رابط کاربری

فایل PDF مستقل، بایت‌به‌بایت

ابزار HotXLS ساختار فایل PDF را به صورت دستی می‌سازد و جدول مرجع متقاطع (cross-reference table) آن را از آفست‌های بایت دقیق محاسبه می‌کند، که دلیل باز شدن خروجی در تمام برنامه‌های خواننده است. همان‌طور که هر شیء را سریال‌سازی می‌کند، HotXLS آفست شروع آن شیء را قبل از الحاق بایت‌هایش ثبت می‌نماید، سپس موقعیت جاری را به اندازه طولی که تازه نوشته است جلو می‌برد، به طوری که جدول xref دقیقاً روی هر شیء قرار می‌گیرد و startxref نشان می‌دهد که آن جدول از کجا شروع می‌شود. خواننده‌ای که این آفست‌ها را حتی یک بایت اشتباه پیدا کند کل فایل را رد می‌کند، که این موضوع آفست محاسبه‌شده توسط خود ابزار را به قرارداد بسیار مهم صادرکننده تبدیل می‌نماید

آن قرارداد یک نتیجه سخت‌گیرانه به همراه دارد که دانستن آن مفید است. گره Pages ابتدا به عنوان شیء ۱ نوشته می‌شود، اما لیست صفحات فرزند آن تا زمانی که هر صفحه صادر نشده باشد مشخص نیست، بنابراین HotXLS آن را به عنوان یک فیلد نگهدارنده رزرو می‌کند و فرزندان نهایی و تعداد را قبل از اجرای آفست اصلاح می‌نماید، و هرگز بعد از آن تغییر نمی‌دهد. به محض اینکه بایت‌های یک شیء برای xref اندازه‌گیری شدند، ثابت می‌شوند: تغییر دادن حتی یک بایت پس از آن باعث جابجایی هر آفست بعدی و خراب شدن جدول می‌گردد. این یک انضباط کوچک است که یک فایل استاندارد PDF 1.4 معتبر را بدون نیاز به هیچ کتابخانه پایه‌ای ارائه می‌دهد

متدهای SaveAsPDF و کلاس TXLSPDFExport نشان داده شده در اینجا همراه با HotXLS Delphi Excel Component ارائه می‌شوند، در کنار صادرکننده‌های CSV، HTML و RTF و API کامل کاربرگ برای دلفی و سی‌پلاس‌پلاس‌بیلدر