GridPrinter

From Lazarus wiki
Revision as of 01:23, 12 December 2022 by Wp (talk | contribs) (→‎TGridPrinter: Header/Footer and Margins classes)
Jump to navigationJump to search

Template:GridPrinter

About

GridPrinter

TGridPrinter is a component to simplify printing of string grids or other descendants of TCustomGrid. It is bundled together with a ready-made print preview dialog, TGridPrintPreviewDialog, as well as standard actions to trigger printing or to show the preview dialog without writing a single line of code.

Author: Werner Pamler.

License: Modified LGPL-2 (with linking exception, like Lazarus LCL).

Download and Installation

Release version

The package is made available for installation by the Online-Package-Manager. Additionally, a zip file with the most recent release version can be found at Lazarus CCR at SourceForge; unzip the file into any folder; load the file gridprinterpkg.lpk into Lazarus and click Use > Install.

Development version

The current development version is hosted at Lazarus CCR. Use SVN to check it out, or download the zipped snapshot from this page. Install by loading the gridprinterpkg.lpk package file into Lazarus and clicking Use > Install.

Getting Started

How can I print a StringGrid?

Nothing easier when you have the GridPrinter package...

  • Drop a TGridPrinter component on the form.
  • Link its Grid property to the StringGrid that you want to print.
  • In the OnClick handler of the button or menu item that is supposed to start the print-out, call the Print method of the GridPrinter. That's all.
procedure TForm1.PrintButtonClick(Sender: TObject);
begin
  GridPrinter1.Print;
end;

How can I see a preview of the printout before the printer starts to waste paper?

  • Drop also a TGridPrintPreviewDialog on the form.
  • Links its GridPrinter property to the GridPrinter instance that you had added in the previous exercise.
  • In the OnClick handler of the button or menu item that is supposed to show the preview, call the Execute method of the GridPrintPreviewDialog.
  • In the preview dialog you can scroll through the pages, zoom to various levels, change page orientation, adjust the page margins by dragging with the mouse, or add a header and/or footer. Of course, you can also print here, too.
procedure TForm1.PrintPreviewButtonClick(Sender: TObject);
begin
  GridPrintPreviewDialog1.Execute;
end;

I have several printers and want to make sure that the print-out goes to the right one

TGridPrinter has a property ShowPrintDialog which controls whether a print dialog should be displayed before printing starts. The kind of dialog is determined by the following options:

  • gpdNone: no print dialog
  • gpdPageSetup: shows a TPageSetupDialog. Here you can select the paper size and set page orientation as well as page margins.
  • gpdPrintDialog: shows a TPrintDialog where you can select the printer, the number of copies and the range of printed pages.
  • gpdPrinterSetup: shows TPrinterSetupDialog. Here you can select the printer, the paper size and the page orientation.

Can individual cell formatting by the OnPrepareCanvas event be applied to the printout?

Yes. The TGridPrinter fires an OnPrepareCanvas event, too. Both even can share the same event handler. You only should be careful to use the correct Canvas when handling the event: When the Sender of the event is the grid, you must refer to the grid's Canvas, and when the Sender is the GridPrinter you must use that Canvas exposed by the GridPrinter; during printing this is the printer's Canvas, and when the preview is painted it is the Canvas of a temporary TBitmap.

Let's assume that your OnPrepareCanvas handler is supposed to paint the column title in bold type face. This could be done by the following code. The procedure must be assigned to the OnPrepareCanvas of both grid and GridPrinter.

procedure TForm1.PrepareCanvasHandler(Sender: TObject; ACol, ARow: Integer; AState: TGridDrawState);
var
  lCanvas: TCanvas;
begin
  if Sender = StringGrid1 then
    lCanvas := StringGrid1.Canvas
  else
  if Sender = GridPrinter1 then
    lCanvas := GridPrinter1.Canvas
  else
    raise Exception.Create('Unknown sender of OnPrepareCanvas.');

  if ARow < StringGrid1.FixedRows then
    lCanvas.Font.Style := [fsBold];
end;

Can I print a DBGrid?

Yes, but it requires a bit more work than just connecting it to the Grid property of the GridPrinter. A DBGrid displays data from a TDataset, but it keeps only a small number of records. But you usually want to print the entire dataset, rather than just the section loaded into the DBGrid.

At first we must tell the GridPrinter how many rows it will have to print. This can be done by providing a handler for the event OnGetRowCount in which we pass the dataset's RecordCount value to the provided parameter. Note that the title row must be included here. Note also that the RecordCount property often is only correct after the dataset pointer has been moved to the last record and back to the first record.

procedure TForm1.GridPrinter1GetRowCount(Sender: TObject; AGrid: TCustomGrid;
  var ARowCount: Integer);
var
  dbGrid: TDBGrid;
begin
  dbGrid := AGrid as TDBGrid;
  dbGrid.Datasource.Dataset.Last;
  dbGrid.Datasource.Dataset.First;
  ARowCount := dbGrid.Datasource.Dataset.RecordCount + 1;  // we must 1 for the header row
end;

In order to provide the cell texts for the GridPrinter we must write a handler for the OnGetCellText event which is fired whenever the GridPrinter needs any cell text. We will return to this in a minute. We must first clarify the process flow. The easiest way to get the cell texts is by iterating over the entire dataset. Provide a handler for the OnBeforePrint event which moves the dataset to its first record:

procedure TForm1.GridPrinter1BeforePrint(Sender: TObject);
begin
  DBGrid1.DataSource.Dataset.First;
end;

Another event, OnNewLine fires when the GridPrinter has finished printing a line and wants to proceed with the next one. This means we must advance the dataset to its next record. However, if a printed line extends over several pages we must be able to return to this record for completing its printout on the next page. Generally this must be handled by setting bookmarks - please see the example dbgrid2 in the GridPrinter installation folder for details. For some flat-file databases such as dBase, BufDataset etc. there is a simpler way by using the RecNo property of the dataset. This is a running number for each record starting at 1 with the first record. So, in the OnNewLine event we simply set the dataset's RecNo to the row parameter passed to the event:

procedure TForm1.GridPrinter1NewLine(Sender: TObject; AGrid: TCustomGrid;
  ARow: Integer);
var
  dbGrid: TDBGrid;
begin
  dbGrid := AGrid as TDBGrid;
  BufDataset1.RecNo := ARow;  // RecNo starts at 1. ARow starts at 1, too, since we display the header row   
end;

Then, within each row, the GridPrinter proceeds from grid column to grid column. In order to extract the cell text, we determine the column col from the ACol parameter of the OnGetCellTextevent and thus have access to the dataset field in that column (col.Field). Finally, we can query the cell text by calling the field's AsString method. Special handling is required for the very first row (ARow = 0) which corresponds to the grid titles:

procedure TForm1.GridPrinter1GetCellText(Sender: TObject; AGrid: TCustomGrid;
  ACol, ARow: Integer; var AText: String);
var
  dbGrid: TDBGrid;
  col: TColumn;
  colOffs: Integer;
begin
  AText := '';

  dbGrid := AGrid as TDBGrid;

  if (dgIndicator in dbGrid.Options) then
    colOffs := 1
  else
    colOffs := 0;

  if ACol < colOffs then
    exit;

  col := dbGrid.Columns[ACol - colOffs];

  if (ARow = 0) then
    AText := col.FieldName
  else
    AText := col.Field.AsString;
end;

As already mentioned, there are DBGrid sample projects in the GridPrinter installation to demonstrate the steps for DBGrid printing.

Documentation

TGridPrinter

Public methods

  • function CreatePreviewBitmap(APageNo, APercentage: Integer): TBitmap -- Creates the preview bitmap for the printout of the specified page. The bitmap is scaled by the given percentage relative to the original pager size (100).
  • function GetCellText(ACol, ARow: Integer): String -- Returns the text to be printed for the grid cell at the given row and column indices.
  • procedure Print -- Prints the grid.
  • procedure ScaleToPages(NumHor, NumVert: Integer) -- Scales the printout such that it fits on NumHor pages horizontally and NumVert pages vertically.
  • function ScaleX(AValue: Integer): Integer -- General scaling function for conversion of horizontal screen pixels to pixels on the printer or the preview bitmap.
  • function ScaleY(AValue: Integer): Integer -- General scaling function for conversion of vertical screen pixels to pixels on the printer or the preview bitmap.
  • procedure UpdatePreview -- Fires the event OnUpdatePreview if the GridPrinter is in preview mode.

Public properties

  • Canvas: TCanvas (read-only) -- Canvas currently used by the GridPrinter. This is either the printer canvas or the canvas of the preview bitmap sent to the TGridPrintPreview component.
  • ColCount: Integer (read-only) -- Number of columns to be printed
  • ColWidth[AIndex: Integer]: Double (read-only) -- width of the specified column, given in pixels of the current output device (printer or preview bitmap)

Published properties and events

Properties

  • Grid: TCustomGrid -- links to the grid to be printed. Ideally, this should be a TStringGrid, but other descendants of TCustomGrid can be printed as well when the appropriate event handlers are provided.
  • BorderLineColor: TColor -- line color of the outer border of the printed grid.
  • BorderLineWidth: Double -- line width of the outer border of the printed grid, in millimeters. If negative, the scaled value of the grid's GridLineWidth is used.
  • FileName: String -- name of the file which is printed. Is displayed in the header of footer of the printout/preview and is used to replace the symbols $FULL_FILENAME, $FILENAME, $PATH.
  • FixedLineColor: TColor -- line color of the dividing line between fixed and normal cells in the printout/preview
  • FixedLineWidth: Double -- line width of the dividing line between fixed and normal cells in the printout/preview, in millimeters. If negative, the scaled value of the grid's GridLineWidth is used.
  • Footer: TGridPrnHeaderFooter -- parameters for printing a footer at the bottom of each page. See TGridPrnHeaderFooter
  • FromPage: Integer -- defines the first page to be printed. Any value less than 1 is interpreted as "first page".
  • GridLineColor: TColor -- color of the inner grid lines
  • GridLineWidth: Double -- line width of the inner grid lines, in millimeters. If negative, the scaled value of the grid's GridLineWidth is used.
  • Header: TGridPrnHeaderFooter -- parameters for printer a header at the top of each page. See TGridPrnHeaderFooter
  • Margins: TGridPrnMargins -- defines page margins, in millimeters
  • Monochrome: Boolean -- prints the grid only with black color
  • Options: TGridPrnOptions -- options for fine-tuning the printout
    • gpoCenterHor -- centers the printed table on the page horizontally
    • gpoCenterVert -- centers the printed table on the page vertically
    • gpoHorGridLines -- overrides the corresponding grid option and can be used to show/hide horizontal grid lines between the printed rows
    • gpoVertGridLines -- overrides the corresponding grid option and can be used to show/hide vertical grid lines between the printed columns
    • gpoFixedHorGridLines -- can be used to show/hide horizontal grid lines between the fixed cells
    • gpoFixedVertGridLines -- can be used to show/hide vertical grid lines between the fixed cells
    • gpoHeaderBorderLines -- can be used to show/hide dividing lines between the fixed and normal cells
    • gpoOuterBorderLines -- can be used to show/hide outer lines around the grid
  • Orientation: TPrinterOrientation -- defines the page orientation: poPortrait, poLandscape, poReverseLandscape, poReversePortrait (declared in the Printers unit).
  • PrintOrder: TGridPrnOrder -- large tables are wrapped into several pages. This property defines whether rows will be completed first (poRowsFirst), or columns (poColsFirst)
  • PrintScaleFactor: Double -- scaling factor for the printout. Default: 1.0
  • ShowPrintDialog: TGridPrnDialog -- determines whether one of the Lazarus print dialog should be shown before printing begins: gpdNone, gpdPageSetup, gpdPrintDialog, gpdPrinterSetup
  • ToPage: Integer -- defines the last page to be printed. Any value larger than the real page count prints to the last page.

Events

  • OnAfterPrint -- Fires when printing is finished.
  • OnBeforePrint -- Fires before printing begins. The printer has not yet received its BeginDoc command.
  • OnGetCellText -- Whenever the GridPrinter needs to know the text in a specific cell it sends this event. The text to be printed can be passed in a parameter. This way non-standard grid which have different cell technology can be printed as well.
  • OnGetRowCount -- In this event the application can tell the GridPrinter the number of rows to be printed. This is useful when a DBGrid which holds only a small parts of all rows of a dataset.
  • OnGetColCount -- similar to OnGetRowCount, just for columns, rather than rows.
  • OnLinePrinted -- Fires when the GridPrinter has finished printing a specific lin
  • OnNewLine -- Fires when the GridPrinter starts printing a new line of cells.
  • OnNewPage -- Fires when the GridPrinter begins a new page.
  • OnPrepareCanvas -- Similar to the equally-named event of the grid. When the canvas for printing a cell has been prepared the user has the opportunity here to override the selection of colors, fonts, alignments etc. The handler can be shared between grid and GridPrinter, it only must be guaranteed that the correct canvas is used in the code.
  • OnPrintCell -- When this event has a handler it completely replaces the built-in code for printing a cell. Can be used for printing very specific grids.
  • OnUpdatePreview -- When the GridPrinter runs in preview mode the application can be notified, for example, when some parameter has been changed and the preview can repaint itself.
TGridPrnHeaderFooter

This is the class of the header and footer lines which can be printed at the top and bottom of each page

Published properties

  • Font: TFont -- Font used for printing the header/footer
  • LineColor: TColor -- Color of the dividing line printed below the header/above the footer
  • LineWidth: Double -- Line width of the dividing line printed below the header/above the footer, in millimeters
  • SectionSeparator: String -- The header/footer text can consist of a left-aligned, centered, and a right-aligned part, all specified together in the Textproperty. Defines the separator character or string between these three sections, default: '|'.
  • ShowLine: Boolean -- Shows/hides the dividing line printed below the header/above the footer
  • Text: String -- Contains the text to be displayed in the header/footer. It can consist of up to three sections, separated by the SectionSeparator, which are printed at the left, in the center or at the right end of the header/footer. Moreover, the Text can contain the following symbols which are replaced during printing by the current values:
    • $DATE -- replaced by current date
    • $PAGECOUNT -- total number of pages to be printed
    • $PAGE -- number of the currently printed page. First page number is 1.
    • $FULL_FILENAME -- is replaced by the full path of the FileName property of the GridPrinter
    • $FILENAME -- is replaced by the FileName property of the GridPrinter after removal of the file path
    • $PATH -- is replaced by the path to the FileName property of the GridPrinter.
    • $TIME -- replaced by current time.
  • Visible: Boolean -- shows/hides the header/footer

Public properties

  • ProcessedText[AIndex: TGridPrnHeaderFooterSection]: String where TGridPrnHeaderFooterSection = (hfsLeft, hfsCenter, hfsRight) -- returns the header/footer text in the specified section after replacement of the symbols.
  • SectionText[AIndex: TGridPrnHeaderFooterSection]: String where TGridPrnHeaderFooterSection = (hfsLeft, hfsCenter, hfsRight) -- returns the specified section Text
TGridPrnMargins

This class collects the parameters for the page margins:

Published properties

  • Left: Double -- left margin, in millimeters
  • Top -- top margin, in millimeters
  • Right -- right margin, in millimeters
  • Bottom -- bottom margin, in millimeters
  • Header -- margin to the top of the header, in millimeters. Note that it is not checked that the header does not overlap with the grid.
  • Footer -- margin to the bottom of the footer, in millimeters. Note that it is not checked that the footer does not overlap with the grid.

TGridPrintPreview