PHP使用xlswriter进行大数据的导入导出的方法是什么?
导读:今天这篇给大家分享的知识是“PHP使用xlswriter进行大数据的导入导出的方法是什么?”,小编觉得挺不错的,对大家学习或是工作可能会有所帮助,对此分享发大家做个参考,希望这篇“PHP使用xlswriter进行大数据的导入导出的方法是什么...
今天这篇给大家分享的知识是“PHP使用xlswriter进行大数据的导入导出的方法是什么?”,小编觉得挺不错的,对大家学习或是工作可能会有所帮助,对此分享发大家做个参考,希望这篇“PHP使用xlswriter进行大数据的导入导出的方法是什么?”文章能帮助大家解决问题。PHP如何使用xlswriter进行大数据的导入导出?下面本篇文章给大家介绍一下PHP大数据xlswriter导入导出(最优数据化)的方法,希望对大家有所帮助!
本文介绍基于PHP扩展xlswriter的Vtiful\Kernel\Excel类可以支持无限层级的复杂表头导出!后续也可能会持续更新优化
一、准备xlswriter扩展
1、windows系统:
到PECL网站下载符合自己本地PHP环境的ddl文件下载地址:https://pecl.php.net/package/xlswriter,并复制到PHP的扩展目录ext文件夹下,修改php.ini文件,
加上这行
extension=xlswriter
2、Linux系统:
使用命令安装
pecl install xlswriter
php配置文件添加
extension = xlswriter.so
重启:php nginx 查看PHP安装xlswriter拓展
二、封装导出类文件(重点来了)
?php
namespace App\Services;
use Vtiful\Kernel\Excel;
class MultiFloorXlsWriterService
{
// 默认宽度
private $defaultWidth = 16;
// 默认导出格式
private $exportType = '.xlsx';
// 表头最大层级
private $maxHeight = 1;
// 文件名
private $fileName = null;
private $xlsObj;
private $fileObject;
private $format;
/**
* MultiFloorXlsWriterService constructor.
* @throws \App\Exceptions\ApiException
*/
public function __construct()
{
// 文件默认输出地址
$path = base_path().'/public/uploads/excel';
$config = [
'path' =>
$path
];
$this->
xlsObj = (new \Vtiful\Kernel\Excel($config));
}
/**
* 设置文件名
* @param string $fileName
* @param string $sheetName
* @author LWW
*/
public function setFileName(string $fileName = '', string $sheetName = 'Sheet1')
{
$fileName = empty($fileName) ? (string)time() : $fileName;
$fileName .= $this->
exportType;
$this->
fileName = $fileName;
$this->
fileObject = $this->
xlsObj->
fileName($fileName, $sheetName);
$this->
format = (new \Vtiful\Kernel\Format($this->
fileObject->
getHandle()));
}
/**
* 设置表头
* @param array $header
* @param bool $filter
* @throws \Exception
* @author LWW
*/
public function setHeader(array $header, bool $filter = false)
{
if (empty($header)) {
throw new \Exception('表头数据不能为空');
}
if (is_null($this->
fileName)) {
self::setFileName(time());
}
// 获取单元格合并需要的信息
$colManage = self::setHeaderNeedManage($header);
// 完善单元格合并信息
$colManage = self::completeColMerge($colManage);
// 合并单元格
self::queryMergeColumn($colManage, $filter);
}
/**
* 填充文件数据
* @param array $data
* @author LWW
*/
public function setData(array $data)
{
foreach ($data as $row =>
$datum) {
foreach ($datum as $column =>
$value) {
$this->
fileObject->
insertText($row + $this->
maxHeight, $column, $value);
}
}
}
/**
* 添加Sheet
* @param string $sheetName
* @author LWW
*/
public function addSheet(string $sheetName)
{
$this->
fileObject->
addSheet($sheetName);
}
/**
* 保存文件至服务器
* @return mixed
* @author LWW
*/
public function output()
{
return $this->
fileObject->
output();
}
/**
* 输出到浏览器
* @param string $filePath
* @throws \Exception
* @author LWW
*/
public function excelDownload(string $filePath)
{
$fileName = $this->
fileName;
$userBrowser = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('/MSIE/i', $userBrowser)) {
$fileName = urlencode($fileName);
}
else {
$fileName = iconv('UTF-8', 'GBK//IGNORE', $fileName);
}
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header('Content-Disposition: attachment;
filename="' . $fileName . '"');
header('Content-Length: ' . filesize($filePath));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Cache-Control: max-age=0');
header('Pragma: public');
if (ob_get_contents()) {
ob_clean();
}
flush();
if (copy($filePath, 'php://output') === false) {
throw new \Exception($filePath . '地址出问题了');
}
// 删除本地文件
@unlink($filePath);
exit();
}
/**
* 组装单元格合并需要的信息
* @param array $header
* @param int $col
* @param int $cursor
* @param array $colManage
* @param null $parent
* @param array $parentList
* @return array
* @throws \Exception
* @author LWW
*/
private function setHeaderNeedManage(array $header,int $col = 1,int &
$cursor = 0,array &
$colManage = [], $parent = null,array $parentList = [])
{
foreach ($header as $head) {
if (empty($head['title'])) {
throw new \Exception('表头数据格式有误');
}
if (is_null($parent)) {
// 循环初始化
$parentList = [];
$col = 1;
}
else {
// 递归进入,高度和父级集合通过相同父级条件从已有数组中获取,避免递归增加与实际数据不符
foreach ($colManage as $value) {
if ($value['parent'] == $parent) {
$parentList = $value['parentList'];
$col = $value['height'];
break;
}
}
}
// 单元格标识
$column = $this->
getColumn($cursor) . $col;
// 组装单元格需要的各种信息
$colManage[$column] = [
'title' =>
$head['title'], // 标题
'cursor' =>
$cursor, // 游标
'cursorEnd' =>
$cursor, // 结束游标
'height' =>
$col, // 高度
'width' =>
$this->
defaultWidth, // 宽度
'mergeStart' =>
$column, // 合并开始标识
'hMergeEnd' =>
$column, // 横向合并结束标识
'zMergeEnd' =>
$column, // 纵向合并结束标识
'parent' =>
$parent, // 父级标识
'parentList' =>
$parentList, // 父级集合
];
if (isset($head['children']) &
&
!empty($head['children']) &
&
is_array($head['children'])) {
// 有下级,高度加一
$col += 1;
// 当前标识加入父级集合
$parentList[] = $column;
$this->
setHeaderNeedManage($head['children'], $col, $cursor, $colManage, $column, $parentList);
}
else {
// 没有下级,游标加一
$cursor += 1;
}
}
return $colManage;
}
/**
* 完善单元格合并信息
* @param array $colManage
* @return mixed
* @author LWW
*/
private function completeColMerge(array $colManage)
{
$this->
maxHeight = max(array_column($colManage, 'height'));
$parentManage = array_column($colManage, 'parent');
foreach ($colManage as $index =>
$value) {
// 设置横向合并结束范围:存在父级集合,把所有父级的横向合并结束范围设置为当前单元格
if (!is_null($value['parent']) &
&
!empty($value['parentList'])) {
foreach ($value['parentList'] as $parent) {
$colManage[$parent]['hMergeEnd'] = self::getColumn($value['cursor']) . $colManage[$parent]['height'];
$colManage[$parent]['cursorEnd'] = $value['cursor'];
}
}
// 设置纵向合并结束范围:当前高度小于最大高度 且 不存在以当前单元格标识作为父级的项
$checkChildren = array_search($index, $parentManage);
if ($value['height'] $this->
maxHeight &
&
!$checkChildren) {
$colManage[$index]['zMergeEnd'] = self::getColumn($value['cursor']) . $this->
maxHeight;
}
}
return $colManage;
}
/**
* 合并单元格
* @param array $colManage
* @param bool $filter
* @author LWW
*/
private function queryMergeColumn(array $colManage,bool $filter)
{
foreach ($colManage as $value) {
$this->
fileObject->
mergeCells("{
$value['mergeStart']}
:{
$value['zMergeEnd']}
", $value['title']);
$this->
fileObject->
mergeCells("{
$value['mergeStart']}
:{
$value['hMergeEnd']}
", $value['title']);
// 设置单元格需要的宽度
if ($value['cursor'] != $value['cursorEnd']) {
$value['width'] = ($value['cursorEnd'] - $value['cursor'] + 1) * $this->
defaultWidth;
}
// 设置列单元格样式
$toColumnStart = self::getColumn($value['cursor']);
$toColumnEnd = self::getColumn($value['cursorEnd']);
$this->
fileObject->
setColumn("{
$toColumnStart}
:{
$toColumnEnd}
", $value['width']);
}
// 是否开启过滤选项
if ($filter) {
// 获取最后的单元格标识
$filterEndColumn = self::getColumn(end($colManage)['cursorEnd']) . $this->
maxHeight;
$this->
fileObject->
autoFilter("A1:{
$filterEndColumn}
");
}
}
/**
* 获取单元格列标识
* @param int $num
* @return string
* @author LWW
*/
private function getColumn(int $num)
{
return Excel::stringFromColumnIndex($num);
}
}
三、使用示例
代码如下
/**
* 导出测试
* @author LWW
*/
public function export()
{
$header = [
[
'title' =>
'一级表头1',
'children' =>
[
[
'title' =>
'二级表头1',
],
[
'title' =>
'二级表头2',
],
[
'title' =>
'二级表头3',
],
]
],
[
'title' =>
'一级表头2'
],
[
'title' =>
'一级表头3',
'children' =>
[
[
'title' =>
'二级表头1',
'children' =>
[
[
'title' =>
'三级表头1',
],
[
'title' =>
'三级表头2',
],
]
],
[
'title' =>
'二级表头2',
],
[
'title' =>
'二级表头3',
'children' =>
[
[
'title' =>
'三级表头1',
'children' =>
[
[
'title' =>
'四级表头1',
'children' =>
[
[
'title' =>
'五级表头1'
],
[
'title' =>
'五级表头2'
]
]
],
[
'title' =>
'四级表头2'
]
]
],
[
'title' =>
'三级表头2',
],
]
]
]
],
[
'title' =>
'一级表头4',
],
[
'title' =>
'一级表头5',
],
];
$data= [];
// header头规则 title表示列标题,children表示子列,没有子列children可不写或为空
for ($i = 0;
$i 100;
$i++) {
$data[] = [
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
'这是第'. $i .'行测试',
];
}
$fileName = '很厉害的文件导出类';
$xlsWriterServer = new MultiFloorXlsWriterService();
$xlsWriterServer->
setFileName($fileName, '这是Sheet1别名');
$xlsWriterServer->
setHeader($header, true);
$xlsWriterServer->
setData($data);
$xlsWriterServer->
addSheet('这是Sheet2别名');
$xlsWriterServer->
setHeader($header);
//这里可以使用新的header
$xlsWriterServer->
setData($data);
// 这里也可以根据新的header定义数据格式
$filePath = $xlsWriterServer->
output();
// 保存到服务器
$xlsWriterServer->
excelDownload($filePath);
// 输出到浏览器
}
导出效果
以上就是关于PHP使用xlswriter进行大数据的导入导出的方法是什么?的介绍,本文内容仅供参考,有需要的朋友可以借鉴了解看看,希望对大家学习或工作,想要了解更多欢迎关注网络,小编每天都会为大家更新不同的知识。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: PHP使用xlswriter进行大数据的导入导出的方法是什么?
本文地址: https://pptw.com/jishu/651229.html
