PHP导入excel到MYSQL列数超过64报错:ERROR 1118 (42000): Row size too large.

发布于2020-04-08 20:22:18  分类:laravel   阅读( 137 ) 

查询系统在导入excel时,使用了laravel的查询构造器创建数据表:

DB::schema()->create($bm, function($table) use($zdsz){
$table->increments('id');//主键
foreach($zdsz as $value){
$table->string($value)->nullable();
}
});

在导入一个列数超过64列的EXCEL表时,发现无法创建表,报错如下 :

Row size too large. The maximum row size for the used table type

原以为是MYSQL数据库列数限制,或者字节数超出,但发现与字节数无关。换csv方式导入,依然报错。仔细看报错内容,总算明白原因了:表的所有字段使用了varchar类型,长度设置过长了。解决方法是,将其改成text,修改之后执行成功了:

DB::schema()->create($bm, function($table) use($zdsz){
$table->increments('id');//主键
foreach($zdsz as $value){
$table->text($value)->nullable();
}
});

由于今天才遇到这种列数超多的EXCEL表,一时没认真看报错内容,导致在解决过程中走了弯路。在此记录一下,附laravel导出数据库内容为excel时,数据太大内存超出的解决方法:

    //核心函数,新版导出excel
    public function Excelwriter($bm,$xmmc){
    $is_login = $this->is_login();
    if($is_login !== '总管理员' && $is_login !=='数据管理员'){
    echo "<script>alert('没有登录!');location.href='/admin/login';</script>";exit;
    }
    if(DB::table($bm)->count() < 2){
echo "<script>alert('数据为空!');location.href='".$_SERVER["HTTP_REFERER"]."';</script>";exit;
    }
    set_time_limit(90); 
ini_set("memory_limit", "200M"); 
$zdsz = DB::Schema()->getColumnListing($bm);//字段数组
    $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();//创建一个实例
    $sheet = $spreadsheet->getActiveSheet();//选择工作表
    $sheet->setTitle($xmmc);//设置sheet名
    if($_SESSION['userinfo']['group'] == '数据管理员'){
$config = $this->hqwzszxx();//获取网站设置
    if($config[28]['value'] == 1){
$username = $_SESSION['userinfo']['username'];//开启协同填表,数据管理员只能导出自己创建的数据
    $data = DB::table($bm)->where('创建者',$username)->get()->toArray();
}else{
$data = DB::table($bm)->get()->toArray();
}
array_splice($zdsz,0,1);//移除id
$zdsz = array_values(array_diff($zdsz, ['创建者']));//移除创建者
//设置表头,支持超过26列的表
$i= 1;
foreach ($zdsz as $value) {
//数字转换为字母,以支持超过26列的表
$lie = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);
$cellName = $lie. "1";
$sheet->setCellValue($cellName, $value)->calculateColumnWidths();
$i++;
}
    $data = $this->objectToArray($data);//对象转数组
        //设置表内容
$ii = 2;//行号
foreach ($data as $value){
$i = 1;//列号
foreach($value as $k=>$nr){
if($_SESSION['userinfo']['group'] == '数据管理员'){
//数据管理员不导出id和创建者
if($k == 'id' or $k == '创建者')
continue;//整行内容为空,跳过
}
//判断是否是json,导出时多个以,分割,单个不分割
if($this->isJson($nr)){
$zdnr = json_decode($nr,true);
if(count($zdnr) == 1){
$nr = json_decode($nr,true)[0];
}else{
$nr = implode(",",$zdnr);
}
}
$lie = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);//数字转换为字母,以支持超过26列的表
$sheet->setCellValueExplicit($lie.$ii,$nr ??"", \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);//防止长数字变科学计数法
$i++;
}
$ii++;
}
    }else{
//设置表头,支持超过26列的表
$i= 1;
foreach ($zdsz as $value) {
//数字转换为字母,以支持超过26列的表
$lie = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);
$cellName = $lie. "1";
$sheet->setCellValue($cellName, $value)->calculateColumnWidths();
$i++;
}
    //总管理员,数据太多,100一次分批取出
DB::table($bm)->orderBy('id')->chunk(100, function ($data) use($sheet) {
static $ii = 2;//行号,Static作用域,每次调用该函数时,该变量将会保留着函数前一次被调用时的值
foreach ($data as $value) {
$i = 1;//列号
foreach($value as $nr){
//判断是否是json,导出时多个以,分割,单个不分割
if($this->isJson($nr)){
$zdnr = json_decode($nr,true);
if(count($zdnr) == 1){
$nr = json_decode($nr,true)[0];
}else{
$nr = implode(",",$zdnr);
}
}
$lie = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);//数字转换为字母以支持超过26列
$sheet->setCellValueExplicit($lie.$ii,$nr ??"", \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);//防止长数字变科学计数法
$i++;
}
$ii++;
}
});
    }
//输出到浏览器下载
header('Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition:attachment;filename="'.$xmmc.'.xlsx"');
header('Cache-Control: max-age=0');
    $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('php://output');
    }


最后更新于:2020-04-08 20:22:18


上一篇: jQuery datatable后台PHP分页,通过Laravel查询构造器实现搜索的方法

下一篇: laravel7.3 安装laravel-admin无法登录,密码正确却跳转回登录框


  • 最新评论(共0条)
需要登录才能发表评论

加入组织

  • QQ
  • 1. 手Q扫左侧二维码

    2. 搜Q群:617719749

    3. 点击加入学习群

最新评论