yii2 使用 PhpSpreadsheet 对excel进行导入导出操作

安装PhpSpreadsheet 

composer require phpoffice/phpspreadsheet

安装完成后我们写一个工具类

Excel.php 工具类

<?php
namespace common\tools;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Spreadsheet;


class Excel
{

    # 导入excel
    static function importExecl($file = '', $sheet = 0, $columnCnt = 0, &$options = [])
    {
        try {
            /* 转码 */
            $file = iconv("utf-8", "gb2312", $file);

            if (empty($file) OR !file_exists($file)) {
                throw new \Exception('文件不存在!');
            }

            /** @var Xlsx $objRead */
            $objRead = IOFactory::createReader('Xlsx');

            if (!$objRead->canRead($file)) {
                /** @var Xls $objRead */
                $objRead = IOFactory::createReader('Xls');

                if (!$objRead->canRead($file)) {
                    throw new \Exception('只支持导入Excel文件!');
                }
            }

            /* 如果不需要获取特殊操作,则只读内容,可以大幅度提升读取Excel效率 */
            empty($options) && $objRead->setReadDataOnly(true);
            /* 建立excel对象 */
            $obj = $objRead->load($file);
            /* 获取指定的sheet表 */
            $currSheet = $obj->getSheet($sheet);

            if (isset($options['mergeCells'])) {
                /* 读取合并行列 */
                $options['mergeCells'] = $currSheet->getMergeCells();
            }

            if (0 == $columnCnt) {
                /* 取得最大的列号 */
                $columnH = $currSheet->getHighestColumn();
                /* 兼容原逻辑,循环时使用的是小于等于 */
                $columnCnt = Coordinate::columnIndexFromString($columnH);
            }

            /* 获取总行数 */
            $rowCnt = $currSheet->getHighestRow();
            $data   = [];

            /* 读取内容 */
            for ($_row = 1; $_row <= $rowCnt; $_row++) {
                $isNull = true;

                for ($_column = 1; $_column <= $columnCnt; $_column++) {
                    $cellName = Coordinate::stringFromColumnIndex($_column);
                    $cellId   = $cellName . $_row;
                    $cell     = $currSheet->getCell($cellId);

                    if (isset($options['format'])) {
                        /* 获取格式 */
                        $format = $cell->getStyle()->getNumberFormat()->getFormatCode();
                        /* 记录格式 */
                        $options['format'][$_row][$cellName] = $format;
                    }

                    if (isset($options['formula'])) {
                        /* 获取公式,公式均为=号开头数据 */
                        $formula = $currSheet->getCell($cellId)->getValue();

                        if (0 === strpos($formula, '=')) {
                            $options['formula'][$cellName . $_row] = $formula;
                        }
                    }

                    if (isset($format) && 'm/d/yyyy' == $format) {
                        /* 日期格式翻转处理 */
                        $cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');
                    }

                    $data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue());

                    if (!empty($data[$_row][$cellName])) {
                        $isNull = false;
                    }
                }

                /* 判断是否整行数据为空,是的话删除该行数据 */
                if ($isNull) {
                    unset($data[$_row]);
                }
            }

            return $data;
        } catch (\Exception $e) {
            throw $e;
        }
    }
   # 导出
    static function exportExcel($data,$title)
    {
        $spreadsheet = new Spreadsheet();
        $worksheet = $spreadsheet->getActiveSheet();

        //设置工作表标题名称
        $worksheet->setTitle('工作表格1');

        //表头 设置单元格内容
        foreach ($title as $key => $value) {
            $worksheet->setCellValueByColumnAndRow($key+1, 1, $value);
        }

        $row = 2; //从第二行开始
        foreach ($data as $item) {
            $column = 1; //从第一列设置并初始化
            foreach ($item as $value) {
                $worksheet->setCellValueByColumnAndRow($column, $row, $value); //哪一列哪一行设置哪个值
                $column++; //列数加1
            }
            $row++; //行数加1
        }

        //输出到浏览器
        $fileName = date('YmdHis',time());
        $fileType = 'Xlsx';
        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
        self::excelBrowserExport($fileName, $fileType);
        $writer->save('php://output');
    }
    static public function excelBrowserExport($fileName, $fileType)
    {
        //文件名称校验
        if (!$fileName) {
            throw new Exception('文件名不能为空');
        }

        //Excel文件类型校验
        $type = ['Excel2007', 'Xlsx', 'Excel5', 'xls'];
        if (!in_array($fileType, $type)) {
            throw new Exception('未知文件类型');
        }

        if ($fileType == 'Excel2007' || $fileType == 'Xlsx') {
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx"');
            header('Cache-Control: max-age=0');
        } else {
            header('Content-Type: application/vnd.ms-excel');
            header('Content-Disposition: attachment;filename="' . $fileName . '.xls"');
            header('Cache-Control: max-age=0');
        }
    }

}

写一个测试的控制器

<?php
namespace frontend\controllers;

use app\models\UploadForm;
use common\tools\Excel;
use Yii;
use yii\web\Controller;
use yii\web\UploadedFile;

class TestController extends Controller
{

    # 用来测试的index页面 
    public function actionIndex()
    {

        # 文件上传的model
        $file = new UploadForm();
        return $this->render('index', [
            'file' => $file
        ]);

    }



    # 导入表格
    public function actionImport_excel_data(){
        $model = new UploadForm();
        if (Yii::$app->request->isPost) {
            $model->file = UploadedFile::getInstance($model, 'file');
            if ($model->file && $model->validate()) {
                $path = 'uploads/';
                if (!file_exists($path)) {
                    mkdir($path, 0755, true);
                }
                $time = time();
                $rand = rand(100,999);
                $basename = $model->file->baseName;
                $filename = md5($basename.$time.$rand);
                $fname = $path . $filename . '.' . $model->file->extension;
                if ($model->file && $model->validate()) {
                    $model->file->saveAs($fname);
                }
                $fpath = Yii::$app->BasePath.'/web/'.$fname;
//                echo $fpath;
//                exit;
                $data = Excel::importExecl($fpath);
                # 得到表头
                $biaotou = $data[1];
//                $date = $biaotou['日期'];
//                $productname = $biaotou['损坏产品名称'];
//                $people = $biaotou['产品使用人'];
//                $ment = $biaotou['产品所属部门'];
//                $reason = $biaotou['损坏原因'];
                $count  = count($data);
//                var_dump($data);
//                exit;
                if ($biaotou['A'] != '日期'||$biaotou['B'] != '损坏产品名称'||$biaotou['C'] != '产品使用人'
                ||$biaotou['D'] != '产品所属部门'||$biaotou['E'] != '损坏原因'){
                    return "表格表头不匹配";
                }
                # 这里要从第二行开始读 因为第一行是表头
                # 拿到数据后写入数据里面 建议这里用批量写入的方式而不是再循环里面写入数据库
                for ($i = 2; $i<$count+1; $i++){
                   # var_dump($data[$i]);
                    echo '日期'.$data[$i]['A']."</br>";
                    echo '损坏产品名称'.$data[$i]['B']."</br>";
                    echo '产品使用人'.$data[$i]['C']."</br>";
                    echo '产品所属部门'.$data[$i]['D']."</br>";
                    echo '损坏原因'.$data[$i]['E']."</br>";
                }
            }
        }

        return "";
    }
    # 导出表格
    public function actionExport_excel_data(){
        $data = [
            ['2020-04-29', '测试', '张三','测试部门','没得原因'],
            ['2020-04-29', '测试', '张三','测试部门','没得原因'],
            ['2020-04-29', '测试', '张三','测试部门','没得原因'],
            ['2020-04-29', '测试', '张三','测试部门','没得原因'],
            ['2020-04-29', '测试', '张三','测试部门','没得原因'],
            ['2020-04-29', '测试', '张三','测试部门','没得原因']
        ];
        $title = ['日期', '损坏产品名称', '产品使用人','产品所属部门','损坏原因'];
        Excel::exportExcel($data,$title);
    }
}

UploadForm.php
<?php

namespace app\models;


use yii\base\Model;

class UploadForm extends Model
{
    /**
     * @var UploadedFile|Null file attribute
     */
    public $file;

    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [
            [['file'], 'file'],
        ];
    }

}

view里面的index.php

<?php
use yii\bootstrap\ActiveForm;
?>

<!--导入表格-->
<h2>导入表格</h2>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data'],'action' => ['import_excel_data'],'method'=>'post']) ?>

<?= $form->field($file, 'file')->fileInput() ?>

<button>导入表格</button>

<?php ActiveForm::end() ?>
<!--下载表格-->
<a  href="export_excel_data">下载表格</a>

以上就是全部代码,均测试过,流程跑通了的。可以根据自己需要进行调整。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值