ReadExecl.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\common\library\phpoffice;
  13. use PhpOffice\PhpSpreadsheet\IOFactory;
  14. use PhpOffice\PhpSpreadsheet\Reader\Xls;
  15. use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
  16. use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
  17. class ReadExecl
  18. {
  19. /**
  20. * 使用PHPEXECL导入
  21. * @param string $file 文件地址
  22. * @param int $sheet 工作表sheet(传0则获取第一个sheet)
  23. * @param int $columnCnt 列数(传0则自动获取最大列)
  24. * @param int $rowCnt 行数(传0则自动获取最大行)
  25. * @param array $options 操作选项
  26. * array mergeCells 合并单元格数组
  27. * array formula 公式数组
  28. * array format 单元格格式数组
  29. * @return array
  30. * @throws \PhpOffice\PhpSpreadsheet\Exception
  31. * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
  32. * @throws \cores\exception\BaseException
  33. */
  34. public static function load(string $file, int $sheet = 0, int $columnCnt = 0, int $rowCnt = 0, array &$options = []): array
  35. {
  36. /* 转码 */
  37. // $file = iconv("utf-8", "gb2312", $file);
  38. if (empty($file) or !file_exists($file)) {
  39. throwError('文件不存在!');
  40. }
  41. // 创建阅读器
  42. $objRead = self::createXlsxReader($file);
  43. /* 如果不需要获取特殊操作,则只读内容,可以大幅度提升读取Excel效率 */
  44. empty($options) && $objRead->setReadDataOnly(true);
  45. /* 建立excel对象 */
  46. $obj = $objRead->load($file);
  47. /* 获取指定的sheet表 */
  48. $currSheet = $obj->getSheet($sheet);
  49. if (isset($options['mergeCells'])) {
  50. /* 读取合并行列 */
  51. $options['mergeCells'] = $currSheet->getMergeCells();
  52. }
  53. if (0 == $columnCnt) {
  54. /* 取得最大的列号 */
  55. $columnH = $currSheet->getHighestColumn();
  56. /* 兼容原逻辑,循环时使用的是小于等于 */
  57. $columnCnt = Coordinate::columnIndexFromString($columnH);
  58. }
  59. /* 获取总行数 */
  60. $rowCnt = $rowCnt ?: $currSheet->getHighestRow();
  61. $data = [];
  62. /* 读取内容 */
  63. for ($_row = 1; $_row <= $rowCnt; $_row++) {
  64. $isNull = true;
  65. for ($_column = 1; $_column <= $columnCnt; $_column++) {
  66. $cellName = Coordinate::stringFromColumnIndex($_column);
  67. $cellId = $cellName . $_row;
  68. $cell = $currSheet->getCell($cellId);
  69. if (isset($options['format'])) {
  70. /* 获取格式 */
  71. $format = $cell->getStyle()->getNumberFormat()->getFormatCode();
  72. /* 记录格式 */
  73. $options['format'][$_row][$cellName] = $format;
  74. }
  75. if (isset($options['formula'])) {
  76. /* 获取公式,公式均为=号开头数据 */
  77. $formula = $currSheet->getCell($cellId)->getValue();
  78. if (0 === strpos($formula, '=')) {
  79. $options['formula'][$cellName . $_row] = $formula;
  80. }
  81. }
  82. if (isset($format) && 'm/d/yyyy' == $format) {
  83. /* 日期格式翻转处理 */
  84. $cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');
  85. }
  86. $data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue());
  87. if (!empty($data[$_row][$cellName])) {
  88. $isNull = false;
  89. }
  90. }
  91. /* 判断是否整行数据为空,是的话删除该行数据 */
  92. if ($isNull) {
  93. unset($data[$_row]);
  94. }
  95. }
  96. return $data;
  97. }
  98. /**
  99. * 创建Xlsx阅读器
  100. * @param string $file
  101. * @return \PhpOffice\PhpSpreadsheet\Reader\IReader|Xlsx
  102. * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
  103. * @throws \cores\exception\BaseException
  104. */
  105. private static function createXlsxReader(string $file)
  106. {
  107. /** @var Xlsx $IReader */
  108. $IReader = IOFactory::createReader('Xlsx');
  109. if (!$IReader->canRead($file)) {
  110. /** @var Xls $objRead */
  111. $IReader = IOFactory::createReader('Xls');
  112. if (!$IReader->canRead($file)) {
  113. throwError('只支持导入Excel文件!');
  114. }
  115. }
  116. return $IReader;
  117. }
  118. }