由于 PHPExcel 已经不再维护,所以推荐使用 PhpSpreadsheet 来实现在 Thinkphp5 中实现 excel 的导入或导出功能,PhpSpreadsheet 是一个用 php 编写的库,并引入了命名空间,PSR 规范等。这里简单介绍下 PhpSpreadsheet 在Thinkphp5 框架中的使用方法。
PHP5.6 或更高版本,推荐 PHP7
支持 php_zip 扩展
支持 php_xml 扩展
支持 php_gd2 扩展
支持读取 .xls,.xlsx,.html,.csv 等格式文件,支持写入导出 .xls,.xlsx,.html,.csv,.pdf 格式文件。提供丰富的 API,提供单元格样式设置、Excel 表格属性设置、图表设置等等诸多功能。使用 PhpSpreadsheet 完全可以生成一个外观结构都满足你的Excel 表格文件。卓越的性能,尤其在 PHP7 上表现优异,比 PHPExcel 强大很多。
PhpSpreadsheet 官网地址
在 composer.json 中使用阿里云中国镜像
"repositories": {
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
}
//默认会安装最新版本
composer require phpoffice/phpspreadsheet
运行完成以后就等待安装完成
在 composer.json 文件中可以看到安装的版本信息
"require": {
"php": ">=7.1",
"topthink/framework": "5.1.*",
"phpoffice/phpspreadsheet": "^1.15"
},
新建一个控制器 TestexcelController.php
//测试 PhpSpreadsheet 中的功能
namespace app\daba\controller;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\Controller;
use think\Request;
getActiveSheet()
/**
* @param Request $request
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
*/
public function handleExcel(Request $request)
{
//实例化Spreadsheet对象
$spreadsheet = new Spreadsheet();
//获取活动工作薄
$sheet = $spreadsheet -> getActiveSheet();
}
方式一:getCell
方式二:getCellByColumnAndRow
//获取单元格
$cellA = $sheet -> getCell('A1');//获取A1单元格
//获取单元格
$cellB = $sheet -> getCellByColumnAndRow(1, 2);//获取坐标为1,2也就是A2单元格
setValue()
//获取单元格
$cellA = $sheet -> getCell('A1');
//设置单元格值
$cellA -> setValue('囚牛');
getValue() 获取单元格值
getCoordinate() 获取单元格坐标
//获取单元格
$cellA = $sheet -> getCell('A1');
//设置单元格值
$cellA -> setValue('囚牛');
echo('值: '.$cellA -> getValue());
echo('坐标: '.$cellA -> getCoordinate());
值: 囚牛坐标: A1
//测试 PhpSpreadsheet 中的功能
namespace app\daba\controller;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use think\Controller;
use think\Request;
class TestexcelController extends Controller
{
/**
* @param Request $request
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
*/
public function handleExcel(Request $request)
{
//实例化Spreadsheet对象
$spreadsheet = new Spreadsheet();
//获取活动工作薄
$sheet = $spreadsheet -> getActiveSheet();
//获取单元格
$cellA = $sheet -> getCell('A1');
//设置单元格值
$cellA -> setValue('囚牛');
// echo('值: '.$cellA -> getValue());
//
// echo('坐标: '.$cellA -> getCoordinate());
//获取单元格
$cellB = $sheet -> getCellByColumnAndRow(1, 2);
//设置单元格值
$cellB -> setValue('睚眦');
//获取设置单元格,链式操作
$sheet -> getCell('A3') -> setValue('嘲风');
$sheet -> getCellByColumnAndRow(1, 4) -> setValue('蒲牢');
$sheet -> getCell('A5') -> setValue('狻猊');
$sheet -> getCellByColumnAndRow(1, 6) -> setValue('霸下');
$sheet -> getCell('A7') -> setValue('狴犴');
$sheet -> getCellByColumnAndRow(1, 8) -> setValue('负屃');
$sheet -> getCell('A9') -> setValue('螭吻');
//定义文件名称,需要带有定义的后缀名
$filename = 'test.xlsx';
ob_end_clean(); //清除缓冲区,避免乱码
//将输出重定向到客户端的web浏览器
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
//如果浏览器为IE9
header('Cache-Control: max-age=1');
//如果通过SSL向IE提供服务
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: cache, must-revalidate');//HTTP/1.1
header('Pragma: public');//HTTP/1.0
$writer = IOFactory ::createWriter($spreadsheet, 'Xlsx');
$writer -> save('php://output');
exit;
}
}
setCellValue(‘参数1’,‘参数2’)
参数1:单元格位置
参数2:单元格的值
setCellValueByColumnAndRow(‘参数1’,‘参数2’,‘参数3’)
参数1:列位置
参数2:行位置
参数3:单元格的值
/**
* @param Request $request
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
*/
public function downExcel(Request $request)
{
//实例化Spreadsheet对象
$spreadsheet = new Spreadsheet();
//获取活动工作薄
$sheet = $spreadsheet -> getActiveSheet();
//定义一个excel的header表头
$header = ['A1'=>'ID','B1'=>'昵称','C1'=>'登录名','D1'=>'手机号','E1'=>'邮箱'];
foreach ($header as $key=>$value) {
$sheet->setCellValue($key,$value);
}
//定义excel之中的内容
$list_data = [
[
'id'=>1,
'nickname'=>'xiaowang',
'name'=>'小王',
'phone'=>12345678900,
'mail'=>'[email protected]'
],
[
'id'=>2,
'nickname'=>'xiaoli',
'name'=>'小李',
'phone'=>12345678900,
'mail'=>'[email protected]'
]
];
$i = 2;//excel表格从第2行开始填入数据
foreach ($list_data as $k => $v) {
$sheet->setCellValueByColumnAndRow(1,$i,$v['id']);
$sheet->setCellValueByColumnAndRow(2,$i,$v['nickname']);
$sheet->setCellValueByColumnAndRow(3,$i,$v['name']);
$sheet->setCellValueByColumnAndRow(4,$i,$v['phone']);
$sheet->setCellValueByColumnAndRow(5,$i,$v['mail']);
$i++;//$i从2累加
}
//定义文件名称,需要带有定义的后缀名
$filename = 'test.xlsx';
ob_end_clean(); //清除缓冲区,避免乱码
//将输出重定向到客户端的web浏览器
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
//如果浏览器为IE9
header('Cache-Control: max-age=1');
//如果通过SSL向IE提供服务
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: cache, must-revalidate');//HTTP/1.1
header('Pragma: public');//HTTP/1.0
$writer = IOFactory ::createWriter($spreadsheet, 'Xlsx');
$writer -> save('php://output');
exit;
}
getStyle(‘参数1’) 获取单元格样式
参数1:单元格的位置
getFont() 获取单元格文字样式
setBold(参数1) 设置文字粗细
参数1:true加粗
参数1:false取消
setName(‘参数1’) 设置文字字体
参数1:字体
setSize(参数1) 设置文字大小
参数1:字体大小
//B1昵称字体加粗,设置成宋体,字号20
$sheet->getStyle('B1')->getFont()->setBold(true)->setName('宋体')->setSize(20);
getColor() 获取坐标颜色
getRGB() 获取字体颜色
getARGB() 获取字体颜色
setRGB(‘参数1’) 设置字体颜色
参数1:颜色值
setARGB(‘参数1’) 设置字体颜色
参数1:颜色值
//设置单元格C2字体的颜色为#6F00D2
$sheet->getStyle('C2')->getFont()->getColor()->setRGB('#6F00D2');
//设置单元格C3字体的颜色为8F006D
$sheet->getStyle('C3')->getFont()->getColor()->setARGB('8F006D');
//也可以使用插件自带的颜色设置
$sheet->getStyle('C3')->getFont()->getColor()->setARGB(Color::COLOR_YELLOW);
getNumberFormat() 获取格式
setFormatCode(NumberFormat::参数1) 设置格式
参数1:各种不同的表格数字格式,详见方法中的类
//设置F1单元格的日期格式为yyyy-mm-dd
$sheet->setCellValue('F1','2020-10-14');
$sheet->getStyle('F1')->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_YYYYMMDD2);
setWrapText(参数1) 设置文本里的\n符合为:换行
参数1:true
//设置单元格中的内容换行
$sheet->setCellValue('F1',"家庭住址\n详细地址");
$sheet->getStyle('F1')->getAlignment()->setWrapText(true);
getHyperlink()获取单元格链接
setUrl(‘参数1’)设置单元格链接
参数1:需要添加的链接
//设置单元格链接
$sheet->setCellValue('F1','https://www.baidu.com/');
$sheet->getCell('F1')->getHyperlink()->setUrl('https://www.baidu.com/');
列宽
getColumnDimension(‘参数1’)获取整列
setWidth(参数1)
参数1:像素值
getDefaultColumnDimension()获取默认列宽
//将A列宽度设置为30
$sheet->getColumnDimension('A')->setWidth(30);
//如果需要自动计算列宽
$sheet->getColumnDimension('B')->setAutoSize(true);
//设置默认列宽为12
$sheet->getDefaultColumnDimension()->setWidth(12);
行高
getRowDimension(‘参数1’)
参数1:行数
setRowHeight(参数1)
参数1:像素值
//设置第2行行高为100
$sheet->getRowDimension('2')->setRowHeight(100);
//设置默认行高
$sheet->getDefaultRowDimension()->setRowHeight(15);
applyFromArray(参数1)批量设置单元格样式
参数1:单元格样式数组
//文字对齐
$styleArray = [
'alignment' => [
//'horizontal' => Alignment::HORIZONTAL_CENTER,//水平居中
//'vertical' => Alignment::VERTICAL_CENTER,//垂直居中
'horizontal' => 'center',//水平居中
'vertical' => 'center',//垂直居中
],
];
$sheet->getStyle('B2')->applyFromArray($styleArray);
合并单元格
mergeCells(‘参数1:参数2’)将指定位置的单元格合并起来
参数1:左上角位置
参数2:右下角位置
//将A4到B5合并为一个单元格。
$sheet->mergeCells('A4:B5');
拆分单元格
unmergeCells(‘参数1:参数2’)将指定位置的单元格拆分起来
参数1:左上角位置
参数2:右下角位置
//合并单元格
//将A4到B5合并为一个单元格。
$sheet->mergeCells('A4:B5');
//拆分单元格
//将合并后的单元格拆分。
$sheet->unmergeCells('A4:B5');
//单元格加边框
//将B2至B3的区域添加红色边框。
$styleArray = [
'borders' => [
'outline' => [
'borderStyle' => Border::BORDER_THICK,
'color' => ['argb' => 'FFFF0000'],
],
],
];
$sheet->getStyle('B2:B3')->applyFromArray($styleArray);
fromArray(参数1,参数2,参数3) 从数组中的值填充工作表
参数1:数据(数组)
参数2:去除某个值
参数3:从哪个位置开始
//定义excel之中的内容
$list_data = [
[
'id'=>1,
'nickname'=>'xiaowang',
'name'=>'小王',
'phone'=>12345678900,
'mail'=>'[email protected]'
],
[
'id'=>2,
'nickname'=>'xiaoli',
'name'=>'小李',
'phone'=>12345678900,
'mail'=>'[email protected]'
]
];
//从A2行开始填充数据
$sheet->fromArray($list_data, '', 'A2');
// $i = 2;//excel表格从第2行开始填入数据
// foreach ($list_data as $k => $v) {
// $sheet->setCellValueByColumnAndRow(1,$i,$v['id']);
// $sheet->setCellValueByColumnAndRow(2,$i,$v['nickname']);
// $sheet->setCellValueByColumnAndRow(3,$i,$v['name']);
// $sheet->setCellValueByColumnAndRow(4,$i,$v['phone']);
// $sheet->setCellValueByColumnAndRow(5,$i,$v['mail']);
//
// $i++;//$i从2累加
// }
$writer = IOFactory ::createWriter($spreadsheet, 'Xlsx');
$writer = IOFactory ::createWriter($spreadsheet, 'Xls');
/**
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
*/
public function importExcel()
{
//IOFactory来判断获取的文件格式
$reader = IOFactory ::createReader('Xlsx');
//当只要读取数据,不要格式时,实例读取器中 readDataOnly 属性
$reader -> setReadDataOnly(true);
$spreadsheet = $reader -> load('C:\Users\admin\Desktop\demo.xlsx');
$worksheet = $spreadsheet -> getActiveSheet();
//总行数
$row = $worksheet -> getHighestRow();
//总列数
// $column = $worksheet -> getHighestColumn();
$insert_data = $temp = [];
for ($rowIndex = 2; $rowIndex <= $row; $rowIndex++) {
//getCellByColumnAndRow中的第一参数为列的A,B,C,用1,2,3代替,第二参数为行号
$temp['num'] = $worksheet -> getCellByColumnAndRow(1, $rowIndex) -> getValue();
$temp['name'] = $worksheet -> getCellByColumnAndRow(2, $rowIndex) -> getValue();
$temp['code'] = $worksheet -> getCellByColumnAndRow(3, $rowIndex) -> getValue();
$temp['page'] = $worksheet -> getCellByColumnAndRow(4, $rowIndex) -> getValue();
$temp['type'] = $worksheet -> getCellByColumnAndRow(5, $rowIndex) -> getValue();
$temp['province'] = $worksheet -> getCellByColumnAndRow(6, $rowIndex) -> getValue();
$temp['city'] = $worksheet -> getCellByColumnAndRow(7, $rowIndex) -> getValue();
$temp['town'] = $worksheet -> getCellByColumnAndRow(8, $rowIndex) -> getValue();
$temp['class'] = $worksheet -> getCellByColumnAndRow(9, $rowIndex) -> getValue();
$temp['design'] = $worksheet -> getCellByColumnAndRow(10, $rowIndex) -> getValue();
$temp['complete_time'] = $worksheet -> getCellByColumnAndRow(11, $rowIndex) -> getValue();
$temp['remark'] = $worksheet -> getCellByColumnAndRow(12, $rowIndex) -> getValue();
$insert_data[] = $temp;
}
//生成的$insert_data可以导入数据库中
}
使用 PhpSpreadsheet 操作 excel 确实方便了很多,还有很多的其他的功能属性有待后续的学习。