首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 生成 PDF 實戰教學:使用 FPDF 從零建立專業報表

     編輯:PHP 相關知識

為什麼選擇 FPDF?

  • 純 PHP 實作,無需安裝擴充套件(對比 PDFlib)
  • 輕量級(單檔 ~100KB),部署簡單
  • 支援 UTF-8(需搭配字型檔)、圖片、表格、頁首頁尾、自動分頁
  • 適合發票、報表、證書、標籤等固定版面文件

快速上手:Hello World

require_once 'fpdf/fpdf.php';

$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Helvetica', 'B', 24);
$pdf->Cell(0, 20, 'Hello, FPDF!', 0, 1, 'C');
$pdf->Output('hello.pdf', 'D'); // D=下載, I=瀏覽器顯示, F=存檔

核心類別繼承:建立專屬報表類別

require_once 'fpdf/fpdf.php';

class MedalReport extends FPDF {
    // 覆寫 Header:每頁自動列印
    function Header() {
        $this->SetFont('Helvetica', 'B', 16);
        $this->Cell(0, 10, '2024 國際賽事獎牌榜', 0, 1, 'C');
        $this->Line(10, $this->GetY(), 200, $this->GetY());
        $this->Ln(5);
    }
    
    // 覆寫 Footer:頁碼
    function Footer() {
        $this->SetY(-15);
        $this->SetFont('Helvetica', 'I', 8);
        $this->Cell(0, 10, 'Page ' . $this->PageNo() . '/{nb}', 0, 0, 'C');
    }
    
    // 自訂方法:繪製單行獎牌資料
    function AddCountryRow($country, $flagPath, $gold, $silver, $bronze) {
        $y = $this->GetY();
        
        // 國旗
        if (file_exists($flagPath)) {
            $this->Image($flagPath, 12, $y, 8);
        }
        
        // 國家名
        $this->SetFont('Helvetica', 'B', 12);
        $this->SetX(25);
        $this->Cell(50, 10, $country, 0, 0, 'L');
        
        // 獎牌數(置中、彩色)
        $this->SetFont('Helvetica', 'B', 12);
        $this->SetTextColor(200, 160, 12); // 金
        $this->Cell(25, 10, (string)$gold, 0, 0, 'C');
        $this->SetTextColor(170, 162, 138); // 銀
        $this->Cell(25, 10, (string)$silver, 0, 0, 'C');
        $this->SetTextColor(187, 120, 68);  // 銅
        $this->Cell(25, 10, (string)$bronze, 0, 0, 'C');
        $this->SetTextColor(0, 0, 0); // 重設顏色
        
        $this->Ln(12);
        
        // 檢查是否需要換頁
        if ($this->GetY() > 270) $this->AddPage();
    }
}

資料準備與報表產生

$medalData = [
    ['country' => '中華人民共和國', 'flag' => 'flags/cn.png', 'gold' => 40, 'silver' => 27, 'bronze' => 24],
    ['country' => '美國', 'flag' => 'flags/us.png', 'gold' => 39, 'silver' => 41, 'bronze' => 33],
    ['country' => '日本', 'flag' => 'flags/jp.png', 'gold' => 27, 'silver' => 14, 'bronze' => 17],
    // ... 更多資料
];

$pdf = new MedalReport();
$pdf->AliasNbPages(); // 啟用 {nb} 總頁數佔位符
$pdf->AddPage();

// 表頭
$pdf->SetFont('Helvetica', 'B', 11);
$pdf->SetFillColor(230, 230, 230);
$pdf->Cell(25, 8, '', 1, 0, 'C', true); // 國旗欄
$pdf->Cell(50, 8, '國家/地區', 1, 0, 'C', true);
$pdf->Cell(25, 8, '金牌', 1, 0, 'C', true);
$pdf->Cell(25, 8, '銀牌', 1, 0, 'C', true);
$pdf->Cell(25, 8, '銅牌', 1, 1, 'C', true);

// 資料列
foreach ($medalData as $row) {
    $pdf->AddCountryRow($row['country'], $row['flag'], $row['gold'], $row['silver'], $row['bronze']);
}

// 總計列
$pdf->SetFont('Helvetica', 'B', 11);
$pdf->SetFillColor(240, 240, 240);
$pdf->Cell(75, 8, '總計', 1, 0, 'R', true);
$pdf->Cell(25, 8, array_sum(array_column($medalData, 'gold')), 1, 0, 'C', true);
$pdf->Cell(25, 8, array_sum(array_column($medalData, 'silver')), 1, 0, 'C', true);
$pdf->Cell(25, 8, array_sum(array_column($medalData, 'bronze')), 1, 1, 'C', true);

// 輸出
$pdf->Output('medal_report_2024.pdf', 'D');

關鍵方法速查表

方法用途常用參數
AddPage()新增頁面orientation ('P'/'L'), size ('A4', 'Letter', [w,h])
SetFont(family, style, size)設定字型style: '', 'B', 'I', 'U' 或組合
Cell(w, h, txt, border, ln, align, fill)繪製儲存格(核心排版單元)w=0 延伸至右邊界, ln: 0/1/2 換行模式
MultiCell(w, h, txt, border, align, fill)多行文字(自動換行)適合長文本、地址
Image(file, x, y, w, h, type, link)插入圖片支援 JPG, PNG, GIF; w/h=0 保持比例
Ln(h)換行h=null 使用上一行高度
SetTextColor(r, g, b)設定文字顏色RGB 0-255
SetFillColor(r, g, b)設定填滿顏色搭配 Cell(fill=true) 使用
Line(x1, y1, x2, y2)畫線分隔線、表格框線
Output(name, dest)輸出 PDFdest: I(顯示), D(下載), F(存檔), S(回傳字串)

中文支援完整方案

FPDF 預設不支援中文,需使用 TTF 字型轉換:

  1. 下載開源中文字型(如 Noto Sans TC)
  2. 使用 makefont.php 工具轉換:
php makefont.php /path/to/NotoSansTC-Regular.otf /path/to/fpdf/font/unifont/ cp1252
  1. 在程式中載入:
$pdf->AddFont('NotoSansTC', '', 'NotoSansTC-Regular.php');
$pdf->AddFont('NotoSansTC', 'B', 'NotoSansTC-Bold.php');
$pdf->SetFont('NotoSansTC', '', 12);

替代方案:若專案大量中文排版,建議改用 TCPDF 或 Dompdf(支援 HTML/CSS 轉 PDF)。

常見問題排查

問題原因解決
中文顯示 □□□字型未包含中文字形AddFont 載入支援中文的 TTF 字型
表格跨頁斷裂Cell 無法自動分頁使用 MultiCell 或手動檢查 GetY() 呼叫 AddPage()
圖片不顯示路徑錯誤/格式不支援使用絕對路徑、確認副檔名、檢查 GD 擴充套件
記憶體耗盡大量圖片/資料分批產生、增加 memory_limit、輸出到檔案而非字串

進階技巧:動態表格與 QR Code

// 簡易表格輔助類
class PDF_Table extends FPDF {
    function DrawTable($headers, $data, $colWidths, $aligns = []) {
        // 表頭
        $this->SetFont('', 'B');
        $this->SetFillColor(230, 230, 230);
        foreach ($headers as $i => $h) {
            $this->Cell($colWidths[$i], 8, $h, 1, 0, 'C', true);
        }
        $this->Ln();
        
        // 資料
        $this->SetFont('', '');
        $fill = false;
        foreach ($data as $row) {
            if ($this->GetY() > 270) { $this->AddPage(); $this->DrawTable($headers, [], $colWidths); }
            $fill = !$fill;
            foreach ($row as $i => $cell) {
                $a = $aligns[$i] ?? 'L';
                $this->Cell($colWidths[$i], 7, $cell, 1, 0, $a, $fill);
            }
            $this->Ln();
        }
    }
}

// QR Code 整合 (需安裝 phpqrcode)
require_once 'phpqrcode/qrlib.php';
QRcode::png('https://example.com/verify/12345', 'qrcode.png', QR_ECLEVEL_L, 4);
$pdf->Image('qrcode.png', 160, 10, 25);

FPDF 以「程式碼即排版」的方式給予最大彈性,適合固定版面、精確定位的報表需求。掌握 Cell/MultiCell/Image 三大核心元件,搭配 Header/Footer/繼承機制,即可建構專業級 PDF 產生系統。

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