下载phpoffice/phpspreadsheet
composer require phpoffice/phpspreadsheet 1.8.2
这个版本兼容PHP5和PHP7
1、新建Excel.php文件
canRead($file)) {
/** @var Xls $objRead */
$objRead = IOFactory::createReader('Xls');
if (!$objRead->canRead($file)) {
$msg['code'] = 0;
$msg['tips'] = '只支持导入Excel文件!';
return $msg;
//throw new \Exception('只支持导入Excel文件!');
}
}
/* 如果不需要获取特殊操作,则只读内容,可以大幅度提升读取Excel效率 */
empty($options) && $objRead->setReadDataOnly(true);
/* 建立excel对象 */
$obj = $objRead->load($file);
/* 获取指定的sheet表 */
$currSheet = $obj->getSheet($sheet);
if (isset($options['mergeCells'])) {
/* 读取合并行列 */
$options['mergeCells'] = $currSheet->getMergeCells();
}
if (0 == $columnCnt) {
/* 取得最大的列号 */
$columnH = $currSheet->getHighestColumn();
/* 兼容原逻辑,循环时使用的是小于等于 */
$columnCnt = Coordinate::columnIndexFromString($columnH);
}
/* 获取总行数 */
$rowCnt = $currSheet->getHighestRow();
$data = [];
/* 读取内容 */
for ($_row = 1; $_row <= $rowCnt; $_row++) {
$isNull = true;
for ($_column = 1; $_column <= $columnCnt; $_column++) {
$cellName = Coordinate::stringFromColumnIndex($_column);
$cellId = $cellName . $_row;
$cell = $currSheet->getCell($cellId);
if (isset($options['format'])) {
/* 获取格式 */
$format = $cell->getStyle()->getNumberFormat()->getFormatCode();
/* 记录格式 */
$options['format'][$_row][$cellName] = $format;
}
if (isset($options['formula'])) {
/* 获取公式,公式均为=号开头数据 */
$formula = $currSheet->getCell($cellId)->getValue();
if (0 === strpos($formula, '=')) {
$options['formula'][$cellName . $_row] = $formula;
}
}
if (isset($format) && 'm/d/yyyy' == $format) {
/* 日期格式翻转处理 */
$cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');
}
$data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue());
if (!empty($data[$_row][$cellName])) {
$isNull = false;
}
}
/* 判断是否整行数据为空,是的话删除该行数据 */
if ($isNull) {
unset($data[$_row]);
}
}
return $data;
} catch (\Exception $e) {
throw $e;
}
}
/**
* Excel导出
*
* @param array $datas 导出数据,格式[['name' => 'alibaba','age' => 18]]
* @param string $fileName 导出文件名称
* @param array $options 操作选项,例如:
* bool print 设置打印格式
* string freezePane 锁定行数,例如表头为第一行,则锁定表头输入A2
* array setARGB 设置背景色,例如['A1', 'C1']
* array setWidth 设置宽度,例如['A' => 30, 'C' => 20]
* bool setBorder 设置单元格边框
* array mergeCells 设置合并单元格,例如['A1:J1' => 'A1:J1']
* array formula 设置公式,例如['F2' => '=IF(D2>0,E42/D2,0)']
* array format 设置格式,整列设置,例如['A' => 'General']
* array alignCenter 设置居中样式,例如['A1', 'A2']
* array bold 设置加粗样式,例如['A1', 'A2']
* string savePath 保存路径,设置后则文件保存到服务器,不通过浏览器下载
* @param array $param 数据键名 ['0' => 'name','1' => 'age']
*/
function exportExcel($datas,$param, $fileName = '', $options = [])
{
try {
if (empty($datas)) {
return false;
}
if (empty($param)) {
return false;
}
//列名
$rows = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
set_time_limit(0);
/** @var Spreadsheet $objSpreadsheet */
$objSpreadsheet = new Spreadsheet();
//设置默认文字居左,上下居中
$styleArray = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_LEFT,
'vertical' => Alignment::VERTICAL_CENTER,
],
];
$objSpreadsheet->getDefaultStyle()->applyFromArray($styleArray);
//设置Excel Sheet
$activeSheet = $objSpreadsheet->setActiveSheetIndex(0);
//打印设置
/*if (isset($options['print']) && $options['print']) {
//设置打印为A4效果
$activeSheet->getPageSetup()->setPaperSize(PageSetup:: PAPERSIZE_A4);
//设置打印时边距
$pValue = 1 / 2.54;
$activeSheet->getPageMargins()->setTop($pValue / 2);
$activeSheet->getPageMargins()->setBottom($pValue * 2);
$activeSheet->getPageMargins()->setLeft($pValue / 2);
$activeSheet->getPageMargins()->setRight($pValue / 2);
}*/
//行数据处理
foreach ($datas as $sKey => $sItem) {
//默认文本格式
$pDataType = DataType::TYPE_STRING;
//设置单元格格式
/*if (isset($options['format']) && !empty($options['format'])) {
$colRow = Coordinate::coordinateFromString($sKey);
//存在该列格式并且有特殊格式
if (isset($options['format'][$colRow[0]]) &&
NumberFormat::FORMAT_GENERAL != $options['format'][$colRow[0]]) {
$activeSheet->getStyle($sKey)->getNumberFormat()
->setFormatCode($options['format'][$colRow[0]]);
if (false !== strpos($options['format'][$colRow[0]], '0.00') &&
is_numeric(str_replace(['¥', ','], '', $sItem))) {
//数字格式转换为数字单元格
$pDataType = DataType::TYPE_NUMERIC;
$sItem = str_replace(['¥', ','], '', $sItem);
}
} elseif (is_int($sItem)) {
$pDataType = DataType::TYPE_NUMERIC;
}
}*/
$sKey = $sKey + 1;
for ($i = 0;$i < count($param);$i++) {
$activeSheet->setCellValueExplicit($rows[$i] .$sKey, $sItem[$param[$i]], $pDataType);
}
//存在:形式的合并行列,列入A1:B2,则对应合并
/*if (false !== strstr($sKey, ":")) {
$options['mergeCells'][$sKey] = $sKey;
}*/
}
unset($datas);
//设置锁定行
/*if (isset($options['freezePane']) && !empty($options['freezePane'])) {
$activeSheet->freezePane($options['freezePane']);
unset($options['freezePane']);
}*/
//设置宽度
/*if (isset($options['setWidth']) && !empty($options['setWidth'])) {
foreach ($options['setWidth'] as $swKey => $swItem) {
$activeSheet->getColumnDimension($swKey)->setWidth($swItem);
}
unset($options['setWidth']);
}*/
//设置背景色
/*if (isset($options['setARGB']) && !empty($options['setARGB'])) {
foreach ($options['setARGB'] as $sItem) {
$activeSheet->getStyle($sItem)
->getFill()->setFillType(Fill::FILL_SOLID)
->getStartColor()->setARGB(Color::COLOR_YELLOW);
}
unset($options['setARGB']);
}*/
//设置公式
/*if (isset($options['formula']) && !empty($options['formula'])) {
foreach ($options['formula'] as $fKey => $fItem) {
$activeSheet->setCellValue($fKey, $fItem);
}
unset($options['formula']);
}*/
//合并行列处理
/*if (isset($options['mergeCells']) && !empty($options['mergeCells'])) {
$activeSheet->setMergeCells($options['mergeCells']);
unset($options['mergeCells']);
}*/
//设置居中
/*if (isset($options['alignCenter']) && !empty($options['alignCenter'])) {
$styleArray = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
];
foreach ($options['alignCenter'] as $acItem) {
$activeSheet->getStyle($acItem)->applyFromArray($styleArray);
}
unset($options['alignCenter']);
}*/
//设置加粗
/*if (isset($options['bold']) && !empty($options['bold'])) {
foreach ($options['bold'] as $bItem) {
$activeSheet->getStyle($bItem)->getFont()->setBold(true);
}
unset($options['bold']);
}*/
//设置单元格边框,整个表格设置即可,必须在数据填充后才可以获取到最大行列
/*if (isset($options['setBorder']) && $options['setBorder']) {
$border = [
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN, // 设置border样式
'color' => ['argb' => 'FF000000'], // 设置border颜色
],
],
];
$setBorder = 'A1:' . $activeSheet->getHighestColumn() . $activeSheet->getHighestRow();
$activeSheet->getStyle($setBorder)->applyFromArray($border);
unset($options['setBorder']);
}*/
$fileName = !empty($fileName) ? $fileName : (date('YmdHis') . '.xlsx');
if (!isset($options['savePath'])) {
//直接导出Excel,无需保存到本地,输出07Excel文件
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header(
"Content-Disposition:attachment;filename=" . iconv(
"utf-8", "GB2312//TRANSLIT", $fileName
)
);
header('Cache-Control: max-age=0');//禁止缓存
$savePath = 'php://output';
} else {
$savePath = $options['savePath'];
}
ob_clean();
ob_start();
$objWriter = IOFactory::createWriter($objSpreadsheet, 'Xlsx');
$objWriter->save($savePath);
//释放内存
$objSpreadsheet->disconnectWorksheets();
unset($objSpreadsheet);
ob_end_flush();
return true;
} catch (Exception $e) {
return false;
}
}
}
2.导入
//导入用户
public function importUser()
{
$excel = new Excel();
$file = request()->file('file');
//获取表单上传文件 限制大小20M
$info = $file->validate(['size' => 20971520, 'ext' => 'xlsx,xls'])->move(ROOT_PATH . 'public' . DS . 'excel');
if ($info) {
$exclePath = $info->getSaveName();
//获取文件名
$file_name = ROOT_PATH . 'public' . DS . 'excel/' . $exclePath;
//获取导入数据
$data = $excel->importExecl($file_name);
array_shift($data);
$insertData = [];
foreach ($data as $key => $datum) {
$insertData[$key]['username'] = $datum['A'];
$insertData[$key]['password'] = md5(md5($datum['B']));
$insertData[$key]['phone'] = $datum['C'];
$insertData[$key]['email'] = $datum['D'];
$insertData[$key]['create_time'] = ($datum['E'] - 25569) * 24 * 3600;
}
$success_count = $this->insertAll($insertData);
$msg['code'] = 1;
$msg['tips'] = '导入成功:' . $success_count . '条。';
return $msg;
} else {
$msg['code'] = 0;
$msg['tips'] = $file->getError();
return $msg;
}
}
3、导出
//导出用户
public function exportUser()
{
$excel = new Excel();
$param = input('post.');
$where = [];
$where['status'] = $param['status'];
$list = $this->where($where)->select()->toArray();
foreach ($list as $key => $item) {
$list[$key]['create_time'] = date('Y-m-d',$item['create_time']);
}
//设置表格标题
$title = [
'username' => '用户名',
'password' => '密码',
'phone' => '手机号',
'email' => '邮箱',
'create_time' => '注册时间',
];
//添加标题到数组头部
array_unshift($list,$title);
//根据此参数获取数据中的值,要与表格标题键名对应
$keys = ['username','password','phone','email','create_time'];
$excel->exportExcel($list,$keys,'用户' . date('Y-m-d_His') . '.xlsx');
}