Articol tehnic

Crearea documentelor PDF de la zero cu PDFium Component în Delphi

Această versiune localizată intră direct în Creating PDF Documents from Scratch with PDFium Component in Delphi și folosește articolul englez actualizat ca reper tehnic pentru echipele Delphi, PDF și software documentar

Pagina transformă articolul de bază actualizat în puncte concrete de control pentru proiectare, implementare și validare

Ce a fost sincronizat din articolul englez

Textul de bază în engleză a fost extins cu context de implementare, decizii tehnice și exemple concrete, astfel că pagina trebuie citită ca un ghid de lucru, nu ca un rezumat scurt

Secțiuni importante din articolul de bază actualizat:

  • Folosește mai întâi fișiere mici de intrare, ușor de reprodus
  • Păstrează neschimbate numele produselor, API-urilor, fișierelor și valorile literale
  • Salvează ieșirea validatorului și informațiile de versiune împreună cu fișierul eșantion generat

Alegeri practice de implementare

Pornește de la tipul de fișier, rezultatul așteptat și starea de eroare care trebuie afișată utilizatorului. Leagă apoi fiecare apel API de un rezultat verificabil, astfel încât validarea, logarea și suportul să poată reproduce cazul clientului

  • Folosește mai întâi fișiere mici de intrare, ușor de reprodus
  • Păstrează neschimbate numele produselor, API-urilor, fișierelor și valorile literale
  • Salvează ieșirea validatorului și informațiile de versiune împreună cu fișierul eșantion generat

Verificare înainte de publicare

Verifică fișierul de ieșire cu aceleași instrumente pe care le va folosi clientul sau arhiva. Notează versiunea componentei, datele de test, versiunea validatorului și rezultatul observat pentru a urmări precis o regresie ulterioară

Lecturi conexe

Note suplimentare

Această completare transformă versiunea scurtă într-un ghid de lucru mai util și rămâne aliniată cu Creating PDF Documents from Scratch with PDFium Component in Delphi și cu baza tehnică din articolul englez. Textul trebuie să arate clar cu ce tip de intrare pornește tema, ce rezultat este așteptat și în ce punct trebuie confirmat comportamentul prin validation

La rescriere contează ordinea deciziilor: mai întâi forma datelor, apoi limita schimbării, după aceea dependențele API și, la final, comportamentul rezultat. Dacă articolul menționează mai multe opțiuni, merită explicat și ce variantă este mai ușor de susținut în maintenance, support și în reproducerea unei probleme

Orice code block, nume de fișier, nume de API și valoare literal trebuie să rămână neschimbate. Explicația din jur poate fi mai amplă, dar exemplul de cod trebuie să fie o referință exactă, astfel încât cititorul să îl poată compara direct cu proiectul lui Delphi, C++Builder sau Lazarus/FPC

Secțiunea de validation ar trebui să menționeze un fișier de intrare mic, compararea rezultatului și notarea versiunii de component sau validator. Dacă pagina descrie un bug fix sau o migrare, traseul de reproducere, starea observată inițial și punctul de confirmare trebuie spuse clar, ca să poată fi urmărită orice regression fără presupuneri

O astfel de extindere face pagina utilă și după prima lectură: pentru reviewer ca explicație a deciziei, pentru support ca fundal de diagnostic și pentru echipa de întreținere ca notă de referință înainte de modificările viitoare

  • Nu schimba numele produselor, API-urilor, fișierelor sau valorile literal
  • Păstrează code block-urile exact așa cum sunt
  • Descrie validation cu fișier de probă și rezultat comparabil
  • Explică ordinea deciziilor, nu doar un rezumat foarte scurt

Exemple de cod suplimentare

uses
  Vcl.Graphics,   // for clBlack and TColor
  PDFium;         // TPdf lives here

procedure CreateBlankPdf(const FileName: string);
var
  Pdf: TPdf;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.CreateDocument;                 // empty in-memory document
    Pdf.AddPage(0, 595, 842);           // A4 portrait, in points
    Pdf.AddText('First page', 'Arial', 18, 50, 780);
    Pdf.SaveAs(FileName);               // serialize to disk
  finally
    Pdf.Active := False;
    Pdf.Free;
  end;
end;
procedure WriteHeader(Pdf: TPdf; const Title, Author: string);
begin
  // Title in black, default opacity, no rotation
  Pdf.AddText(Title, 'Arial', 20, 50, 780);
  // A lighter byline 24 points below it
  Pdf.AddText('By ' + Author, 'Arial', 11, 50, 756, clGray);
  // A faint diagonal draft stamp across the page
  Pdf.AddText('DRAFT', 'Arial', 64, 180, 380, clGray, $30, 45.0);
end;
procedure DrawDivider(Pdf: TPdf; X, Y, Width: Single);
begin
  // A thin horizontal rule. The rectangle overload sets a box directly:
  // X, Y, Width, Height, then fill mode and colors.
  Pdf.CreatePath(X, Y, Width, 0.5, fmNone, clBlack, $FF,
    True, clBlack, $FF, 1.0);
  Pdf.AddPath;
end;

procedure DrawTriangle(Pdf: TPdf);
begin
  // Point overload: start at the first vertex, line to the rest, close.
  Pdf.CreatePath(200, 300, fmWinding, clBlue, $80, True, clNavy, $FF, 2.0);
  Pdf.LineTo(300, 300);
  Pdf.LineTo(250, 400);
  Pdf.ClosePath;
  Pdf.AddPath;          // nothing is drawn until this runs
end;
procedure DrawTable(Pdf: TPdf; Left, Top: Double);
const
  ColX: array[0..2] of Double = (0, 110, 210);  // column offsets
  RowH = 20;
var
  Y: Double;
  Row: Integer;
begin
  // Header row
  Pdf.AddText('Item', 'Arial', 10, Left + ColX[0], Top);
  Pdf.AddText('Qty', 'Arial', 10, Left + ColX[1], Top);
  Pdf.AddText('Price', 'Arial', 10, Left + ColX[2], Top);

  // Rule under the header
  Pdf.CreatePath(Left, Top - 5, 260, 0.5, fmNone, clBlack, $FF);
  Pdf.AddPath;

  // Data rows, stepping Y downward each iteration
  Y := Top;
  for Row := 1 to 3 do
  begin
    Y := Y - RowH;
    Pdf.AddText('Item ' + IntToStr(Row), 'Arial', 9, Left + ColX[0], Y);
    Pdf.AddText(IntToStr(Row * 2), 'Arial', 9, Left + ColX[1], Y);
    Pdf.AddText('$' + IntToStr(Row * 10) + '.00', 'Arial', 9, Left + ColX[2], Y);
  end;
end;
procedure CreateMultiPageReport(const FileName: string; PageCount: Integer);
var
  Pdf: TPdf;
  P: Integer;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.CreateDocument;
    for P := 1 to PageCount do
    begin
      Pdf.AddPage(P, 595, 842);     // append; the new page becomes current
      Pdf.AddText('Page ' + IntToStr(P) + ' of ' + IntToStr(PageCount),
        'Arial', 10, 50, 30);       // footer near the bottom edge
      // ... draw this page's body here ...
    end;
    Pdf.SaveAs(FileName);
  finally
    Pdf.Active := False;
    Pdf.Free;
  end;
end;