在之前的文章中我们说了万级以上数据的导出及读取,
这里我们来说一下正常情况下,
使用phpOffice中的phpspreadsheet对Excel文件的导出及读取。
composer require phpoffice/phpspreadsheet
从数据库查处二维数组,键值对方式,以及设置每行对应的标题
<?php
/**
* @Author: [FENG] <1161634940@qq.com>
* @Date: 2020-04-06 20:49:34
* @Last Modified by: [FENG] <1161634940@qq.com>
* @Last Modified time: 2020-04-07T12:53:31+08:00
*/
include_once './vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
class Ceshi
{
public static function export()
{
$data = [
[ 'id'=>1, 'name'=>'张三', 'sex'=>'男', 'age'=>20, 'tel'=>1111, 'ceshi'=>'测试' ],
[ 'id'=>2, 'name'=>'李四', 'sex'=>'女', 'age'=>18, 'tel'=>2222, 'ceshi'=>'测试' ],
[ 'id'=>3, 'name'=>'王五', 'sex'=>'女', 'age'=>25, 'tel'=>3333, 'ceshi'=>'测试' ],
[ 'id'=>4, 'name'=>'赵六', 'sex'=>'男', 'age'=>22, 'tel'=>4444, 'ceshi'=>'测试' ],
];
// $fieldArr = ['ID'=>'id', '姓名'=>'name', '性别'=>'sex', '年龄'=>'age', '电话'=>'tel', '测试'=>'ceshi']; // 声明对应字段关系
$newExcel = new Spreadsheet(); //创建一个新的excel文档
$objSheet = $newExcel->getActiveSheet(); //获取当前操作sheet的对象
$objSheet->setTitle('测试表'); //设置当前sheet的标题
$lines = 1;
$fieldArr = [ 'id' => 'ID', 'name' => '姓名', 'sex' => '性别', 'age' => '年龄', 'tel' => '电话', 'ceshi' => '测试' ]; // 声明对应字段关系
$value_field = $fieldArr ? array_values($fieldArr) : array_keys($data[0]);
foreach ($value_field as $k => $v) {
$letter = num_letter($k+1);
$newExcel->getActiveSheet()->getColumnDimension($letter)->setAutoSize(true); // 简单设置列宽
$objSheet = $objSheet->setCellValue($letter . $lines, $v); // 设置标题
}
// 第二行起,每一行的值,setCellValueExplicit是用来导出文本格式的。
// $objSheet->setCellValueExplicit('A1', '超长数字', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); // 可以用来导出数字不变格式(设置单元格格式为纯文本)
$key_field = $fieldArr ? array_keys($fieldArr) : array_keys($data[0]);
foreach ($data as $k => $v) { // 数据循环处理
$lines ++;
// $newExcel->getActiveSheet()->mergeCells('A19:A22'); // 数组合并
foreach ($key_field as $m => $n) {
$letter = num_letter($m+1);
$objSheet = $objSheet->setCellValue($letter . $lines, $v[$n]);
}
}
// downloadExcel($newExcel, '测试表', 'Xlsx', './public'); // 保存到本地
downloadExcel($newExcel, '测试表', 'Xlsx'); //生成文件直接下载
}
}
// 公共文件,十进制转二十六进制(基数为A-Z)
function num_letter($num) {
$num = intval($num);
if ($num <= 0)
return false;
$letterArr = array('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');
$letter = '';
do {
$key = ($num - 1) % 26;
$letter = $letterArr[$key] . $letter;
$num = floor(($num - $key) / 26);
} while ($num > 0);
return $letter;
}
// 公共文件,用来传入xls并下载
function downloadExcel($newExcel, $filename, $format, $savePath = false)
{
if(!$savePath){ //网页下载
// $format只能为 Xlsx 或 Xls
if ($format == 'Xlsx') {
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
} elseif ($format == 'Xls') {
header('Content-Type: application/vnd.ms-excel');
}
//
header("Content-Disposition: attachment;filename=" . $filename . date('Y-m-d') . '.' . strtolower($format));
header('Cache-Control: max-age=0');
$objWriter = IOFactory::createWriter($newExcel, $format);
$objWriter->save('php://output');
} else {
ob_clean();
ob_start();
$objWriter = IOFactory::createWriter($newExcel, $format);
$savePath = './' . trim(ltrim($savePath, '.'), '/') . '/' . $filename . date('Y-m-d') . '.' . strtolower($format);
$objWriter->save($savePath);
/* 释放内存 */
$newExcel->disconnectWorksheets();
unset($newExcel);
ob_end_flush();
}
}
Ceshi::export(); // 数据文件的导出到ececl
整合 CSV、Xls及Xlsx文件的读取,默认首行为标题,以及设置标题对应的键名
<?php
/**
* @Author: [FENG] <1161634940@qq.com>
* @Date: 2020-04-06 20:49:34
* @Last Modified by: [FENG] <1161634940@qq.com>
* @Last Modified time: 2020-04-07T13:22:39+08:00
*/
include_once './vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
class Ceshi
{
// 导入
public static function import()
{
$filePath = './ceshi.xlsx';
//实例化reader
$ext = pathinfo($filePath, PATHINFO_EXTENSION);
if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
die('当前文件类型不支持');
}
if ($ext === 'csv') {
$file = fopen($filePath, 'r');
$filePath = tempnam(sys_get_temp_dir(), 'import_csv');
$fp = fopen($filePath, "w");
$n = 0;
while ($line = fgets($file)) {
$line = rtrim($line, "\n\r\0");
$encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
if ($encoding != 'utf-8') {
$line = mb_convert_encoding($line, 'utf-8', $encoding);
}
if ($n == 0 || preg_match('/^".*"$/', $line)) {
fwrite($fp, $line . "\n");
} else {
fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
}
$n++;
}
fclose($file) || fclose($fp);
$reader = new Csv();
} elseif ($ext === 'xls') {
$reader = new Xls();
} else {
$reader = new Xlsx();
}
// 声明对应字段关系
$fieldArr = ['ID'=>'id', '姓名'=>'name', '性别'=>'sex', '年龄'=>'age', '电话'=>'tel', '测试'=>'ceshi'];
//加载文件
$insert = [];
try {
if (!$PHPExcel = $reader->load($filePath)) {
die('获取数据失败');
}
$currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
$allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
$allRow = $currentSheet->getHighestRow(); //取得一共有多少行
$maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
$fields = [];
for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
is_object($val) && $val= $val->__toString();
$fields[] = $val;
}
}
for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
$values = [];
for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
is_object($val) && $val= $val->__toString();
$values[] = is_null($val) ? '' : $val;
}
$row = [];
$temp = array_combine($fields, $values);
foreach ($temp as $k => $v) {
if (isset($fieldArr[$k]) && $k !== '') {
$row[$fieldArr[$k]] = $v;
}
}
if ($row) {
$insert[] = $row;
}
}
} catch (Exception $e) {
die($e->getMessage());
}
// dump($insert); 二维数据,键值对
}
}
Ceshi::import(); // 读取xlsx文件数据
关于PhpSpreadsheet的更多使用方法可参考:http://blog.shzhaoqi.com/article/191
本文为冯奎原创文章,转载无需和我联系,但请注明来自冯奎博客fengkui.net
最新评论