You need to enable JavaScript to run this app. 如何调整TStringGrid打印逻辑实现带页眉页脚页面的网格居中输出
优惠活动
大模型
产品
解决方案
定价
更多

如何调整TStringGrid打印逻辑实现带页眉页脚页面的网格居中输出

问题结论

完全不需要重构整套打印逻辑,现有代码框架只要调整坐标计算规则,就可以实现将TStringGrid在预设页眉页脚的页面空白区居中打印,不需要换全新的实现方案。

现有代码的核心问题

你当前的代码所有打印坐标都是硬编码固定值:

  • 网格横向所有坐标起点直接写死为页面最左侧X=0,完全没计算网格本身的总宽度
  • 纵向坐标直接写死从Y=300开始累加,既没匹配预留页眉页脚的边界位置,也没计算网格本身的总高度
    相当于直接把网格贴在页面左上角打印,自然没法实现居中定位。

调整思路

只需要在原有代码的坐标逻辑基础上,新增三个计算步骤即可:

  1. 先计算你要预留的空白可打印区域边界
    对照你的页面版式,把页眉、页脚、左右固定占位区域的位置换算成打印机画布坐标,定义出中间可用的空白矩形范围。比如页眉占页面顶部300打印单位、页脚占页面底部400打印单位、左右各留200边距,直接把这个范围存成一个TRect变量即可。
  2. 提前统计整个网格的实际打印总尺寸
    沿用你原有代码的缩放规则:每列实际打印宽度为5 * sGrid.ColWidths[列索引],每一行实际打印高度为固定150打印单位,循环累加出整个网格的总宽度、总高度。
  3. 计算居中偏移量
    • 横向居中偏移:可打印区域左边界 + (可打印区域总宽度 - 网格总宽度) / 2
    • 纵向居中偏移:可打印区域上边界 + (可打印区域总高度 - 网格总高度) / 2
      原有代码里所有硬编码的起点坐标(比如X方向的0、Y方向的300),全部替换成对应计算出来的偏移值即可。

可直接参考的核心调整代码片段

procedure PrintGrid(sGrid: TStringGrid; sTitle: string);
var
  X1, X2, Y1, Y2: Integer;
  TmpI, F: Integer;
  TR: TRect;
  // 新增变量:网格总尺寸、居中偏移、可打印区域
  GridTotalWidth, GridTotalHeight, OffsetX, OffsetY: Integer;
  PrintableArea: TRect;
begin
  Printer.Title := sTitle;
  Printer.BeginDoc;
  Printer.Canvas.Pen.Color  := 0;
  Printer.Canvas.Font.Name  := 'Times New Roman';
  Printer.Canvas.Font.Size  := 12;

  // ========= 新增的居中计算逻辑 =========
  // 1. 定义预留可打印区域:根据你的实际页面边距调整数值
  // 示例值:左边界200,上边界300,右边界=打印页宽-200,下边界=打印页高-400
  PrintableArea := Rect(
    200,
    300,
    Printer.PageWidth - 200,
    Printer.PageHeight - 400
  );

  // 2. 统计网格总打印尺寸
  GridTotalWidth := 0;
  for TmpI := 1 to sGrid.ColCount - 1 do
    GridTotalWidth := GridTotalWidth + 5 * sGrid.ColWidths[TmpI];
  GridTotalHeight := 150 * sGrid.RowCount; // 沿用原150单位固定行高

  // 3. 计算居中偏移坐标
  OffsetX := PrintableArea.Left + (PrintableArea.Right - PrintableArea.Left - GridTotalWidth) div 2;
  OffsetY := PrintableArea.Top + (PrintableArea.Bottom - PrintableArea.Top - GridTotalHeight) div 2;
  // =====================================

  // 原有列遍历逻辑,仅替换硬编码的起点坐标
  for F := 1 to sGrid.ColCount - 1 do
  begin
    // 原X1 := 0; 替换为基于偏移量计算
    X1 := OffsetX;
    for TmpI := 1 to (F - 1) do
      X1 := X1 + 5 * (sGrid.ColWidths[TmpI]);

    // 原Y1 := 300; 替换为基于偏移量计算
    Y1 := OffsetY;
    X2 := OffsetX;
    for TmpI := 1 to F do
      X2 := X2 + 5 * (sGrid.ColWidths[TmpI]);
    Y2 := Y1 + 150; // 表头行高固定150

    TR := Rect(X1, Y1, X2 - 30, Y2);
    Printer.Canvas.Font.Style := [fsBold];
    Printer.Canvas.Font.Size := 7;
    Printer.Canvas.TextRect(TR, X1 + 50, Y1 + 50, sGrid.Cells[F, 0]);
    Printer.Canvas.Font.Style := [];

    for TmpI := 1 to sGrid.RowCount - 1 do
    begin
      Y1 := OffsetY + 150 * TmpI;
      Y2 := OffsetY + 150 * (TmpI + 1);
      TR := Rect(X1, Y1, X2 - 30, Y2);
      Printer.Canvas.TextRect(TR, X1 + 50, Y1 + 50, sGrid.Cells[F, TmpI]);
    end;
  end;
  Printer.EndDoc;
end;

注意事项

  • 调整时不需要改动原有的字体设置、单元格绘制逻辑,仅替换坐标计算的基准值即可,不会影响原有打印的显示效果
  • 如果计算得到的偏移值为负数,说明网格总尺寸超过了预留的空白区域范围,可适当调低列宽、行高的缩放系数,保证网格能完整落在可打印区内,不会被页眉、页脚遮挡
  • 你原有代码里独立打印标题的逻辑,如果对应位置已经属于预留页眉区域,可以直接删掉,避免和预设的页眉内容重叠

内容的提问来源于stack exchange,提问作者PrimeBeat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 18:24:00