Printing PDF documents with accurate rendering and proper scaling is a common requirement. The Print PDF demo shows how to implement professional PDF printing with preview, page selection, and quality options using PDFium VCL Component.
Overview
This comprehensive demo provides a complete printing solution including print preview, page range selection, quality settings, scaling options, and recent file history. It demonstrates best practices for PDF printing in Delphi applications.
Key Features
- Print Preview – Visual preview before printing
- Page Selection – Print all pages or specific ranges
- Quality Settings – Draft, normal, and high-quality modes
- Scaling Options – Fit to page, shrink to fit, or no scaling
- Multiple Copies – Print multiple copies with collation
- Progress Tracking – Visual feedback during printing
- Recent Files – Quick access to previously printed documents
PDFium DLL Requirements
Before running any PDFium VCL application, ensure the PDFium DLL files are installed:
pdfium32.dll/pdfium64.dll– Standard versions (~5-6 MB)pdfium32v8.dll/pdfium64v8.dll– With V8 JavaScript engine (~23-27 MB)
Installation: Run PDFiumVCL\DLLs\CopyDlls.bat as Administrator to automatically copy the DLLs to Windows system directories.
Basic PDF Printing
|
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 |
procedure PrintPdfSimple(const FileName: string); var Pdf: TPdf; I: Integer; Bitmap: TBitmap; begin Pdf := TPdf.Create(nil); try Pdf.FileName := FileName; Pdf.Active := True; Printer.Title := Pdf.Title; Printer.BeginDoc; try for I := 1 to Pdf.PageCount do begin if I > 1 then Printer.NewPage; Pdf.PageNumber := I; // Render page to printer Bitmap := Pdf.RenderPage( 0, 0, Printer.PageWidth, Printer.PageHeight, ro0, [rePrinting] ); try PrintBitmap(Printer, Bitmap); finally Bitmap.Free; end; end; finally Printer.EndDoc; end; finally Pdf.Active := False; Pdf.Free; end; end; |
Printing Bitmap to Printer
|
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 |
procedure PrintBitmap(Printer: TPrinter; Bitmap: TBitmap); var InfoHeaderSize, ImageSize: DWORD; InfoHeader: PBitmapInfo; Image: Pointer; begin GetDIBSizes(Bitmap.Handle, InfoHeaderSize, ImageSize); InfoHeader := AllocMem(InfoHeaderSize); try Image := AllocMem(ImageSize); try GetDIB(Bitmap.Handle, 0, InfoHeader^, Image^); StretchDIBits( Printer.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, 0, 0, Bitmap.Width, Bitmap.Height, Image, InfoHeader^, DIB_RGB_COLORS, SRCCOPY ); finally FreeMem(Image); end; finally FreeMem(InfoHeader); end; end; |
Complete Printing with Options
|
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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
procedure TFormMain.PrintPDFPages; var FromPage, ToPage, Page, Copy, CopyCount: Integer; FirstPage: Boolean; Bitmap: TBitmap; ScaleX, ScaleY, Scale: Double; DestWidth, DestHeight: Integer; Dpi: Integer; begin // Get print quality DPI case cmbQuality.ItemIndex of 0: Dpi := 150; // Draft 1: Dpi := 300; // Normal 2: Dpi := 600; // High else Dpi := 300; end; // Determine page range if radAllPages.Checked then begin FromPage := 1; ToPage := Pdf.PageCount; end else begin FromPage := StrToIntDef(edtFromPage.Text, 1); ToPage := StrToIntDef(edtToPage.Text, Pdf.PageCount); end; // Handle copies and collation if chkCollate.Checked then CopyCount := 1 // Will repeat entire job else CopyCount := spnCopies.Value; FProcessing := True; FCancelled := False; Printer.Title := ExtractFileName(Pdf.FileName); Printer.BeginDoc; try FirstPage := True; progressPrint.Max := (ToPage - FromPage + 1) * spnCopies.Value; progressPrint.Position := 0; for Page := FromPage to ToPage do begin for Copy := 1 to CopyCount do begin if FCancelled then Break; if FirstPage then FirstPage := False else Printer.NewPage; Pdf.PageNumber := Page; // Calculate scaling based on settings case cmbScaling.ItemIndex of 0: // No scaling begin DestWidth := Round(Pdf.PageWidth * Dpi / 72); DestHeight := Round(Pdf.PageHeight * Dpi / 72); end; 1: // Fit to page begin ScaleX := Printer.PageWidth / (Pdf.PageWidth * Dpi / 72); ScaleY := Printer.PageHeight / (Pdf.PageHeight * Dpi / 72); Scale := Min(ScaleX, ScaleY); DestWidth := Round(Pdf.PageWidth * Dpi / 72 * Scale); DestHeight := Round(Pdf.PageHeight * Dpi / 72 * Scale); end; 2: // Shrink to fit (only if needed) begin ScaleX := Printer.PageWidth / (Pdf.PageWidth * Dpi / 72); ScaleY := Printer.PageHeight / (Pdf.PageHeight * Dpi / 72); Scale := Min(ScaleX, ScaleY); if Scale > 1 then Scale := 1; DestWidth := Round(Pdf.PageWidth * Dpi / 72 * Scale); DestHeight := Round(Pdf.PageHeight * Dpi / 72 * Scale); end; end; // Render and print Bitmap := Pdf.RenderPage(0, 0, DestWidth, DestHeight, ro0, [rePrinting, reAnnotations]); try PrintBitmap(Printer, Bitmap); finally Bitmap.Free; end; progressPrint.Position := progressPrint.Position + 1; Application.ProcessMessages; end; if FCancelled then Break; end; finally Printer.EndDoc; FProcessing := False; end; end; |
Using Print Dialog
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
procedure TFormMain.btnPrintClick(Sender: TObject); begin if not FileExists(edtPdfFile.Text) then begin ShowError('Please select a valid PDF file first.'); Exit; end; // Setup print dialog PrintDialog.MinPage := 1; PrintDialog.MaxPage := Pdf.PageCount; PrintDialog.FromPage := 1; PrintDialog.ToPage := Pdf.PageCount; PrintDialog.Options := [poPageNums, poSelection]; if PrintDialog.Execute then begin PrintPDFPages; end; end; |
Print Preview
|
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 |
procedure TFormMain.UpdatePreview; var PreviewWidth, PreviewHeight: Integer; Scale: Double; begin if not Pdf.Active then Exit; Pdf.PageNumber := FCurrentPreviewPage; // Calculate preview size to fit panel Scale := Min( pnlPreview.Width / Pdf.PageWidth, pnlPreview.Height / Pdf.PageHeight ) * (FCurrentZoom / 100); PreviewWidth := Round(Pdf.PageWidth * Scale); PreviewHeight := Round(Pdf.PageHeight * Scale); // Render preview FPreviewBitmap.Free; FPreviewBitmap := Pdf.RenderPage( 0, 0, PreviewWidth, PreviewHeight, ro0, [reAnnotations], clWhite ); // Display in image control imgPreview.Picture.Assign(FPreviewBitmap); // Update page info lblPageInfo.Caption := Format('Page %d of %d', [FCurrentPreviewPage, Pdf.PageCount]); end; |
Preview Navigation
|
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 |
procedure TFormMain.btnFirstPageClick(Sender: TObject); begin if Pdf.Active then begin FCurrentPreviewPage := 1; edtPreviewPage.Text := '1'; UpdatePreview; end; end; procedure TFormMain.btnPrevPageClick(Sender: TObject); begin if Pdf.Active and (FCurrentPreviewPage > 1) then begin Dec(FCurrentPreviewPage); edtPreviewPage.Text := IntToStr(FCurrentPreviewPage); UpdatePreview; end; end; procedure TFormMain.btnNextPageClick(Sender: TObject); begin if Pdf.Active and (FCurrentPreviewPage < Pdf.PageCount) then begin Inc(FCurrentPreviewPage); edtPreviewPage.Text := IntToStr(FCurrentPreviewPage); UpdatePreview; end; end; procedure TFormMain.btnLastPageClick(Sender: TObject); begin if Pdf.Active then begin FCurrentPreviewPage := Pdf.PageCount; edtPreviewPage.Text := IntToStr(FCurrentPreviewPage); UpdatePreview; end; end; |
Zoom Control
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
procedure TFormMain.cmbZoomChange(Sender: TObject); begin case cmbZoom.ItemIndex of 0: FCurrentZoom := 50; 1: FCurrentZoom := 75; 2: FCurrentZoom := 100; 3: FCurrentZoom := 125; 4: FCurrentZoom := 150; 5: FCurrentZoom := 200; else FCurrentZoom := 100; end; UpdatePreview; end; |
Handling Page Rotation
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function GetPrintRotation(Rotation: TRotation): TRotation; begin // Adjust rotation for printing (printer coordinate system) case Rotation of ro90: Result := ro270; ro270: Result := ro90; else Result := Rotation; end; end; // Use in printing Bitmap := Pdf.RenderPage(0, 0, Width, Height, GetPrintRotation(Pdf.PageRotation), [rePrinting]); |
Save/Load Settings
|
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 |
procedure TFormMain.SaveSettings; var Ini: TIniFile; begin Ini := TIniFile.Create(FSettingsFile); try Ini.WriteInteger('Print', 'Quality', cmbQuality.ItemIndex); Ini.WriteInteger('Print', 'Scaling', cmbScaling.ItemIndex); Ini.WriteInteger('Print', 'Copies', spnCopies.Value); Ini.WriteBool('Print', 'Collate', chkCollate.Checked); Ini.WriteInteger('Preview', 'Zoom', FCurrentZoom); finally Ini.Free; end; end; procedure TFormMain.LoadSettings; var Ini: TIniFile; begin if FileExists(FSettingsFile) then begin Ini := TIniFile.Create(FSettingsFile); try cmbQuality.ItemIndex := Ini.ReadInteger('Print', 'Quality', 1); cmbScaling.ItemIndex := Ini.ReadInteger('Print', 'Scaling', 1); spnCopies.Value := Ini.ReadInteger('Print', 'Copies', 1); chkCollate.Checked := Ini.ReadBool('Print', 'Collate', False); FCurrentZoom := Ini.ReadInteger('Preview', 'Zoom', 100); finally Ini.Free; end; end; end; |
Use Cases
- Document Printing – High-quality printing of PDF documents
- Batch Printing – Print multiple documents in sequence
- Report Distribution – Print reports for distribution
- Proof Printing – Print proofs before final production
Conclusion
The Print PDF demo shows how to implement professional PDF printing with PDFium VCL. From simple single-page printing to advanced multi-copy jobs with preview and quality settings, the component provides everything you need.
The RenderPage method with the rePrinting option ensures optimal output for printers, while the preview functionality lets users verify their settings before printing.
Add professional PDF printing to your applications with PDFium Delphi Component.