ListsExcelTrait.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeshop100%开源免费商用商城系统
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | 商业版本务必购买商业授权,以免引起法律纠纷
  8. // | 禁止对系统程序代码以任何目的,任何形式的再发布
  9. // | gitee下载:https://gitee.com/likeshop_gitee
  10. // | github下载:https://github.com/likeshop-github
  11. // | 访问官网:https://www.likeshop.cn
  12. // | 访问社区:https://home.likeshop.cn
  13. // | 访问手册:http://doc.likeshop.cn
  14. // | 微信公众号:likeshop技术社区
  15. // | likeshop团队 版权所有 拥有最终解释权
  16. // +----------------------------------------------------------------------
  17. // | author: likeshopTeam
  18. // +----------------------------------------------------------------------
  19. namespace app\common\lists;
  20. use app\common\cache\ExportCache;
  21. use PhpOffice\PhpSpreadsheet\IOFactory;
  22. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  23. use PhpOffice\PhpSpreadsheet\Style\Border;
  24. use PhpOffice\PhpSpreadsheet\Style\Fill;
  25. trait ListsExcelTrait
  26. {
  27. public int $pageStart = 1; //导出开始页码
  28. public int $pageEnd = 200; //导出介绍页码
  29. public string $fileName = ''; //文件名称
  30. /**
  31. * @notes 创建excel
  32. * @param $excelFields
  33. * @param $lists
  34. * @return string
  35. * @throws \PhpOffice\PhpSpreadsheet\Exception
  36. * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
  37. * @author 令狐冲
  38. * @date 2021/7/21 16:04
  39. * Excel显示数字时,
  40. 若是数字大于12位,它会自动转化为科学计数法;
  41. 若是数字大于15位,它不只用于科学计数法表示,还会只保留高15位,其余位都变0。
  42. *
  43. */
  44. public function createExcel($excelFields, $lists)
  45. {
  46. $title = array_values($excelFields);
  47. $letter_column = ['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'];
  48. $data = [];
  49. foreach ($lists as $row) {
  50. $temp = [];
  51. foreach ($excelFields as $key => $excelField) {
  52. $fieldData = $row[$key];
  53. if(is_numeric($fieldData) && strlen($fieldData) >= 11){
  54. $fieldData.="\t";
  55. }
  56. $temp[$key] = $fieldData;
  57. }
  58. $data[] = $temp;
  59. }
  60. $spreadsheet = new Spreadsheet();
  61. $sheet = $spreadsheet->getActiveSheet();
  62. //设置单元格内容
  63. foreach ($title as $key => $value) {
  64. // 单元格内容写入
  65. $sheet->setCellValueByColumnAndRow($key + 1, 1, $value);
  66. }
  67. //设置行高
  68. $spreadsheet->getActiveSheet()->getRowDimension(1)->setRowHeight(25);
  69. $row = 2; //从第二行开始
  70. foreach ($data as $item) {
  71. $column = 1;
  72. $merge_num = isset($item['goods_name_arr']) && is_array($item['goods_name_arr']) ? count($item['goods_name_arr']) : 0;//合并数量
  73. $value_key = 0;
  74. foreach ($item as $value) {
  75. //设置列宽
  76. $columnWidth = (is_array($value) ? strlen($value[0]) : strlen($value)) * 1.2;
  77. $columnWidth = max([$columnWidth, 15]);
  78. $spreadsheet->getActiveSheet()->getColumnDimension($letter_column[$value_key])->setWidth($columnWidth);
  79. if (is_array($value) && count($value) <= 1) {
  80. $value = $value[0] ?? '';
  81. }
  82. if ($merge_num > 1) {
  83. //合并单元格
  84. $spreadsheet->getActiveSheet()->mergeCells($letter_column[$value_key].$row.':'.$letter_column[$value_key].($row + $merge_num - 1));
  85. if (is_array($value)) {
  86. //将合并后的单元格拆分
  87. $spreadsheet->getActiveSheet()->unmergeCells($letter_column[$value_key].$row.':'.$letter_column[$value_key].($row + $merge_num - 1));
  88. foreach ($value as $key=>$val) {
  89. // 在 = 前面加个空格防止报错
  90. $val = strpos($val, '=') === 0 ? " " . $val : $val;
  91. //单元格内容写入
  92. $sheet->setCellValueByColumnAndRow($column, $row + $key, $val);
  93. }
  94. } else {
  95. // 在 = 前面加个空格防止报错
  96. $value = strpos($value, '=') === 0 ? " " . $value : $value;
  97. //单元格内容写入
  98. $sheet->setCellValueByColumnAndRow($column, $row, $value);
  99. }
  100. } else {
  101. // 在 = 前面加个空格防止报错
  102. $value = strpos($value, '=') === 0 ? " " . $value : $value;
  103. //单元格内容写入
  104. $sheet->setCellValueByColumnAndRow($column, $row, $value);
  105. }
  106. $column++;
  107. $value_key++;
  108. }
  109. if ($merge_num > 1) {
  110. for ($i=$row;$i<($row+$merge_num);$i++) {
  111. //设置行高
  112. $spreadsheet->getActiveSheet()->getRowDimension($i)->setRowHeight(25);
  113. }
  114. $row = $row + $merge_num;
  115. } else {
  116. //设置行高
  117. $spreadsheet->getActiveSheet()->getRowDimension($row)->setRowHeight(25);
  118. $row++;
  119. }
  120. }
  121. $getHighestRowAndColumn = $sheet->getHighestRowAndColumn();
  122. $HighestRow = $getHighestRowAndColumn['row'];
  123. $column = $getHighestRowAndColumn['column'];
  124. $titleScope = 'A1:' . $column . '1';//第一(标题)范围(例:A1:D1)
  125. $sheet->getStyle($titleScope)
  126. ->getFill()
  127. ->setFillType(Fill::FILL_SOLID) // 设置填充样式
  128. ->getStartColor()
  129. ->setARGB('26956d');
  130. // 设置文字颜色为白色
  131. $sheet->getStyle($titleScope)->getFont()->getColor()
  132. ->setARGB('FFFFFF');
  133. $allCope = 'A1:' . $column . $HighestRow;//整个表格范围(例:A1:D5)
  134. //设置水平垂直居中
  135. $styleArray = [
  136. 'alignment' => [
  137. 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
  138. 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
  139. ],
  140. ];
  141. $sheet->getStyle($allCope)->applyFromArray($styleArray);
  142. $sheet->getStyle($allCope)->getBorders()->getAllBorders()->setBorderStyle(Border::BORDER_THIN);
  143. $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
  144. //创建excel文件
  145. $exportCache = new ExportCache();
  146. $src = $exportCache->getSrc();
  147. if (!file_exists($src)) {
  148. mkdir($src, 0775, true);
  149. }
  150. $writer->save($src . $this->fileName);
  151. //设置本地excel缓存并返回下载地址
  152. return (string)(url('index/download/export', ['file' => $exportCache->setFile($this->fileName)], true, true));
  153. }
  154. /**
  155. * @notes 获取导出信息
  156. * @return array
  157. * @author 令狐冲
  158. * @date 2021/7/29 16:08
  159. */
  160. public function excelInfo()
  161. {
  162. $count = $this->count();
  163. $sum_page = max(ceil($count / $this->pageSize), 1);
  164. return [
  165. 'count' => $count, //所有数据记录数
  166. 'page_size' => $this->pageSize,//每页记录数
  167. 'sum_page' => $sum_page,//一共多少页
  168. 'max_page' => floor($this->pageSizeMax / $this->pageSize),//最多导出多少页
  169. 'all_max_size' => $this->pageSizeMax,//最多导出记录数
  170. 'page_start' => $this->pageStart,//导出范围页码开始值
  171. 'page_end' => min($sum_page, $this->pageEnd),//导出范围页码结束值
  172. 'file_name' => $this->fileName,//默认文件名
  173. ];
  174. }
  175. }