|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
|
|
|
use Illuminate\Support\Facades\File;
|
|
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 批量导出
|
|
|
|
* Class BatchExportService
|
|
|
|
* @package App\Services
|
|
|
|
* @author zbj
|
|
|
|
* @date 2023/5/8
|
|
|
|
*/
|
|
|
|
class BatchExportService
|
|
|
|
{
|
|
|
|
|
|
|
|
private $name = '';
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
private $data = [];
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var null | \PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
|
|
*/
|
|
|
|
private $spreadsheet = null;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 包头与字段映射
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
private $head = [];
|
|
|
|
|
|
|
|
|
|
|
|
public function __construct($name)
|
|
|
|
{
|
|
|
|
$this->name = $name;
|
|
|
|
$this->spreadsheet = new Spreadsheet();
|
|
|
|
$this->spreadsheet->setActiveSheetIndex(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* config hook
|
|
|
|
* @param $callback
|
|
|
|
* @return $this
|
|
|
|
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
|
|
|
*/
|
|
|
|
public function config($callback)
|
|
|
|
{
|
|
|
|
if(is_callable($callback)) {
|
|
|
|
$callback($this->spreadsheet->getActiveSheet(),$this->spreadsheet);
|
|
|
|
}
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 设置表头
|
|
|
|
* @param array $data
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function head($map = [])
|
|
|
|
{
|
|
|
|
$this->head = $map;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $data
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function data($data)
|
|
|
|
{
|
|
|
|
$this->data = $data;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return false|string
|
|
|
|
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
|
|
|
|
* @author zbj
|
|
|
|
* @date 2023/5/8
|
|
|
|
*/
|
|
|
|
public function save()
|
|
|
|
{
|
|
|
|
$file = "runtime/export/".date('Y-m-d')."/{$this->name}_" . date('YmdHis') . ".xlsx";
|
|
|
|
$filename = public_path($file);
|
|
|
|
|
|
|
|
if (!is_dir(dirname($filename))) {
|
|
|
|
@mkdir(dirname($filename),0755, true);
|
|
|
|
}
|
|
|
|
$this->render();
|
|
|
|
|
|
|
|
$writer = new Xlsx($this->spreadsheet);
|
|
|
|
$writer->save($filename);
|
|
|
|
if(file_exists($filename) && filesize($filename)) {
|
|
|
|
return $file;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 进行数据渲染
|
|
|
|
* 遍历所有的单元格处理文件,进行数据处理
|
|
|
|
* @return $this
|
|
|
|
* @author zbj
|
|
|
|
* @date 2023/5/8
|
|
|
|
*/
|
|
|
|
protected function render()
|
|
|
|
{
|
|
|
|
|
|
|
|
$map = [];
|
|
|
|
$sheet = $this->spreadsheet->getActiveSheet();
|
|
|
|
$i = 0;
|
|
|
|
foreach ($this->head as $k=>$title) {
|
|
|
|
$chr = chr(65+$i);
|
|
|
|
$map[$chr] = $k;
|
|
|
|
if(is_array($title)) {
|
|
|
|
$title = $title[0];
|
|
|
|
}
|
|
|
|
$sheet->setCellValue($chr . "1", $title);
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
foreach ($this->data as $k=>$item) {
|
|
|
|
foreach ($map as $chr => $field) {
|
|
|
|
if(is_array($this->head[$field]) && is_callable($this->head[$field][1])) { //TODO 进行字段内容的处理
|
|
|
|
$this->head[$field][1]($sheet, $chr . ($k + 2), $item[$field]);
|
|
|
|
}
|
|
|
|
$sheet->setCellValue($chr . ($k + 2), $this->getDataValue($field, $item));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 读取指定字段的value, 支持"."形式指定多维数组
|
|
|
|
* @param $name
|
|
|
|
* @param $data
|
|
|
|
* @return mixed|null
|
|
|
|
* @author zbj
|
|
|
|
* @date 2023/5/8
|
|
|
|
*/
|
|
|
|
protected function getDataValue($name, $data)
|
|
|
|
{
|
|
|
|
if(false === strpos($name, '.')) {
|
|
|
|
return $data[$name] ?? null;
|
|
|
|
}
|
|
|
|
$name = explode('.', $name);
|
|
|
|
$name[0] = strtolower($name[0]);
|
|
|
|
|
|
|
|
// 按.拆分成多维数组进行判断
|
|
|
|
foreach ($name as $val) {
|
|
|
|
if (isset($data[$val])) {
|
|
|
|
$data = $data[$val];
|
|
|
|
} else {
|
|
|
|
$data = null;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|