首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 直接列印 DBGrid 內容:所見即所得的報表輸出技巧

     編輯:Delphi

許多報表工具配置繁複,其實若只需「把 DBGrid 畫面原樣列印」,直接繪製到 Printer.Canvas 最簡單高效。利用螢幕與印表機解析度換算、DBGrid.Columns 寬度與標題,即可實現包含表頭、格線、分頁的完整列表列印,且使用者在 DBGrid 調整欄序、欄寬即時反映列印結果,真正做到所見即所得。

核心邏輯

  1. 取得印表機 DPI(GetDeviceCaps(Printer.Handle, LOGPIXELSX/Y))與螢幕 DPI,計算縮放比例 PointScale。
  2. 設定列印邊界(Left/Right/Top/Bottom Blank)、字體、行高(TextHeight + 間距)。
  3. 遍歷 DataSet 記錄,巢狀迴圈遍歷 DBGrid.Columns:
    • 計算列印座標 x, y。
    • 若超出頁寬則略過該欄;超出頁高則 Printer.NewPage 重置 y 並重印表頭。
    • Canvas.Rectangle 畫格線,TextOut 印標題(首行)或資料。
  4. 列印結束 Printer.EndDoc,提示完成。

完整代碼(Delphi 4 / Win98 驗證)

procedure TForm1.Button2Click(Sender: TObject);
const
  LeftBlank = 1; RightBlank = 1; TopBlank = 1; BottomBlank = 1; // 厘米
var
  PointX, PointY, PointScale, PrintStep: Integer;
  s: string; x, y, i: Integer;
begin
  // 1. 解析度與縮放
  PointX := Trunc(GetDeviceCaps(Printer.Handle, LOGPIXELSX) / 2.54);
  PointY := Trunc(GetDeviceCaps(Printer.Handle, LOGPIXELSY) / 2.54);
  PointScale := Trunc(GetDeviceCaps(Printer.Handle, LOGPIXELSX) / Screen.PixelsPerInch + 0.5);

  Printer.Orientation := poLandscape; // 橫向列印
  Printer.Canvas.Font.Name := '新細明體';
  Printer.Canvas.Font.Size := 10;

  s := '範例標題';
  PrintStep := Printer.Canvas.TextHeight(s) + 16; // 行高

  x := PointX * LeftBlank;
  y := PointY * TopBlank;

  if DataSource1.DataSet.Active and (DataSource1.DataSet.RecordCount > 0) then begin
    Printer.BeginDoc;
    DataSource1.DataSet.First;
    while not DataSource1.DataSet.Eof do begin
      for i := 0 to DBGrid1.FieldCount - 1 do begin
        // 欄寬換算後是否超出右邊界
        if (x + DBGrid1.Columns.Items[i].Width * PointScale) <= (Printer.PageWidth - PointX * RightBlank) then begin
          // 畫格線
          Printer.Canvas.Rectangle(x, y,
            x + DBGrid1.Columns.Items[i].Width * PointScale, y + PrintStep);
          // 印標題或資料
          if y = PointY * TopBlank then
            Printer.Canvas.TextOut(x + 8, y + 8, DBGrid1.Columns[i].Title.Caption)
          else
            Printer.Canvas.TextOut(x + 8, y + 8, DBGrid1.Fields[i].AsString);
        end;
        x := x + DBGrid1.Columns.Items[i].Width * PointScale;
      end;

      if y <> PointY * TopBlank then DataSource1.DataSet.Next;
      x := PointX * LeftBlank;
      y := y + PrintStep;

      // 分頁判斷
      if (y + PrintStep) > (Printer.PageHeight - PointY * BottomBlank) then begin
        Printer.NewPage;
        y := PointY * TopBlank;
      end;
    end;
    Printer.EndDoc;
    DataSource1.DataSet.First;
    ShowMessage('列印完成');
  end;
end;

優化方向

  • 支援欄位隱藏/顯示:檢查 Columns[i].Visible。
  • 自適應欄寬:依資料最長字串或標題動態計算。
  • 多頁表頭重複:已內建於分頁邏輯中。
  • 匯出 PDF:改用 TPrinter 相容元件或第三方 PDF 庫同樣邏輯繪製。

此法無需報表設計器、無額外元件,幾十行代碼解決 80% 列表列印需求,維護極簡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved