webman_duanju/extend/alei/Export.php

231 lines
7.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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;
}
}