新增 excel 工具

This commit is contained in:
JaguarJack 2020-05-25 19:47:54 +08:00
parent c0e3726775
commit 2074c1f65d
4 changed files with 392 additions and 7 deletions

View File

@ -1 +1,220 @@
<?php
namespace catcher\library\excel;
use catcher\CatchUpload;
use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use think\file\UploadedFile;
class Excel
{
use MacroExcel;
/**
* @var ExcelContract $excel
*/
protected $excel;
protected $sheets;
protected $spreadsheet = null;
/**
* save
*
* @time 2020年05月25日
* @param ExcelContract $excel
* @param $path
* @param null $disk
* @throws Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @return void
*/
public function save(ExcelContract $excel, $path, $disk = null)
{
$this->excel = $excel;
// register worksheet for current excel
$this->registerWorksheet();
// set excel title
$this->setTitle();
// set excel headers
$this->setExcelHeaders();
// set cell width
$this->setSheetWidth();
// set worksheets
$this->setWorksheets();
(new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($this->spreadsheet))->save($path);
// $this->upload($disk, $path);
}
/**
* 设置 sheets
*
* @time 2020年05月25日
* @throws Exception
* @return void
*/
protected function setWorksheets()
{
$keys= $this->getKeys();
$isArray = $this->arrayConfirm();
$worksheet = $this->getWorksheet();
if (empty($keys)) {
if ($isArray) {
foreach ($this->excel->sheets() as $sheet) {
$worksheet->fromArray($sheet, null, $this->start . $this->row);
$this->incRow();
}
} else {
foreach ($this->excel->sheets() as $sheet) {
$worksheet->fromArray($sheet->toArray(), null, $this->start . $this->row);
$this->incRow();
}
}
} else {
if ($isArray) {
foreach ($this->excel->sheets() as $sheet) {
$worksheet->fromArray($this->getValuesByKeys($sheet, $keys), null, $this->start . $this->row);
$this->incRow();
}
} else {
foreach ($this->excel->sheets() as $sheet) {
$worksheet->fromArray($this->getValuesByKeys($sheet->toArray(), $keys), null, $this->start . $this->row);
$this->incRow();
}
}
}
}
/**
* 判断 sheet 是否是 array 类型
*
* @time 2020年05月25日
* @return bool
*/
protected function arrayConfirm()
{
$sheets = $this->excel->sheets();
$array = true;
foreach ($sheets as $sheet) {
$array = is_array($sheet);
break;
}
return $array;
}
/**
* 获取 item 特定 key 的值
*
* @time 2020年05月25日
* @param array $item
* @param array $keys
* @return array
*/
protected function getValuesByKeys(array $item, array $keys)
{
$array = [];
foreach ($keys as $key) {
$array[] = $item[$key];
}
return $array;
}
/**
* 设置 Excel 头部
*
* @time 2020年05月23日
* @throws Exception
*/
protected function setExcelHeaders()
{
$worksheet = $this->getWorksheet();
// get columns
$columns = $this->getSheetColumns();
// get start row
$startRow = $this->getStartRow();
foreach ($this->excel->headers() as $k => $header) {
$worksheet->getCell($columns[$k] . $startRow)->setValue($header);
}
$this->incRow();
}
/**
* get spreadsheet
*
* @time 2020年05月25日
* @return Spreadsheet
*/
protected function getSpreadsheet()
{
if (!$this->spreadsheet) {
$this->spreadsheet = new Spreadsheet();
}
return $this->spreadsheet;
}
/**
* 获取 active sheet
*
* @time 2020年05月25日
* @throws Exception
* @return Worksheet
*/
protected function getWorksheet()
{
return $this->getSpreadsheet()->getActiveSheet();
}
/**
* upload
*
* @time 2020年05月25日
* @param $disk
* @param $path
* @return string
* @throws \Exception
*/
protected function upload($disk, $path)
{
$upload = new CatchUpload;
return ($disk ? $upload->setDriver($disk) : $upload)->upload($this->uploadedFile($path));
}
/**
* get uploaded file
*
* @time 2020年05月25日
* @param $file
* @return UploadedFile
*/
protected function uploadedFile($file)
{
return new UploadedFile($file, pathinfo($file, PATHINFO_BASENAME));
}
}

View File

@ -1,14 +1,11 @@
<?php
namespace catcher\library\excel;
interface Excel
interface ExcelContract
{
public function title(): string;
public function headers(): array;
public function sheets(): array;
public function filename():string;
public function keys(): array ;
public function sheets();
}

View File

@ -1 +1,171 @@
<?php
namespace catcher\library\excel;
trait MacroExcel
{
/**
* @var string
*/
protected $start = 'A';
/**
* 开始行
*
* @var int
*/
protected $row = 1;
/**
* @var array
*/
protected $columns = [];
/**
* 设置开始的单元
*
* @time 2020年05月25日
* @return string
*/
protected function getStartSheet(): string
{
if (method_exists($this->excel, 'start')) {
return $this->excel->start();
}
return $this->start;
}
/**
* 设置单元格宽度
*
* @time 2020年05月25日
* @return void
*/
protected function setSheetWidth()
{
if (method_exists($this->excel, 'setWidth')) {
$width = $this->excel->setWidth();
foreach ($width as $sheet => $w) {
$this->getWorksheet()->getColumnDimension($sheet)->setWidth($w);
}
}
}
/**
* 设置 column 信息 ['A', 'B', 'C' ...]
*
* @time 2020年05月25日
* @return array
*/
protected function getSheetColumns()
{
if (empty($this->columns)) {
if (method_exists($this->excel, 'sheetColumns')) {
$this->columns = $this->excel->sheetColumns();
return $this->columns;
}
$start = $this->getStartSheet();
$columns = [];
// 通过 headers 推断需要的 columns
foreach ($this->excel->headers() as $k => $header) {
$columns[] = chr(ord($start) + $k);
}
return $columns;
}
return $this->columns;
}
/**
* set keys
*
* @time 2020年05月25日
* @return array
*/
protected function getKeys()
{
if (method_exists($this->excel, 'keys')) {
return $this->excel->keys();
}
return [];
}
/**
* set start row
*
* @time 2020年05月25日
* @return int
*/
protected function getStartRow()
{
if (method_exists($this->excel, 'setRow')) {
$this->row = $this->excel->setRow();
}
return $this->row;
}
/**
* 设置 title
*
* @time 2020年05月25日
* @return void
*/
protected function setTitle()
{
if (method_exists($this->excel, 'setTitle')) {
[$cells, $title, $style] = $this->excel->setTitle();
$this->getWorksheet()
->mergeCells($cells) // 合并单元格
->setCellValue(explode(':', $cells)[0], $title)
->getStyle($cells) // 设置样式
->getAlignment()
->setHorizontal($style);
}
}
/**
* 设置其他信息
*
* @time 2020年05月25日
* @return void
*/
protected function setOther()
{
if (method_exists($this->excel, 'setOther')) {
$this->excel->setOther($this->getWorksheet());
}
}
/**
* register worksheet for excel
*
* @time 2020年05月25日
* @return void
*/
protected function registerWorksheet()
{
if (method_exists($this->excel, 'getWorksheet')) {
$this->excel->getWorksheet($this->getWorksheet());
}
}
/**
* 增加 start row
*
* @time 2020年05月25日
* @return void
*/
protected function incRow()
{
++$this->row;
}
}

View File

@ -1 +0,0 @@
<?php