首先说明,xlswriter是PHP的一个扩展,官网文档有介绍。也有更为详细的文档,https://xlswriter-docs.viest.me/

Excel

你的瓶颈不再是PHP

传统的HTML格式数据转EXCEL,从浏览器直接输出不支持EXCEL2007。
所以就得安装类型PHP-EXCEL的扩展。但是十万条数据,就能把系统趴下(HTTP请求时间不允许)。
而xlswriter支持EXCEL2007,并且速度与直接输出HTML相差无几。

而且它有两种方式:
1、省时间
2、省内存

基准测试[复制自官网]

测试环境: Macbook Pro 13 inch, Intel Core i5, 16GB 2133MHz LPDDR3 Memory, 128GB SSD Storage

导出

两种内存模式导出100万行数据(单行27列,数据类型均为字符串,单个字符串长度为19)

  • 普通默认模式:耗时 29S,内存只需 2083MB
  • 内存优化模式:耗时 52S,内存仅需 <1MB

    导入

    100万行数据(单行1列,数据类型为INT)

  • 全量模式:耗时 3S,内存仅 558MB

  • 游标模式:耗时 2.8S,内存仅 <1MB

实例:

  1. function getTmpDir()
  2. {
  3. $tmp = ini_get('upload_tmp_dir');
  4. if ($tmp !== False && file_exists($tmp)) {
  5. return realpath($tmp);
  6. }
  7. return realpath(sys_get_temp_dir());
  8. }
  9. $filename = empty($identify) ? '1.xlsx' : '2.xlsx';
  10. $config = [
  11. 'path' => $this->getTmpDir() . '/',
  12. ];
  13. $fileName = $filename;
  14. $xlsxObject = new \Vtiful\Kernel\Excel($config);
  15. $fileObject = $xlsxObject->fileName($fileName);
  16. $data = array();
  17. if(!empty($excel_data) && is_array($excel_data)) {
  18. $format = new \Vtiful\Kernel\Format($xlsxObject->getHandle());
  19. $alignStyle = $format
  20. ->align(\Vtiful\Kernel\Format::FORMAT_ALIGN_VERTICAL_CENTER, \Vtiful\Kernel\Format::FORMAT_ALIGN_CENTER_ACROSS)
  21. ->bold()
  22. ->toResource();
  23. foreach($excel_data as $id_key => $id_val) {
  24. $data[] = [$id_val['a'], $role_info['b'], $id_val['c'], $id_val['d']];
  25. }
  26. unset($excel_data);
  27. $filePath = $fileObject->header(['A列', 'B列', 'C列', 'D列'])
  28. ->data($data)
  29. ->setRow('A1', 22, $alignStyle)
  30. ->output();
  31. header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  32. header('Content-Disposition: attachment;filename="' . $fileName . '"');
  33. header('Content-Length: ' . filesize($filePath));
  34. header('Content-Transfer-Encoding: binary');
  35. header('Cache-Control: must-revalidate');
  36. header('Cache-Control: max-age=0');
  37. header('Pragma: public');
  38. ob_clean();
  39. flush();
  40. if (copy($filePath, 'php://output') === false) {
  41. // Throw exception
  42. }
  43. // Delete temporary file
  44. @unlink($filePath);
  45. } else {
  46. exit("没有任何数据,取消导出");
  47. }