cehi
This commit is contained in:
288
app/Admin/Exporters/NewCouponExport.php
Normal file
288
app/Admin/Exporters/NewCouponExport.php
Normal file
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Exporters;
|
||||
|
||||
use Encore\Admin\Grid\Exporters\ExcelExporter;
|
||||
|
||||
class NewCouponExport extends ExcelExporter
|
||||
{
|
||||
protected $fileName = null;
|
||||
protected $debug = false;
|
||||
protected $dealColumnList = [];
|
||||
protected $columnCallback = null;
|
||||
protected $addColumnList = [];
|
||||
protected $appendColumn = [];
|
||||
protected $perLimit = 1500;
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
$model = $this;
|
||||
$grid = $this->grid;
|
||||
$columns = $this->getColumns();
|
||||
$columns = $this->addingColumn($columns);
|
||||
|
||||
$call_back = function ($page, $limit) use ($model, $grid, $columns) {
|
||||
$model->page = $page;
|
||||
$grid->paginate($limit);
|
||||
$model->setGrid($grid);
|
||||
request()->offsetSet('per_page', $limit);
|
||||
|
||||
$list = $model->getQuery()->get()->toArray();
|
||||
$list = $this->dealColumn($columns, $list);
|
||||
if ($this->columnCallback) {
|
||||
$list = call_user_func($this->columnCallback, $columns, $list);
|
||||
}
|
||||
return $list;
|
||||
};
|
||||
if ($this->debug) {
|
||||
dd($columns, call_user_func($call_back, 1, 20));
|
||||
}
|
||||
$file_name = $this->fileName ? $this->fileName : $this->getTable().date('YmdHis');
|
||||
$data_count = $this->getQuery()->count();
|
||||
$perPage = request()->get('per_page', $this->perLimit);
|
||||
$this->exportCsv($file_name, $columns, $call_back, $data_count, $perPage);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件名
|
||||
*
|
||||
* @param null $file_name
|
||||
*/
|
||||
public function setName($file_name = null)
|
||||
{
|
||||
if ($file_name) {
|
||||
$this->fileName = $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 设置处理字段值的规则
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2023/2/1 15:42
|
||||
* @param $column
|
||||
* @param \Closure $call_back
|
||||
*/
|
||||
public function setColumn($column, \Closure $call_back)
|
||||
{
|
||||
$this->dealColumnList[$column] = $call_back;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加字段
|
||||
*
|
||||
* @param $column
|
||||
* @param $name
|
||||
* @param null|string|\Closure $after_column
|
||||
* @param null|\Closure $call_back
|
||||
*/
|
||||
public function addColumn($column, $name, $after_column = null, $call_back = null)
|
||||
{
|
||||
if ($after_column instanceof \Closure) {
|
||||
$this->addColumnList[$column] = $after_column;
|
||||
$this->appendColumn[$column] = [$name, null];
|
||||
} else {
|
||||
if ($call_back instanceof \Closure) {
|
||||
$this->addColumnList[$column] = $call_back;
|
||||
$this->appendColumn[$column] = [$name, $after_column];
|
||||
} else {
|
||||
$this->appendColumn[$column] = [$name, $after_column];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 正式追加字段
|
||||
*
|
||||
* @param $columns
|
||||
* @return array
|
||||
*/
|
||||
protected function addingColumn($columns): array
|
||||
{
|
||||
if (! $this->appendColumn) {
|
||||
return $columns;
|
||||
}
|
||||
$keys = array_keys($columns);
|
||||
foreach ($this->appendColumn as $column => $item) {
|
||||
list ($name, $after_column) = $item;
|
||||
if (! empty($after_column) && in_array($after_column, $keys)) {
|
||||
$index = array_search($after_column, $keys);
|
||||
array_splice($keys, $index + 1, 0, $column);
|
||||
} else {
|
||||
array_push($keys, $column);
|
||||
}
|
||||
$columns[$column] = $name;
|
||||
}
|
||||
$result = [];
|
||||
foreach ($keys as $column) {
|
||||
$result[$column] = $columns[$column] ?? $column;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段值重新处理 回调函数
|
||||
*
|
||||
* @param \Closure $call_back
|
||||
*/
|
||||
public function setList(\Closure $call_back)
|
||||
{
|
||||
$this->columnCallback = $call_back;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理有共同特征的字段值
|
||||
*
|
||||
* @param $columns
|
||||
* @param $list
|
||||
* @return mixed
|
||||
*/
|
||||
protected function dealColumn($columns, $list)
|
||||
{
|
||||
if (! $list) {
|
||||
return $list;
|
||||
}
|
||||
$deal = array_keys($this->dealColumnList);
|
||||
$add = array_keys($this->addColumnList);
|
||||
foreach ($list as $index => $data) {
|
||||
foreach ($columns as $column => $name) {
|
||||
switch ($column) {
|
||||
case strpos($column, '.') !== false :
|
||||
$keys = explode('.', $column);
|
||||
$value = $data;
|
||||
for ($i = 0; $i < count($keys); $i++) {
|
||||
$value = $value[$keys[$i]] ?? [];
|
||||
}
|
||||
if (is_array($value)) {
|
||||
$value = empty($value) ? '' : json_encode($value, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
$data[$column] = $value;
|
||||
break;
|
||||
}
|
||||
if ($this->dealColumnList && in_array($column, $deal)) {
|
||||
$data[$column] = call_user_func_array($this->dealColumnList[$column],
|
||||
[$data[$column] ?? '', $data]);
|
||||
}
|
||||
if ($this->addColumnList && in_array($column, $add)) {
|
||||
$data[$column] = call_user_func($this->addColumnList[$column], $data);
|
||||
}
|
||||
}
|
||||
$list[$index] = $data;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选中的导出字段
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getColumns(): array
|
||||
{
|
||||
$columns = [];
|
||||
foreach ($this->grid->getColumns() as $column) {
|
||||
$columns[$column->getName()] = $column->getLabel();
|
||||
}
|
||||
$column_string = request()->get('_columns_', '');
|
||||
if (! $column_string) {
|
||||
return $columns;
|
||||
}
|
||||
$column_array = explode(',', $column_string);
|
||||
$column_list = [];
|
||||
foreach ($columns as $column => $name) {
|
||||
if (in_array($column, $column_array)) {
|
||||
$column_list[$column] = $name;
|
||||
}
|
||||
}
|
||||
return $column_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印
|
||||
*/
|
||||
public function dd()
|
||||
{
|
||||
$this->debug = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出CSV
|
||||
*
|
||||
* @param string $file_name 文件名
|
||||
* @param array $head_list 表头
|
||||
* @param int $data_count 总数
|
||||
* @param int $page_limit 每页数量
|
||||
* @param \Closure $call_back 获取分页数据的回调函数
|
||||
*/
|
||||
function exportCsv(
|
||||
string $file_name,
|
||||
array $head_list,
|
||||
\Closure $call_back,
|
||||
int $data_count,
|
||||
int $page_limit = 0
|
||||
) {
|
||||
set_time_limit(0);
|
||||
ini_set('memory_limit', -1);
|
||||
header('Content-Type: application/vnd.ms-excel');
|
||||
header('Content-Disposition: attachment;filename="'.$file_name.'.csv"');
|
||||
header('Cache-Control: max-age=0');
|
||||
//打开PHP文件句柄,php://output 表示直接输出到浏览器
|
||||
$fp = fopen('php://output', 'a');
|
||||
$head = [];
|
||||
//输出Excel列名信息
|
||||
foreach ($head_list as $name) {
|
||||
//CSV的Excel支持GBK编码,一定要转换,否则乱码
|
||||
$head[] = iconv('utf-8', 'gbk', $name);
|
||||
}
|
||||
//将数据通过fputcsv写到文件句柄
|
||||
fputcsv($fp, $head);
|
||||
$page_limit = $data_count > $page_limit ? $page_limit : $data_count;
|
||||
$page_count = ceil($data_count / $page_limit);
|
||||
for ($page = 1; $page <= $page_count; $page++) {
|
||||
//逐页取出数据,不浪费内存
|
||||
$data_list = call_user_func($call_back, $page, $page_limit);
|
||||
if (! $data_list) {
|
||||
continue;
|
||||
}
|
||||
foreach ($data_list as $data) {
|
||||
$row = [];
|
||||
foreach ($head_list as $key => $name) {
|
||||
$value = $data[$key] ?? '';
|
||||
$row[] = iconv('utf-8', 'gbk', $value);
|
||||
}
|
||||
|
||||
fputcsv($fp, $row);
|
||||
unset($row);
|
||||
}
|
||||
//刷新一下输出buffer,防止由于数据过多内存不足
|
||||
ob_flush();
|
||||
flush();
|
||||
info($page.'/'.$page_count.' time= '.$this->getElapsedTime().' memory= '.$this->getMemoryUsage());
|
||||
}
|
||||
fclose($fp);
|
||||
exit();
|
||||
}
|
||||
|
||||
public function getElapsedTime(int $decimals = 2): string
|
||||
{
|
||||
return number_format(microtime(true) - request()->server('REQUEST_TIME_FLOAT'), $decimals).' s';
|
||||
}
|
||||
|
||||
public function getMemoryUsage($precision = 2): string
|
||||
{
|
||||
$size = memory_get_usage(true);
|
||||
|
||||
$unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];
|
||||
|
||||
return round($size / pow(1024, ($i = floor(log($size, 1024)))), $precision).' '.$unit[$i];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user