标签归档:csv

PHP 导入导出 csv

每次写类似的需求都需要现查,那么今天就来个通用的吧!

class ManageCsv
{
    // 表头
    protected $csvHeader = [];
    // 数据数组
    protected $rows = [];
    // 表头在数组中的索引,要保持表头的顺序
    protected $headerIndex = [];
    // 表名
    protected $filename = '';
    /**
     * 导出初始化
     *
     * @param array  $csvHeader
     * @param array  $rows
     * @param string $filename
     * @param array  $headerIndex
     *
     * @return $this
     */
    public function initExport(array $csvHeader, array $rows, $filename = '', $headerIndex = [])
    {
        $this->csvHeader = $csvHeader;
        $this->rows = $rows;
        $this->headerIndex = $headerIndex;
        $this->filename = $filename;
        return $this;
    }
    /**
     * 导入初始化
     *
     * @param $filename
     *
     * @return $this
     */
    public function initImport($filename)
    {
        $this->filename = $filename;
        return $this;
    }
    /**
     * 保存 csv
     *
     * @param string $path
     *
     * @return $this
     * @throws
     */
    public function storeCsv($path = '')
    {
        if (empty($this->csvHeader) || empty($this->rows)) {
            throw new \Exception('表头或数据不能为空!');
        }
        $handler = fopen($this->getAbsFile($path), 'w+');
        fwrite($handler,chr(0xEF).chr(0xBB).chr(0xBF));// 解决 windows 乱码
        fputcsv($handler, $this->csvHeader);
        foreach ($this->rows as $row) {
            fputcsv($handler, $row);
        }
        fclose($handler);
        return $this;
    }
    /**
     * 设置导出的 csv 数据并下载
     *
     * @throws
     */
    public function export()
    {
        if (empty($this->csvHeader) || empty($this->rows)) {
            throw new \Exception('表头或数据不能为空!');
        }
        $str    = '';
        $header = mb_convert_encoding(implode(',', $this->csvHeader) . "\n", "GBK", "UTF-8");
        foreach ($this->rows as $row) {
            if (empty($this->headerIndex)) {
                $str .= mb_convert_encoding(implode(',', $row), 'GBK', 'UTF-8') . "\n";
            } else {
                $item = '';
                foreach ($this->headerIndex as $index) {
                    $item .= mb_convert_encoding($row[$index], 'GBK', 'UTF-8') . ',';
                }
                $item = rtrim($item, ',') . "\n";
                $str .= $item;
            }
        }
        $data     = $header . $str;
        $this->downloadCsv($this->filename ?: time() . '.csv', $data);
    }
    /**
     * 导入csv
     *
     * @return array
     * @throws Exception
     */
    public function import()
    {
        if (empty($this->filename)) {
            throw new \Exception('文件名不能为空!');
        }
        $handler = fopen($this->filename, 'r');
        $result = [];
        while ($item = fgets($handler)) {
            $result[] = $item;
        }
        fclose($handler);
        return $result;
    }
    /**
     * 浏览器下载 csv
     *
     * @param $filename
     * @param $data
     */
    protected function downloadCsv($filename, $data)
    {
        header("Content-type:text/csv");
        header("Content-Disposition:attachment;filename=" . $filename);
        header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
        header('Expires:0');
        header('Pragma:public');
        echo $data;
    }
    /**
     * 根据路径返回完整的文件名
     *
     * @param string $path
     *
     * @return string
     */
    protected function getAbsFile($path = '')
    {
        $filename = $this->filename ?: time() . '.csv';
        return !empty($path) ? rtrim($path, '/') . '/' . $filename : $filename;
    }
}
$csvHeader = ['姓名', '性别', '年龄'];
$rows = [
    ['张三', '男', 12],
    ['张四', '女', 16],
    ['张五', '未知', 19],
];
$rows2 = [
    ['name' => '张三', 'sex' => '男', 'age' => 12],
    ['name' => '张四', 'sex' => '女', 'age' => 16],
    ['name' => '张五', 'sex' => '未知', 'age' => 19],
];
$headerIndex = ['name', 'sex', 'age'];
$csvManger = new ManageCsv();
// $csvManger->init($csvHeader, $rows)->storeCsv();
// $csvManger->initImport('1607671482.csv')->import();
// $csvManger->initExport($csvHeader, $rows, 'download.csv')->export();
$csvManger->initExport($csvHeader, $rows2, 'download.csv', $headerIndex)->export();