ExcelHelper.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. namespace App\Http\helper;
  3. class ExcelHelper
  4. {
  5. public static $styleFormat = [];
  6. /**
  7. * @see \PHPExcel_Style_NumberFormat
  8. */
  9. public static function setStyleFormat($format)
  10. {
  11. self::$styleFormat = $format;
  12. }
  13. /**
  14. * 导出
  15. * @see https://www.cnblogs.com/tujia/p/11358096.html
  16. * @param array $titles 标题,一维数组,可传map或单纯标题
  17. * @param array $dataArray 数据,二维数组,可传map或单纯数据
  18. * @param string $filename 文件名,要带后缀
  19. * @param string $bigTitle 居中加粗的大标题,默认为空
  20. * @param array $extra 扩展数据
  21. * @return file
  22. */
  23. public static function export(array $titles, $dataArray, $filename, $bigTitle = '', $extra = [])
  24. {
  25. set_time_limit(0);
  26. ini_set('memory_limit', '512M');
  27. // 后缀
  28. $suffix = substr($filename, strrpos($filename, '.'));
  29. empty($titles) && die('标题数组不能为空!');
  30. empty($dataArray) && die('数据数组不能为空!');
  31. !in_array($suffix, ['.xls', '.xlsx']) && die('文件名格式错误!');
  32. $cacheMethod = \PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized;
  33. $cacheSettings = array('memoryCacheSize ' => '512MB');
  34. \PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
  35. $oExcel = new \PHPExcel();
  36. $oExcel->setActiveSheetIndex(0);
  37. $sheet = $oExcel->getActiveSheet();
  38. // 设置列数据格式
  39. if (!empty(self::$styleFormat)) {
  40. $fields = array_keys($titles);
  41. foreach (self::$styleFormat as $field => $formatCode) {
  42. $offset = array_search($field, $fields);
  43. $col = chr(65 + $offset);
  44. $sheet->getStyle($col)->getNumberFormat()->setFormatCode($formatCode);
  45. }
  46. }
  47. // 行索引
  48. $rowIndex = $bigTitle != '' ? 2 : 1;
  49. $chr = [
  50. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  51. 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ'
  52. ];
  53. // 设置大标题
  54. if ($bigTitle != '') {
  55. $sheet->mergeCells('A1:' . $chr[count($titles) - 1] . '1');
  56. $sheet->getStyle('A1')->applyFromArray([
  57. 'font' => ['bold' => true],
  58. 'alignment' => ['horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER]
  59. ]);
  60. $sheet->setCellValue('A1', $bigTitle);
  61. }
  62. // 设置标题 A1 B1 C1 ....
  63. $colIndex = 0;
  64. $fieldsMap = [];
  65. foreach ($titles as $key => $title) {
  66. $fieldsMap[] = $key;
  67. $sheet->setCellValue($chr[$colIndex] . $rowIndex, $title);
  68. $colIndex++;
  69. }
  70. // 设置内容 A1 B1 C1 .... A2 B2 C2 ....
  71. $rowIndex++;
  72. foreach ($dataArray as $key => $value) {
  73. foreach ($fieldsMap as $colIndex => $field) {
  74. if (strrpos($field, '|') !== false) {
  75. $temp1 = explode('|', $field);
  76. $pos = strrpos($temp1[1], '.');
  77. $pos === false && $pos = strlen($temp1[1]);
  78. $temp2 = [];
  79. $temp2[0] = substr($temp1[1], 0, $pos);
  80. $temp2[1] = substr($temp1[1], $pos + 1);
  81. $val = $value[$temp1[0]];
  82. //$val = self::$temp2[0]($extra, $temp2[1], $val);
  83. $val = call_user_func_array(array('\common\helpers\ExcelHelper', $temp2[0]), array($extra, $temp2[1], $val, $value));
  84. } else {
  85. $val = $field ? $value[$field] : $value;
  86. }
  87. $sheet->setCellValue($chr[$colIndex] . $rowIndex, $val);
  88. }
  89. $rowIndex++;
  90. }
  91. header("Content-Type: application/force-download");
  92. header("Content-Type: application/octet-stream");
  93. header("Content-Type: application/download");
  94. if ($suffix == '.xlsx') {
  95. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  96. } else {
  97. header('Content-Type: application/vnd.ms-excel');
  98. }
  99. header('Content-Disposition: attachment;filename="' . $filename . '"');
  100. header("Content-Transfer-Encoding: binary");
  101. header("Pragma: no-cache");
  102. $oWriter = \PHPExcel_IOFactory::createWriter($oExcel, 'Excel2007');
  103. $oWriter->save('php://output');
  104. $oExcel->disconnectWorksheets();
  105. exit;
  106. }
  107. /**
  108. * 导出
  109. * @see https://www.cnblogs.com/tujia/p/5999806.html
  110. * @param array $titles 标题,一维数组,可传map或单纯标题
  111. * @param array $dataArray 数据,二维数组,可传map或单纯数据
  112. * @param string $filename 文件名,要带后缀
  113. * @param array $extra 扩展数据
  114. * @return file
  115. */
  116. public static function exportSimple(array $titles, $dataArray, $filename, $extra = [])
  117. {
  118. // 后缀
  119. $suffix = substr($filename, strrpos($filename, '.'));
  120. empty($titles) && die('标题数组不能为空!');
  121. empty($dataArray) && die('数据数组不能为空!');
  122. !in_array($suffix, ['.xls', '.xlsx', '.csv']) && die('文件名格式错误!');
  123. // 导出准备
  124. set_time_limit(0);
  125. ini_set('memory_limit', '512M');
  126. header("Content-Type: application/force-download");
  127. header("Content-Type: application/octet-stream");
  128. header("Content-Type: application/download");
  129. header('Content-Disposition: attachment; filename=' . $filename);
  130. if ($suffix == '.xlsx') {
  131. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  132. } elseif ($suffix == '.xls') {
  133. header('Content-Type: application/vnd.ms-excel');
  134. } elseif ($suffix == '.csv') {
  135. header('Content-Type: application/vnd.ms-excel; charset=gb18030');
  136. }
  137. header("Content-Transfer-Encoding: binary");
  138. header("Pragma: no-cache");
  139. $isCsv = ($suffix == '.csv');
  140. $fieldsCount = count($titles);
  141. if ($isCsv) {
  142. echo mb_convert_encoding(implode(',', array_values($titles)), 'gb18030') . "\n";
  143. } else {
  144. echo '<table>';
  145. echo '<tr>';
  146. foreach ($titles as $key => $value) {
  147. echo sprintf('<td>%s</td>', $value);
  148. }
  149. echo '</tr>';
  150. }
  151. foreach ($dataArray as $key => $value) {
  152. $i = 0;
  153. $isCsv == false && print('<tr>');
  154. foreach ($titles as $field => $title) {
  155. if (strrpos($field, '|') !== false) {
  156. $temp1 = explode('|', $field);
  157. $pos = strrpos($temp1[1], '.');
  158. $pos === false && $pos = strlen($temp1[1]);
  159. $temp2 = [];
  160. $temp2[0] = substr($temp1[1], 0, $pos);
  161. $temp2[1] = substr($temp1[1], $pos + 1);
  162. $val = $value[$temp1[0]];
  163. //$val = self::$temp2[0]($extra, $temp2[1], $val);
  164. $val = call_user_func_array(array('\common\helpers\ExcelHelper', $temp2[0]), array($extra, $temp2[1], $val, $value));
  165. } else {
  166. $val = $field ? $value[$field] : $value;
  167. }
  168. if ($isCsv) {
  169. echo mb_convert_encoding($val . ($i == $fieldsCount - 1 ? "\n" : ','), 'gb18030');
  170. } else {
  171. if (isset(self::$styleFormat[$field])) {
  172. echo sprintf("<td style='mso-number-format:\"%s\";'>%s</td>", self::$styleFormat[$field], $val);
  173. } else {
  174. echo sprintf('<td>%s</td>', $val);
  175. }
  176. }
  177. $i++;
  178. }
  179. $isCsv == false && print('</tr>');
  180. }
  181. $isCsv == false && print('</table>');
  182. exit;
  183. }
  184. public static function extra($extra, $extra_key, $val, $row)
  185. {
  186. $arr = ArrayHelper::getValue($extra, $extra_key, []);
  187. return ArrayHelper::getValue($arr, $val, '');
  188. }
  189. public static function dateIsEmpty($extra, $extra_key, $val, $row)
  190. {
  191. return strtotime($val) > 1000 ? $val : '';
  192. }
  193. public static function toFixed($extra, $extra_key, $val, $row)
  194. {
  195. return (string)sprintf("%.{$extra_key}f", floatval($val));
  196. }
  197. public static function dateFormat($extra, $extra_key, $val, $row)
  198. {
  199. return date('Y-m-d H:i:s', $val / 1000);
  200. }
  201. public static function trim($extra, $extra_key, $val, $row)
  202. {
  203. return str_replace(["\r", "\n", ","], ["", "", ","], $val);
  204. }
  205. public static function shopNameIsEmpty($extra, $extra_key, $val, $row)
  206. {
  207. return !empty($val) ? $val : '个人发布';
  208. }
  209. public static function extraConcat($extra, $extra_key, $val, $row)
  210. {
  211. $arr = explode('-', $extra_key);
  212. foreach ($arr as $key => $value) {
  213. $val .= ArrayHelper::getValue($extra[$value . 'Options'], $row[$value], '');
  214. }
  215. return $val;
  216. }
  217. }