231 lines
7.5 KiB
PHP
231 lines
7.5 KiB
PHP
<?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;
|
||
}
|
||
|
||
} |