مقالة تقنية

جدول HotPDF إلى PDF

· برامج PDF

هذا المثال الخاص بمكون HotPDF يقوم بتحويل سجلات قاعدة البيانات إلى جدول PDF منسق. إنه نمط موجز لإنشاء التقارير: قراءة الصفوف من مجموعة بيانات، ورسم رأس الجدول، وطباعة كل صف في موضع عمودي محدد، وإضافة صفحة جديدة عندما تمتلئ الصفحة الحالية.

يستخدم المثال مصدر بيانات TTable قديم، ولكن منطق PDF مستقل عن طبقة التخزين هذه. يمكن استخدام نفس طريقة العرض مع FireDAC، أو ADO، أو مجموعات البيانات الموجودة في الذاكرة، أو نتائج REST، أو أي بيانات تطبيق يمكن تعدادها صفًا تلو الآخر.

النقطة الرئيسية في التصميم هي فصل عرض الصفوف عن إعداد الصفحة. ترسم الدالة PrintRow صفًا واحدًا، وتنشئ الدالة PreparePage الرأس المتكرر وبيانات وصف الصفحة، وتتحكم الحلقة الرئيسية في التقسيم إلى صفحات. هذا الفصل يجعل المثال أسهل في التكيف مع الجداول الأوسع، أو الإجماليات، أو التجميع، أو رؤوس التقارير المخصصة.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
program TableDemo;
{$APPTYPE CONSOLE}
{ Reduce EXE size by disabling as much of RTTI as possible }
{$IFDEF VER210}
{$WEAKLINKRTTI ON}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
{$ENDIF}
 
uses
  {$IFDEF VER230}System.Classes, System.SysUtils, Vcl.Graphics, DB, DBTables,
  {$ELSE} Classes, SysUtils, Graphics, DB, DBTables,
  {$ENDIF} HPDFDoc;
 
var
  HotPDF: THotPDF;
  PageNum, VertPos: Integer;
  CustomerTable: TTable;
  Back: boolean;
 
procedure PrintRow(Position: Integer; No, Company, Addr, City: AnsiString; ShowBackground: boolean);
begin
  if ShowBackground then
  begin
    HotPDF.CurrentPage.SetRGBColor($FFF3DD);
    HotPDF.CurrentPage.Rectangle(50, Position, 520, 20);
    HotPDF.CurrentPage.Fill;
    HotPDF.CurrentPage.SetRGBColor(clBlack);
  end;
  HotPDF.CurrentPage.TextOut(70, Position, 0, No);
  HotPDF.CurrentPage.TextOut(110, Position, 0, Company);
  HotPDF.CurrentPage.TextOut(300, Position, 0, Addr);
  HotPDF.CurrentPage.TextOut(480, Position, 0, City);
end;
 
procedure PreparePage;
begin
  HotPDF.CurrentPage.SetFont('Arial', [fsItalic], 10);
  HotPDF.CurrentPage.TextOut(50, VertPos, 0, 'customer.db' + '  Page' + AnsiString(IntToStr(PageNum)));
  HotPDF.CurrentPage.TextOut(480, VertPos, 0, AnsiString(DateTimeToStr(Now)));
  HotPDF.CurrentPage.MoveTo(50, VertPos + 15);
  HotPDF.CurrentPage.LineTo(570, VertPos + 15);
  HotPDF.CurrentPage.MoveTo(50, VertPos + 45);
  HotPDF.CurrentPage.LineTo(570, VertPos + 45);
  HotPDF.CurrentPage.Stroke;
  HotPDF.CurrentPage.SetFont('Times New Roman', [fsItalic, fsBold], 12);
  HotPDF.CurrentPage.SetRGBFillColor(clNavy);
  PrintRow(VertPos + 25, 'No', 'Company', 'Addr', 'City', false);
  HotPDF.CurrentPage.SetRGBFillColor(clBlack);
  Inc(VertPos, 20);
end;
 
begin
  CustomerTable := TTable.Create(nil);
  try
    CustomerTable.DatabaseName := 'DBDEMOS';
    CustomerTable.TableName := GetCurrentDir + '\customer.db';
    CustomerTable.Active := true;
    CustomerTable.First;
    HotPDF := THotPDF.Create(nil);
    try
      HotPDF.AutoLaunch := true;
      HotPDF.FileName := 'TableDemo.pdf';
      HotPDF.PageLayout := plOneColumn;
      HotPDF.BeginDoc;
      HotPDF.CurrentPage.SetFont('Arial', [fsBold], 24);
      HotPDF.CurrentPage.TextOut(200, 20, 0, 'Customer report'); // Print PDF header
      PageNum := 1;
      VertPos := 60;
      PreparePage; // Table header
      Back := true;
      while (not(CustomerTable.Eof)) do
      begin
        Back := not(Back);
        if (VertPos > 700) then // If end of page then
        begin
          HotPDF.AddPage; // Add page, draw and print
          Inc(PageNum);   // table header and set
          VertPos := 60;  // new print position
          PreparePage;
        end;
        PrintRow(VertPos + 25, // print row from the current position
          AnsiString(CustomerTable.FieldValues['CustNo']), AnsiString(CustomerTable.FieldValues['Company']),
          AnsiString(CustomerTable.FieldValues['Addr1']), AnsiString(CustomerTable.FieldValues['City']), Back);
        Inc(VertPos, 20);
        CustomerTable.Next;
      end;
      HotPDF.EndDoc;
    finally
      HotPDF.Free;
    end;
  finally
    CustomerTable.Free;
  end;
 
end.

ما يجب تعديله في الإنتاج.

  • استبدل جدول DBDEMOS التجريبي بمجموعة البيانات أو نتيجة الاستعلام الخاصة بالتطبيق.
  • قم بقياس عرض الأعمدة بناءً على البيانات المتوقعة بدلاً من ترميز كل إحداثي x يدويًا.
  • تعامل مع النصوص الطويلة عن طريق التفاف أو اقتطاع الحقول قبل رسم الصف.
  • كرر رؤوس الجدول في كل صفحة جديدة بحيث تظل التقارير المصدرة قابلة للقراءة.
  • حافظ على هوامش الصفحة وارتفاع الصفوف في ثوابت مُعرَّفة لتجعل التغييرات في التخطيط قابلة للتوقع.

لماذا يعتبر الرسم المباشر للجداول في ملفات PDF مفيدًا.

الرسم المباشر يمنح تحكمًا كاملاً في الخطوط والألوان والحدود وعلامات التبويب والصفوف التلخيصية دون الاعتماد على مصمم تقارير مرئي. إنه مفيد بشكل خاص للأدوات التي تعمل من جانب الخادم أو على دفعات، حيث يجب أن يظل تنسيق الإخراج ثابتًا عبر الأجهزة.