This commit is contained in:
2025-08-13 18:31:52 +08:00
parent 17ad88608b
commit 275713f893
77 changed files with 10658 additions and 178 deletions

231
extend/alei/Export.php Normal file
View File

@@ -0,0 +1,231 @@
<?php
namespace alei;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
/**
* 导出类
*/
class Export
{
//导出选项
private $option = [
//导出文件路径
'file_path' => '',
//导出文件名
'file_name' => '导出文件',
//首行是否加粗
'header_bold' => true,
//垂直居中
'header_vertical_center' => true,
//水平居中
'header_horizontal_center' => true,
//首列高度
'header_row_height' => 30
];
private $column;
private $data;
/**
* @params Array|String $option_or_file_name 导出选项或者文件名
* @params String $file_path 文件保存路径
*/
public function __construct($option_or_file_name = null, $file_path = null)
{
if(!is_null($option_or_file_name)){
if(is_array($option_or_file_name)) {
//设置导出选项
$this->option = array_merge($this->option, $option_or_file_name);
}else if(is_string($option_or_file_name) && strlen($option_or_file_name) > 0){
//设置保存的文件名
$this->option['file_name'] = $option_or_file_name;
}
}
//设置保存的文件路径
if (!is_null($file_path) && is_string($file_path) && strlen($file_path) > 0) {
$this->option['file_path'] = $file_path;
}
}
/**
* 设置列参数
* @param String field 字段名
* @param String title 标题
* @param Int width 列宽
* @param Function|String formater [格式化器参数1字段值参数2行数据参数3行号] 或 [预定义方法:'time':格式化时间]
* @param String type 类型 default 'text'
* @param Boole vertical_center 是否垂直居中default false
* @param Boole horizontal_center 是否水平居中default false
*/
public function setColumn($column)
{
$this->column = $column;
}
/**
* 格式化行参数
*/
private function formatRowData($data)
{
$tmp = [];
foreach ($this->column as $key => $column) {
if (isset($data[$column['field']])) {
$tmp[$column['field']] = $data[$column['field']];
} else {
$tmp[$column['field']] = '';
}
if (isset($column['formater'])) {
if (gettype($column['formater']) === 'object' && is_callable($column['formater'])) {
$tmp[$column['field']] = $column['formater']($tmp[$column['field']], $data, $key);
} else if (is_string($column['formater'])) {
//格式化
switch($column['formater']){
case 'time': //时间戳转时间
$format_time = $column['format_time'] ?? 'Y-m-d H:i:s';
if (empty($tmp[$column['field']])) {
$tmp[$column['field']] = '';
} else {
$tmp[$column['field']] = date($format_time, $tmp[$column['field']]);
}
break;
default :
}
}
}
}
return $tmp;
}
/**
* 设置数据
*/
public function setData($list)
{
if (empty($this->column)) throw new \think\Exception('Please set the column parameters first!');
$data = [];
foreach ($list as $key => $val) {
$data[] = $this->formatRowData($val);
unset($list[$key]);
}
$this->data = $data;
}
/**
* 渲染表格并返回
* @params $column 列参数
* @params $data 导出数据
*/
public function build()
{
if (empty($this->column)) {
throw new \think\Exception('Please set the column parameters first!');
}
$spreadsheet = new Spreadsheet();
// 1获取活动工作薄
$sheet = $spreadsheet->getActiveSheet();
//最后一列列号
$end_row = count($this->column);
// 首行选择器
$first_cell = [1, 1, $end_row, 1];
//设置背景色
$sheet->getStyle($first_cell)->getFill()->setFillType(Fill::FILL_SOLID);
$sheet->getStyle($first_cell)->getFill()->getStartColor()->setARGB('FFeeeeee');
//首行加边框
$sheet->getStyle($first_cell)->getBorders()->applyFromArray([
'allBorders' => [
'borderStyle' => Border::BORDER_HAIR,
'color' => ['argb' => '666666']
]
]);
//加粗
if ($this->option['header_bold']) {
$sheet->getStyle($first_cell)->getFont()->setBold(true);
}
//垂直居中
if ($this->option['header_vertical_center']) {
$sheet->getStyle($first_cell)->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
}
//水平居中
if ($this->option['header_horizontal_center']) {
$sheet->getStyle($first_cell)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
}
//首行高度
$sheet->getRowDimension(1)->setRowHeight($this->option['header_row_height']);
foreach ($this->column as $key => $column) {
$sheet->setCellValue([$key + 1, 1], $column['title']);
$sheet->getColumnDimensionByColumn($key + 1)->setAutoSize(true);
}
foreach ($this->data as $key => $row) {
foreach ($this->column as $k => $column) {
$value = $row[$column['field']];
$cell = [$k + 1, $key + 2];
//换行
if (mb_strpos($value, PHP_EOL) !== false) {
$sheet->getStyle($cell)->getAlignment()->setWrapText(true);
}
//垂直居中
if (!empty($column['vertical_center'])) {
$sheet->getStyle($cell)->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
}
//水平居中
if (!empty($column['horizontal_center'])) {
$sheet->getStyle($cell)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
}
//设置文字
$sheet->setCellValueExplicit($cell, $value, DataType::TYPE_STRING);
}
unset($this->data[$key]);
}
//设置工作表标题
$sheet->setTitle($this->option['file_name']);
$this->option['file_path'] = $this->option['file_path'] == '' ? '' : ($this->option['file_path'] . '/' );
$url = '/export/' . $this->option['file_path'] . $this->option['file_name'] . '.xlsx';
$filePath = public_path() . str_replace('/', DIRECTORY_SEPARATOR, $url);
if(is_file($filePath) ){
//如果文件已经导出过则删除旧文件
// unlink($filePath);
}else if (!is_dir(dirname($filePath))) {
mkdir(dirname($filePath), 0700, true);
}
// 保存电子表格
$writer = new Xlsx($spreadsheet);
$writer->save($filePath);
return $url;
}
}