Dit HotPDF Component-voorbeeld zet databaserecords om in een gepagineerde PDF-tabel. Het is een compact patroon voor rapportgeneratie: lees rijen uit een dataset, teken de tabelkop, druk elke rij af op een bekende verticale positie en voeg een nieuwe pagina toe wanneer de huidige pagina vol is.
Het voorbeeld gebruikt een oudere TTable-gegevensbron, maar de PDF-logica is onafhankelijk van die opslaglaag. Dezelfde renderaanpak kan worden gebruikt met FireDAC, ADO, datasets in het geheugen, REST-resultaten of andere toepassingsgegevens die rij voor rij kunnen worden doorlopen.
Het belangrijkste ontwerpprincipe is het scheiden van rijrendering en pagina-inrichting. PrintRow tekent één rij, PreparePage maakt de herhaalde kop en paginametadata, en de hoofdlus stuurt de paginering. Die scheiding maakt het voorbeeld eenvoudiger aan te passen voor bredere tabellen, totalen, groepering of rapportkoppen met branding.
|
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. |
Wat u in productie aanpast
- Vervang de voorbeeldtabel DBDEMOS door de dataset of query-uitvoer van de toepassing.
- Bepaal kolombreedtes op basis van de verwachte gegevens in plaats van elke x-coördinaat hard te coderen.
- Verwerk lange tekst door velden af te breken of in te korten voordat de rij wordt getekend.
- Herhaal tabelkoppen op elke nieuwe pagina zodat geëxporteerde rapporten leesbaar blijven.
- Bewaar paginamarges en rijhoogte in benoemde constanten zodat lay-outwijzigingen voorspelbaar blijven.
Waarom direct PDF-tabellen tekenen nuttig is
Direct tekenen geeft volledige controle over lettertypen, kleuren, randen, pagina-einden en samenvattingsrijen zonder afhankelijk te zijn van een visuele rapportontwerper. Dit is vooral nuttig voor server-side of batchachtige tools waarbij het uitvoerformaat op verschillende machines stabiel moet blijven.