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

PHPExcel 在 ThinkPHP 中實現 Excel 導入導出完整實戰指南

     編輯:PHP 相關知識

ThinkPHP 整合 PHPExcel:從零構建 Excel 導入導出功能

PHPExcel(現已併入 PhpSpreadsheet)是 PHP 操作 Excel 最經典的庫。本文以 ThinkPHP 2.x/3.x 為例,詳細演示如何部署 PHPExcel、封裝通用操作類、構建控制器與視圖,實現「Excel 導入入庫」與「資料導出下載」雙向流程。

一、庫檔案部署

  1. 下載 PHPExcel(建議改用 PhpSpreadsheet)
  2. 建立目錄結構:
    ThinkPHP/Extend/Vendor/Excel/
        ├── PHPExcel.php
        └── PHPExcel/ (核心目錄)

二、封裝通用操作類 ExcelToArray

路徑:ThinkPHP/Extend/Library/ORG/Util/ExcelToArray.class.php

<?php
class ExcelToArray {
    public function __construct() {
        Vendor('Excel.PHPExcel');
        Vendor('Excel.PHPExcel.IOFactory');
    }

    /**
     * 讀取 Excel 轉為二維陣列
     * @param string $filename 檔案路徑
     * @param string $encode 編碼
     * @param string $file_type xls|xlsx
     * @return array
     */
    public function read($filename, $encode, $file_type) {
        $type = strtolower($file_type);
        if ($type === 'xls') {
            Vendor('Excel.PHPExcel.Reader.Excel5');
            $reader = PHPExcel_IOFactory::createReader('Excel5');
        } elseif ($type === 'xlsx') {
            Vendor('Excel.PHPExcel.Reader.Excel2007');
            $reader = PHPExcel_IOFactory::createReader('Excel2007');
        } else {
            throw new Exception('不支援的檔案格式');
        }

        $reader->setReadDataOnly(true);
        $objPHPExcel = $reader->load($filename);
        $sheet = $objPHPExcel->getActiveSheet();
        $highestRow = $sheet->getHighestRow();
        $highestCol = $sheet->getHighestColumn();
        $colIndex = PHPExcel_Cell::columnIndexFromString($highestCol);

        $data = [];
        for ($row = 1; $row <= $highestRow; $row++) {
            for ($col = 0; $col < $colIndex; $col++) {
                $data[$row][] = (string)$sheet->getCellByColumnAndRow($col, $row)->getValue();
            }
        }
        return $data;
    }

    /**
     * 導出陣列資料為 Excel 下載
     * @param array $data 二維陣列 [['username'=>..., 'password'=>..., 'sex'=>...], ...]
     * @param string $name 下載檔名
     */
    public function push($data, $name = 'Excel') {
        $objPHPExcel = new PHPExcel();
        // 文件屬性
        $objPHPExcel->getProperties()
            ->setCreator('System')
            ->setLastModifiedBy('System')
            ->setTitle('Export')
            ->setSubject('Data Export')
            ->setDescription('Backup')
            ->setKeywords('excel')
            ->setCategory('result file');

        // 寫入標題列(可動態生成)
        $headers = ['username', 'password', 'sex'];
        foreach ($headers as $i => $h) {
            $objPHPExcel->setActiveSheetIndex(0)->setCellValueByColumnAndRow($i, 1, $h);
        }

        // 寫入資料
        foreach ($data as $i => $row) {
            $r = $i + 2;
            $objPHPExcel->getActiveSheet()->setCellValue('A' . $r, $row['username'] ?? '');
            $objPHPExcel->getActiveSheet()->setCellValue('B' . $r, $row['password'] ?? '');
            $objPHPExcel->getActiveSheet()->setCellValue('C' . $r, $row['sex'] ?? '');
        }

        $objPHPExcel->getActiveSheet()->setTitle('Data');
        $objPHPExcel->setActiveSheetIndex(0);

        // 輸出下載
        ob_end_clean();
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="' . $name . '.xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }
}

三、建立控制器 ExcelAction

路徑:Home/Lib/Action/ExcelAction.class.php

<?php
class ExcelAction extends Action {
    public function __construct() {
        import('ORG.Util.ExcelToArray');
    }

    public function index() {
        $this->display();
    }

    /** 導入 Excel 入庫 */
    public function add() {
        $tmp = $_FILES['file_stu']['tmp_name'];
        $ext = strtolower(pathinfo($_FILES['file_stu']['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, ['xls', 'xlsx'])) {
            $this->error('請上傳 .xls 或 .xlsx 檔案');
        }

        $savePath = 'Uploads/';
        if (!is_dir($savePath)) mkdir($savePath, 0777, true);
        $file = date('YmdHis') . '.' . $ext;
        if (!move_uploaded_file($tmp, $savePath . $file)) {
            $this->error('上傳失敗');
        }

        $excel = new ExcelToArray();
        $rows = $excel->read($savePath . $file, 'UTF-8', $ext);

        $data = [];
        foreach ($rows as $k => $v) {
            if ($k === 1) continue; // 跳過標題列
            $data[] = [
                'username' => $v[0] ?? '',
                'password' => $v[1] ?? '',
                'sex'      => $v[2] ?? '',
            ];
        }

        if (M('User')->addAll($data)) {
            $this->success('導入成功');
        } else {
            $this->error('入庫失敗');
        }
    }

    /** 導出資料 */
    public function load() {
        $data = M('User')->select();
        $excel = new ExcelToArray();
        $excel->push($data, 'UserTable');
    }
}

四、視圖模板

路徑:Home/Tpl/Excel/index.html

<form method="post" action="__APP__/Excel/add" enctype="multipart/form-data">
  <h3>導入 Excel:</h3>
  <input type="file" name="file_stu" />
  <input type="submit" value="導入" />
</form>

<form method="post" action="__APP__/Excel/load">
  <input type="submit" value="導出" />
</form>

五、資料表結構

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `sex` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

進階優化建議

  • 大檔案處理:使用 setReadDataOnly(true)、分塊讀取(PHPExcel_IOFactory::createReader 支援 setLoadSheetsOnly)
  • 記憶體優化:改用 Box/Spout 或 PhpSpreadsheet 串流模式
  • 日期/數值格式:讀取時用 getFormattedValue() 保留 Excel 顯示格式
  • 安全性:上傳檔案需驗證 MIME、限制大小、重命名儲存、隔離執行權限

遵循本指南,你可以在半小時內為 ThinkPHP 專案新增穩健的 Excel 導入導出功能,並具備擴展至 CSV、ODS、PDF 等格式的基礎架構。

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