php万级以上Excel的导出及读取--Xlswriter

当我们进行万级以上数据的导入及导出时,经常或遇到内存超出或超时的情况;
这里介绍一下解决方案,xlsxwriter 一个 PHP C 扩展(giteegithub);
用于在Excel 2007及以上版本XLSX文件中写入多个工作表的文本,数字,公式和超链接。
在composer找个两个扩展(PHP_XLSXWriterphp-ext-xlswriter-ide-helper
大家可以根据需求,选择合适的扩展,这篇文章主要介绍 php-ext-xlswriter-ide-helper 的使用

一、安装 xlsxwriter(文档

Linux下PECL安装(推荐)

[root@bogon ~]# pecl install xlswriter
# 添加 extension = xlswriter.so 到 ini 配置

如果PECL安装失败,可以使用编译安装(注意扩展及php位置)

[root@bogon ~]# wget https://pecl.php.net/get/xlswriter-1.3.2.tgz
[root@bogon ~]# tar xf xlswriter-1.3.2.tgz
[root@bogon ~]# cd xlswriter-1.3.2
[root@bogon ~]# /www/server/php/72/bin/phpize
[root@bogon ~]# ./configure --with-php-config=/www/server/php/72/bin/php-config --enable-reader
[root@bogon ~]# make && make install

[xlswriter]
# extension=/www/server/php/72/lib/php/extensions/no-debug-non-zts-20170718/xlswriter.so

windows的安装及测试速度对比,可以参考这篇文章, php百万级数据Excel导出的解决方案

安装扩展(仅支持php7.0及以上版本)

composer require viest/php-ext-xlswriter-ide-helper:dev-master

二、文件导出(数据文件的导出到excel)

<?php
$count = 1000;
set_time_limit(0);
ini_set('memory_limit', '10240M');

$callStartTime = microtime(true);
$config = ['path' => './']; // 设置文件保存路径
$excel  = new \Vtiful\Kernel\Excel($config);

$data = []; // 具体excel数据
for ($i=0; $i < $count; $i++) {
    $data[] = [$i, 'aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaaa'];
}

// fileName 会自动创建一个工作表,你可以自定义该工作表名称,工作表名称为可选参数
$filePath = $excel->fileName('111111.xlsx', 'Sheet1')
    ->header(['ID', '姓名', '性别', '年龄', '电话', '测试']) // 设置表首行名称
    ->data($data)
    ->output();

三、文件导入(读取xlsx文件数据)

<?php
$config   = ['path' => './'];
$excel    = new \Vtiful\Kernel\Excel($config);

// 读取测试文件
$data = $excel->openFile('111111.xlsx')
    ->openSheet('Sheet1', \Vtiful\Kernel\Excel::SKIP_EMPTY_ROW)
    ->getSheetData();

var_dump($data);

详细测试文件 ceshi.php

<?php
/**
 * @Author: [FENG] <1161634940@qq.com>
 * @Date:   2020-02-12 18:42:15
 * @Last Modified by:   [FENG] <1161634940@qq.com>
 * @Last Modified time: 2020-02-12 18:23:58
 */

include_once './vendor/autoload.php';

class Ceshi
{
    /**
     * [export 数据文件的导出到excel]
     * @return [type] [description]
     */
    public static function export()
    {
		$count = 1000;
		set_time_limit(0);
		ini_set('memory_limit', '10240M');

		$callStartTime = microtime(true);
		$config = ['path' => './']; // 设置文件保存路径
		$excel  = new \Vtiful\Kernel\Excel($config);

		$data = []; // 具体excel数据
		for ($i=0; $i < $count; $i++) {
		    $data[] = [$i, 'aaaa', 'aaaa', 'aaaa', 'aaaa', 'aaaa'];
		}

		// fileName 会自动创建一个工作表,你可以自定义该工作表名称,工作表名称为可选参数
		$filePath = $excel->fileName('111111.xlsx', 'sheet1')
		    ->header(['ID', '姓名', '性别', '年龄', '电话', '测试']) // 设置表首行名称
		    ->data($data)
		    ->output();

    }

    /**
     * [import 读取xlsx文件数据]
     * @return [type] [description]
     */
    public static function import()
    {
		$config   = ['path' => './'];
		$excel    = new \Vtiful\Kernel\Excel($config);

		// 读取测试文件
		$data = $excel->openFile('111111.xlsx')
		    ->openSheet('Sheet1', \Vtiful\Kernel\Excel::SKIP_EMPTY_ROW)
		    ->getSheetData();

		var_dump($data);
    }

    /**
     * [import1 读取xlsx文件数据并进行数据处理便于插入数据库]
     * @return [type] [description]
     */
    public static function import1()
    {
		$filePath = './111111.xlsx';
		$file_array = explode('/', $filePath);
		$fileName = array_pop($file_array); // 文件名称

		if (!in_array('xlsx', explode('.', $fileName))) {
		    die('仅支持xlsx文件导入');
		}

		$path = implode('/', $file_array); // 文件路径
		$config   = ['path' => $path];
		$excel    = new \Vtiful\Kernel\Excel($config);

		// 读取测试文件
		$data_excel = $excel->openFile($fileName)->openSheet();
		$data = $data_excel->getSheetData(); // 获取表格内数据
		$fields = array_shift($data); // 首行标题title

		$fieldArr = ['ID'=>'id', '姓名'=>'name', '性别'=>'sex', '年龄'=>'age', '电话'=>'tel', '测试'=>'ceshi']; // 声明对应字段关系

		$insert = [];
		// foreach ($data as $key => $value) {
		//     if (array_filter($value)) {
		//         $row = [];
		//         $temp = array_combine($fields, $value);
		//         foreach ($temp as $k => $v) {
		//             if (isset($fieldArr[$k]) && $k !== '') {
		//                 $row[$fieldArr[$k]] = $v;
		//             }
		//         }
		//         if ($row) {
		//             $row && $insert[] = $row;
		//         }
		//     }
		// }

		$field_array = [$fields, array_filter($fieldArr)];
		array_walk($data, function (&$value, $key, $field_array) {
		    if (array_filter($value)) {
		        $row = [];
		        $temp = array_combine($field_array[0], $value);
		        foreach ($temp as $k => $v) {
		            if (isset($field_array[1][$k]) && $k !== '') {
		                $row[$field_array[1][$k]] = $v;
		            }
		        }
		        $row && $value = $row;
		    } else {
		        $value = '';
		    }
		}, $field_array);
		$insert = array_filter($data);

		var_dump($insert);die;
    }

}

Ceshi::export(); // 数据文件的到处到ececl
Ceshi::import1(); // 读取xlsx文件数据

冯奎博客
请先登录后发表评论
  • latest comments
  • 总共0条评论