You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FPDF生成PDF报表时页眉跨页样式不一致问题求助

解决FPDF多页面页眉样式不一致的问题

你遇到的这个问题其实很常见——根源出在headerSummary()方法里的SetLeftMargin(50)调用上。这个方法会全局修改整个PDF文档的左边距,第一页执行完这个操作后,后续所有页面的页眉都会继承这个新的50px左边距,导致原本应该居中的页眉内容偏移,看起来样式异常。

修复方案

我们只需要在修改左边距前保存原始值,绘制完表格后再恢复回去,就能让页眉不受表格边距设置的影响:

class Report extends FPDF {
    function header() {
        $this->Image('logo.png', 10, 6, 25, 25);
        $this->SetFont('Arial', 'B', 14);
        $this->Cell(200, 5, 'Cabarrus County GOP Convention' . ' ' . date("Y"), 0, 0, 'C');
        $this->Ln();
        $this->SetFont('Arial', '', 12);
        $this->Cell(200, 10, 'Attendance Report', 0, 0, 'C');
        $this->Ln(25);
    }

    function footer() {
        $this->SetY(-15);
        $this->SetFont('Arial', '', 8);
        $this->Cell(0, 10, 'Page '. $this->PageNo(), 0, 0,'R');
    }

    function headerSummary() {
        // 保存当前默认的左边距
        $originalMargin = $this->lMargin;
        
        $this->SetFont('Arial', 'B', 12);
        $this->Cell(275, 5, 'Summary', 0, 0, 'L');
        $this->Ln(10);
        $this->SetFont('Arial', 'B', 10);
        $this->SetLeftMargin(50); // 仅为表格设置临时左边距
        $this->Cell(20, 10, 'Precinct', 1, 0, 'C');
        $this->Cell(40, 10, 'Delegates Present', 1, 0, 'C');
        $this->Cell(40, 10, 'Delegates Absent', 1, 0, 'C');
        $this->Cell(20, 10, 'Total', 1, 0, 'C');
        $this->Ln();
        
        // 恢复原始左边距,确保后续页眉不受影响
        $this->SetLeftMargin($originalMargin);
    }

    function viewSummary() {
        // 同样,这里绘制表格时如果需要保持50的左边距,也要临时设置并恢复
        $originalMargin = $this->lMargin;
        $this->SetLeftMargin(50);
        
        $this->SetFont('Arial', '', 8);
        global $pdo;
        $sql = "SELECT IFNULL(m.precinct, 'Totals') as 'precinct', COUNT(at.member_id) as 'delegates_present', COUNT(ab.member_id) as 'delegates_absent', COUNT(at.member_id) + COUNT(ab.member_id) as 'total' FROM members m LEFT JOIN attendance as at ON at.member_id = m.id LEFT JOIN absence as ab ON ab.member_id = m.id GROUP BY m.precinct WITH ROLLUP;";
        $stmt = $pdo->prepare($sql);
        $stmt->execute();
        while($data = $stmt->fetch(PDO::FETCH_OBJ)) {
            $this->Cell(20, 10, $data->precinct, 1, 0, 'C');
            $this->Cell(40, 10, $data->delegates_present, 1, 0, 'C');
            $this->Cell(40, 10, $data->delegates_absent, 1, 0, 'C');
            $this->Cell(20, 10, $data->total, 1, 0, 'C');
            $this->Ln();
        }
        
        $this->SetLeftMargin($originalMargin);
    }
}

额外优化提示

如果你的表格数据较多会跨页,还可以在header()方法里添加判断,当不是第一页时自动重新绘制表格表头,这样跨页后的表格可读性会更好:

function header() {
    // 原有页眉代码不变
    $this->Image('logo.png', 10, 6, 25, 25);
    $this->SetFont('Arial', 'B', 14);
    $this->Cell(200, 5, 'Cabarrus County GOP Convention' . ' ' . date("Y"), 0, 0, 'C');
    $this->Ln();
    $this->SetFont('Arial', '', 12);
    $this->Cell(200, 10, 'Attendance Report', 0, 0, 'C');
    $this->Ln(25);
    
    // 非第一页时自动绘制表格表头
    if($this->PageNo() > 1) {
        $originalMargin = $this->lMargin;
        $this->SetFont('Arial', 'B', 10);
        $this->SetLeftMargin(50);
        $this->Cell(20, 10, 'Precinct', 1, 0, 'C');
        $this->Cell(40, 10, 'Delegates Present', 1, 0, 'C');
        $this->Cell(40, 10, 'Delegates Absent', 1, 0, 'C');
        $this->Cell(20, 10, 'Total', 1, 0, 'C');
        $this->Ln();
        $this->SetLeftMargin($originalMargin);
    }
}

这样修改后,所有页面的页眉都会保持一致的样式,同时表格的布局也不会受到影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:47:30