unit main; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, Grids, Types, GridPrn, GridPrnPreviewDlg, fpspreadsheet, fpstypes, fpspreadsheetgrid, fpspreadsheetctrls, fpsAllFormats; type { TMainForm } TMainForm = class(TForm) Bevel1: TBevel; btnPrint: TButton; btnPreview: TButton; btnOpenFile: TButton; GridPrinter1: TGridPrinter; GridPrintPreviewDialog1: TGridPrintPreviewDialog; OpenDialog1: TOpenDialog; ButtonPanel: TPanel; sWorkbookSource1: TsWorkbookSource; sWorkbookTabControl1: TsWorkbookTabControl; sWorksheetGrid1: TsWorksheetGrid; procedure btnPrintClick(Sender: TObject); procedure btnPreviewClick(Sender: TObject); procedure btnOpenFileClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure GridPrinter1AfterPrint(Sender: TObject); procedure GridPrinter1BeforePrint(Sender: TObject); procedure GridPrinter1GetColCount(Sender: TObject; AGrid: TCustomGrid; var AColCount: Integer); procedure GridPrinter1GetRowCount(Sender: TObject; AGrid: TCustomGrid; var ARowCount: Integer); procedure GridPrinter1PrintCell(Sender: TObject; AGrid: TCustomGrid; ACanvas: TCanvas; ACol, ARow: Integer; ARect: TRect); private FGridCanvas: TCanvas; FOldZoomFactor: Double; FOldPadding: Integer; FNewPadding: Integer; public end; var MainForm: TMainForm; implementation {$R *.lfm} uses Variants; type TsWorksheetGridOpener = class(TsWorksheetGrid); { TMainForm } procedure TMainForm.FormCreate(Sender: TObject); begin if ParamCount > 0 then sWorkbookSource1.LoadFromSpreadsheetFile(ParamStr(1)); end; procedure TMainForm.GridPrinter1BeforePrint(Sender: TObject); begin // We want to draw on the printer/preview canvas. Therefore, we assign the // grid's canvas to that of the GridPrinter. In order to restore the grid // canvas after printing, we store its old canvas. FGridCanvas := sWorksheetGrid1.Canvas; sWorksheetGrid1.Canvas := GridPrinter1.Canvas; // FOldPadding := varCellPadding; FNewPadding := GridPrinter1.Padding - varCellPadding; // The TsWorksheetGrid paints the grid lines in the DrawCell method. To // avoid duplicate drawing (which, BTW, is offset by 1 pixel) we turn off // painting of the grid lines by the grid printer. GridPrinter1.Options := GridPrinter1.Options - [ gpoHorGridLines, gpoVertGridLines, gpoFixedHorGridLines, gpoFixedVertGridLines, gpoHeaderBorderLines ]; // Store the worksheetgrid's ZoomFactor. We may have to change it FOldZoomFactor := sWorksheetGrid1.ZoomFactor; sWorksheetGrid1.ZoomFactor := GridPrinter1.PrintScaleFactor; end; procedure TMainForm.GridPrinter1AfterPrint(Sender: TObject); begin // Restore the worksheetgrid's Canvas. sWorksheetGrid1.Canvas := FGridCanvas; varCellPadding := FOldPadding; // Restore drawing of the grid lines by the grid printer. GridPrinter1.Options := GridPrinter1.Options + [ gpoHorGridLines, gpoVertGridLines, gpoFixedHorGridLines, gpoFixedVertGridLines, gpoHeaderBorderLines ]; // Restore the worksheetgrid's ZoomFactor sWorksheetGrid1.ZoomFactor := FOldZoomFactor; end; procedure TMainForm.btnPrintClick(Sender: TObject); begin GridPrinter1.Print; end; procedure TMainForm.btnPreviewClick(Sender: TObject); begin GridPrintPreviewDialog1.Execute; end; procedure TMainForm.btnOpenFileClick(Sender: TObject); begin if OpenDialog1.FileName <> '' then OpenDialog1.InitialDir := ExtractFileDir(OpenDialog1.FileName); if OpenDialog1.Execute then sWorkbookSource1.LoadFromSpreadsheetFile(OpenDialog1.FileName); end; procedure TMainForm.GridPrinter1GetColCount(Sender: TObject; AGrid: TCustomGrid; var AColCount: Integer); begin if sWorksheetGrid1.Worksheet <> nil then AColCount := sWorksheetGrid1.Worksheet.GetLastOccupiedColIndex + 1 + sWorksheetGrid1.HeaderCount; end; procedure TMainForm.GridPrinter1GetRowCount(Sender: TObject; AGrid: TCustomGrid; var ARowCount: Integer); begin if sWorksheetGrid1.Worksheet <> nil then ARowCount := sWorksheetGrid1.Worksheet.GetLastOccupiedRowIndex + 1 + sWorksheetGrid1.HeaderCount; end; procedure TMainForm.GridPrinter1PrintCell(Sender: TObject; AGrid: TCustomGrid; ACanvas: TCanvas; ACol, ARow: Integer; ARect: TRect); var worksheet: TsWorksheet; cell: PCell; gr, gc: Integer; begin worksheet := sWorksheetGrid1.Worksheet; if worksheet <> nil then begin varCellPadding := FNewPadding; // FIXME TsWorksheetGridOpener(sWorksheetGrid1).DrawCell(ACol, ARow, ARect, []); gr := sWorksheetGrid1.GetWorksheetRow(ARow); gc := sWorksheetGrid1.GetWorksheetCol(ACol); cell := worksheet.FindCell(gr, gc); if worksheet.HasComment(cell) then TsWorksheetGridOpener(sWorksheetGrid1).DrawCommentMarker(ARect); // FIXME if uffBorder in worksheet.ReadUsedFormatting(cell) then TsWorksheetGridOpener(sWorksheetGrid1).DrawCellBorders(gc, gr, ARect, cell) end; end; end.