<?php

namespace app\common\util;

use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;

/**
 * Excel表格功能封装类
 */
class PhpSpreadsheetImport
{
    /**
     * 读取表格数据
     * @param string $path 路径
     * @param int $sheetIndex 工作簿索引
     * @param array $field 初始化数组键名
     * @param int $row 从第几行开始读
     * @param string $scene
     * @return array
     */
    public static function readData(string $path, array $field = [], int $row = 2, int $sheetIndex = 0, string $scene = 'excel'): array
    {
        try {
            // 创建读操作对象
            $reader = IOFactory::createReader('Xlsx');
            // 忽略任何格式的信息
            $reader->setReadDataOnly(true);
            // 打开文件、载入excel表格
            $spreadsheet = $reader->load($path);
            // 获取活动工作薄
            $sheet = $spreadsheet->getSheet($sheetIndex);
            // 返回表格数据
            return self::getCellData($row, $sheet, $field);
        } catch (\Exception $e) {
            // 有异常发生
            return ['code' => $e->getCode(), 'errMsg' => $e->getMessage()];
        }
    }

    /**
     * 获取单元格数据
     * @param $row
     * @param object $sheet
     * @param array $field
     * @return array
     * @throws Exception
     */
    private static function getCellData($row, object $sheet, array $field):array
    {
        # 获取最高列 返回字母 如: C
        $highestColumn = $sheet->getHighestColumn();
        # 获取最大行 返回数字 如: 4
        $highestRow = $sheet->getHighestRow();
        # 列数 改为数字显示
        $highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);
        $data = [];
        // 从第二行开始读取数据
        for ($row; $row <= $highestRow; $row++) {
            $build = [];
            // 从第一列读取数据
            for ($col = 1; $col <= $highestColumnIndex; $col++) {
                // 'A' 对应的ASCII码十进制为 64
                // 将ASCII值转为字符
                $chr = chr(64 + $col);
                // 列转为数据库字段名
                $key = $field[$chr] ?? $chr;
                // 构建当前行数据
                $build[$key] = $sheet->getCellByColumnAndRow($col, $row)->getValue();
            }
            $data[] = $build; //当前行数据
        }
        return $data;
    }
}