超简单的excel文件导出
希望以后还会用上吧。。。
推荐使用:phpspreadsheet 这个用了好多年了,个人蛮喜欢的。
具体选择看个人喜好吧,毕竟php导出excel的包/库的太多了。。。
最近写了个简单导出功能,当然也是简单的实现,应该满足日常项目使用。也可按需自行扩展或使用三方库,顺手记录下说不定啥时候又用上了。。
核心代码实现:
<?php
namespace App\Service\Excel;
class ExcelService
{
/**
* excel文本制表符
*/
const EXCEL_TAB = "\t";
const EXCEL_BOM = "\xEF\xBB\xBF";
const EXCEL_EXT_DEFAULT = '.xls';
/**
* 表头
* @var array
*/
private array $header;
/**
* 列值
* @var array
*/
private array $columns;
/**
* 后缀
* @var string
*/
private string $ext;
/**
* 文件名称
* @var string
*/
private string $fileName;
/**
* 导出数据
* @var array
*/
private array $content;
private \SplFileObject $fp;
/**
* @param $header | 表头
* @param $columns | 对应字段
* @param $title | title
* @param $ext | 文件后缀:csv,xlsx,xls
*/
public function __construct($header, $columns, $title = '', $ext = '')
{
$this->header = $header;
$this->columns = $columns;
$this->ext = $ext ? $ext : self::EXCEL_EXT_DEFAULT;
$this->fileName = $this->setFileName($title);
$this->outputInit();
$this->setBom();
$this->setHeader();
}
/**
* 初始响应文件
*/
public function outputInit(): void
{
$output = 'php://output';
header('Content-type:application/vnd.ms-excel; charset=utf-8');
header("Content-Disposition: attachment; filename={$this->fileName}");
$this->fp = new \SplFileObject($output, 'w');
}
/**
* UTF-8格式解决中文乱码问题,写入BOM头
* 也可采用iconv()转码gbk,excel默认gbk格式
*/
public function setBom(): void
{
$this->fp->fwrite(self::EXCEL_BOM);
}
/**
* 设置表格头部
* @return void
*/
public function setHeader(): void
{
$this->fp->fputcsv($this->header);
}
/**
* 设置表格内容
* @param $data
* @return void
*/
public function setContent($data): void
{
foreach ($data as $row) {
$arr = [];
foreach ($this->columns as $key => $column) {
$text = $row[$column] ?? '';
$arr[$key] = $text ? (self::EXCEL_TAB . $text) : $text;
}
$this->content[] = $arr;
}
}
/**
* 保存
* @return void
*/
public function save()
{
foreach ($this->content as $row) {
$this->fp->fputcsv($row);
}
unset($this->fp);
}
/**
* @param $title
* @param $ext
* @return string
*/
public function setFileName($title): string
{
return $title . '-' . microtime(true) * 10000 . $this->ext;
}
}
代码demo:
public function export(Request $request)
{
/**
* demo数据
*/
$data = [
['id' => 1, 'name' => '张三', 'age' => 18],
['id' => 2, 'name' => '历史', 'age' => 20],
['id' => 3, 'name' => '王五', 'age' => 22],
['id' => 4, 'name' => '王五2', 'age' => 22],
['id' => 6, 'name' => 'ff', 'age' => 23],
];
/**
* 导出配置可写到config统一管理
*/
$exportConfig = [
['id' => 'id', 'name' => '序号'],
['id' => 'name', 'name' => '姓名'],
['id' => 'age', 'name' => '年龄'],
];
$header = array_column($exportConfig, 'name');
$columns = array_column($exportConfig, 'id');
$excel = new ExcelService($header, $columns, '导出试试', '.xlsx');
$totalCount = count($data);
$pageSize = 2;
//大量数据分批次导出
for ($i = 1; $i <= ceil($totalCount / $pageSize); $i++) {
//获取数据
$res = array_slice($data, ($i - 1) * $pageSize, $pageSize);
$excel->setContent($res);
}
$excel->save();
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐使用xlswriter
你封装的超简单的导出类,有2个场景问题,你是怎么解决的?
setContent()
函数,将数据存储,这时候你的内存开销会很大,你如何解决呢?都4202年了 还在用xls... :smile:
直接xlswriter吧
分享一个自己在生产环境中用的
function.php
,使用的是xlswriter
扩展定义
write_to_xlsx
函数使用数组导出文件
使用闭包导出文件