PHPExcel类是php一个excel表格处理插件,最近由于工作需要用到了这个插件,完成了一个excel导入导入的功能。现在将主要逻辑整理一下和大家分享,有需要的可以参考一下。
下面的事例只是完成了一个excel的上传下载的基本功能,还有一些设置表格样式、合并单元格等操作没有体现在这里,大家可以参考PHPExcel的手册,事例后面是我摘出来的PHPExcel的常见的一些操作,供大家参考:
将PHPExcel提供的API根据需要封装成一个供上传和下载使用的类,其实就是两个函数,一个用于上传一个用于下载,这里我就直接将代码贴出来了。
<?php
/* PHPExcel库可以从https://phpexcel.codeplex.com/下载,例子中用的版本是1.8.0 */
require_once dirname(__FILE__) . '/PHPExcel/PHPExcel.class.php';
class parseExcel
{
function __construct()
{
/* do nothing */
}
/**
* 将excel文件转化为一个二维数组(这里还没有考虑excel中的页签)
* 将excel的内容全部读取回去
* 第一行为标题行,不在返回的数据里面
*
* @param $file : excel文件名
* @param $filed: 要读取的列
*
* @access public
*
* @return 对象的array,每行数据为一个对象,array的大小为行数(不包含标题)
* 每一行是一个对象
*/
public function excel2array($file, $fields = array())
{
/* 如果文件名为空或者要读取的列为空,则返回一个空的数组 */
if ($file == "" || count($fields) == 0)
{
return array();
}
/* 创建reader */
$phpReader = new PHPExcel_Reader_Excel2007();
if(!$phpReader->canRead($file))
{
/* 如果PHPExcel_Reader_Excel2007无法读取excel,则销毁刚才创建的对象,使用PHPExcel_Reader_Excel5来读 */
unset($phpReader);
$phpReader = new PHPExcel_Reader_Excel5();
}
if(!$phpReader->canRead($file))
{
/* 文件无法读取,返回空的数组 */
return array();
}
$phpExcel = $phpReader->load($file);
/* 目前的实现只读取第一个工作表 */
$currentSheet = $phpExcel->getSheet(0);
/* 拿到工作表的行数和列数 */
$allRows = $currentSheet->getHighestRow();
$allColumns = $currentSheet->getHighestColumn();
$allColumns++;
$currentColumn = 'A';
/* 解析第一个行,记录$fields中要读取的行 */
while($currentColumn != $allColumns)
{
$title = $currentSheet->getCell($currentColumn . '1')->getValue();
$field = array_search($title, $fields);
$columnKey[$currentColumn] = $field ? $field : '';
$currentColumn++;
}
$dataList = array();
/* 跳过标题行(第一行)开始读取数据 */
for($currentRow = 2; $currentRow <= $allRows; $currentRow++)
{
$currentColumn = 'A';
$data = new stdclass();
$ignore = true; /* 对于空行,需要忽略,这里通过记录一个标记处理 */
while($currentColumn != $allColumns)
{
$cellValue = trim($currentSheet->getCell($currentColumn . $currentRow)->getValue());
if(empty($columnKey[$currentColumn]))
{
$currentColumn++;
continue;
}
$field = $columnKey[$currentColumn];
$currentColumn++;
if (empty($cellValue))
{
$data->$field = '';
}
else
{
$data->$field = $cellValue;
$ignore = false;
}
}
if ($ignore == true)
{
continue;
}
/* 设置没有从excel中读到的数据 */
foreach(array_keys($fields) as $key)
{
if(!isset($data->$key))
{
$data->$key = '';
}
}
$dataList[] = $data;
}
return $dataList;
}
public function setExcelFiled($count)
{
$letter = 'A';
for($i = 1; $i <= $count; $i++) $letter++;
return $letter;
}
/**
* 将一个对象写入到文件
*
* @param $data : 要写入到excel文件的数据
* kind :页签名称
* fields : 标题行,输入的文件要包含的字段
* rows :对象数组,每一个数据,这些数据会通过fields过滤,只保留fields的内容(和excel2array的返回值格式一致)
* fileName : 要保存的文件名
* @param $fileType : 输入文件类型,包括xls和xlsx两种类型
* @param $savePath : 文件路径
*
* @access public
*
* @return 对象的array,每行数据为一个对象,array的大小为行数(不包含标题)
* 如果输入为空,则可能是由于参数不对或者excel文件无法读取
*/
public function export2excel($data, $savePath = '')
{
$this->phpExcel = new phpExcel();
$this->rawExcelData = $data;
$this->fields = $this->rawExcelData->fields;
$this->rows = $this->rawExcelData->rows;
$this->fieldsKey = array_keys($this->fields);
if(!$this->rawExcelData->fileName) $this->rawExcelData->fileName = $this->rawExcelData->kind;
$this->excelKey = array();
for($i = 0; $i < count($this->fieldsKey); $i++) $this->excelKey[$this->fieldsKey[$i]] = $this->setExcelFiled($i);
/* Set file base property */
$excelProps = $this->phpExcel->getProperties();
$excelProps->setCreator('ricky');
$excelProps->setLastModifiedBy('ricky');
$excelProps->setTitle('Office XLS Document');
$excelProps->setSubject('Office XLS Document');
$excelProps->setDescription('Document generated by PHPExcel.');
$excelProps->setKeywords('office excel PHPExcel');
$excelProps->setCategory('Result file');
/* 处理第一个页签 */
$this->phpExcel->setActiveSheetIndex(0);
$sheetTitle = $this->rawExcelData->kind;
$excelSheet = $this->phpExcel->getActiveSheet();
/* 设置页签名称 */
if($sheetTitle) $excelSheet->setTitle($sheetTitle);
foreach($this->fields as $key => $field) $excelSheet->setCellValueExplicit($this->excelKey[$key] . '1', $field, PHPExcel_Cell_DataType::TYPE_STRING);
$i = 1;
foreach($this->rows as $num => $row)
{
$i++;
foreach($row as $key => $value)
{
if(isset($this->excelKey[$key]))
{
$excelSheet->setCellValueExplicit($this->excelKey[$key] . $i, $value, PHPExcel_Cell_DataType::TYPE_STRING);
}
}
}
/* urlencode the filename for ie. */
$fileName = $this->rawExcelData->fileName;
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== false) $fileName = urlencode($fileName);
$excelWriter = PHPExcel_IOFactory::createWriter($this->phpExcel, 'Excel5');
$excelWriter->setPreCalculateFormulas(false);
if($savePath == '')
{
header('Content-Type: application/vnd.ms-excel');
header("Content-Disposition: attachment;filename=\"{$fileName}.xls\"");
header('Cache-Control: max-age=0');
$excelWriter->save('php://output');
}
else
{
$excelWriter->save($savePath);
}
}
}
测试代码:
测试代码中完成了excel文件的上传和下载:从本客户端择一个excel文件导入,然后完成解析后,再下载到客户端。
HTML代码很简单,没有css、js,只有一个file空间和一个提交按钮。如下所示:
<!doctype html>
<html>
<body>
<form action="excel.php" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>
<?php
function output($var)
{
echo "<xmp class='a-left'>";
print_r($var);
echo "</xmp>";
}
include_once 'parseexcel.class.php';
/* 处理上传的文件 */
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
exit;
}
move_uploaded_file($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]);
/**
* excel格式:
*
* 姓名 | 性别
* -----------------
* ricky | 男
* xxxxx | xxx
*/
/* 定义要读取的列,数组的值需要和excel的每一行的标题一致或子集 */
$fileds = array(
'name' => '姓名',
'sex' => '性别',
);
$parse = new parseExcel();
/* 从上传的文件中解析出数据 */
$rows = $parse->excel2array($_FILES["file"]["name"], $fileds);
/* 注意: 测试导入的时候,打开这个注释行,测试下载的时候需要关闭该注释行 */
//output($rows);exit;
/* 将数据原封不动在写入一个新的文件,供用户下载 */
$data = new stdClass();
/* excel的文件名 */
$data->fileName = 'ceshi';
/* 页签的名字 */
$data->kind = 'ceshi';
/* excel的标题 */
$data->fields = $fileds;
/* 要写入的数据 */
$data->rows = $rows;
$parse->export2excel($data);
创建excel
$objPHPExcel = new PHPExcel();
创建一个worksheet
$objPHPExcel->createSheet();
$objWriter = PHPExcel_IOFactory::createWriter($objExcel, 'Excel5');
$objWriter-save('php://output');
保存excel(2007)
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
非2007格式:$objWriter = new PHPExcel_Writer_Excel5($objPHPExcel);
$objWriter->save("xxx.xlsx");
直接输出到浏览器供下载
header('Content-Type: application/vnd.ms-excel');
header("Content-Disposition: attachment;filename=\"{$fileName}.xls\"");
header('Cache-Control: max-age=0');
$excelWriter->save('php://output');
设置excel的属性:
创建人
$objPHPExcel->getProperties()->setCreator("Maarten Balliauw");
最后修改人
$objPHPExcel->getProperties()->setLastModifiedBy("Maarten Balliauw");
标题
$objPHPExcel->getProperties()->setTitle("Office 2007 XLSX Test Document");
题目
$objPHPExcel->getProperties()->setSubject("Office 2007 XLSX Test Document");
描述
$objPHPExcel->getProperties()->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.");
关键字
$objPHPExcel->getProperties()->setKeywords("office 2007 openxml php");
种类
$objPHPExcel->getProperties()->setCategory("Test result file");
设置当前的sheet
$objPHPExcel->setActiveSheetIndex(0);
设置sheet的name
$objPHPExcel->getActiveSheet()->setTitle('Simple');
设置单元格的值
$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String');
$objPHPExcel->getActiveSheet()->setCellValue('A1', 12);
$objPHPExcel->getActiveSheet()->setCellValue('A1', true);
$objPHPExcel->getActiveSheet()->setCellValue('A1', '=SUM(C2:C4)');
$objPHPExcel->getActiveSheet()->setCellValue('A1', '=MIN(B2:C5)');
合并单元格
$objPHPExcel->getActiveSheet()->mergeCells('A18:E22');
分离单元格
$objPHPExcel->getActiveSheet()->unmergeCells('A28:B28');
设置宽度
$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12);
设置字体
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setName('Candara');
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setSize(20);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);
设置对齐方式
$objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY);
$objPHPExcel->getActiveSheet()->getStyle('C1')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
设置单元格border
$objPHPExcel->getActiveSheet()->getStyle('D1')->getBorders()->getTop()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
设置border的color
$objPHPExcel->getActiveSheet()->getStyle('E1')->getBorders()->getLeft()->getColor()->setARGB('FF993300');;
$objPHPExcel->getActiveSheet()->getStyle('E1')->getBorders()->getRight()->getColor()->setARGB('FF993300');
$objPHPExcel->getActiveSheet()->getStyle('E1')->getBorders()->getTop()->getColor()->setARGB('FF993300');
$objPHPExcel->getActiveSheet()->getStyle('E1')->getBorders()->getBottom()->getColor()->setARGB('FF993300');
设置填充颜色
$objPHPExcel->getActiveSheet()->getStyle('F1')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
$objPHPExcel->getActiveSheet()->getStyle('F1')->getFill()->getStartColor()->setARGB('FF808080');
加载图片
$objDrawing = new PHPExcel_Worksheet_Drawing();
$objDrawing->setName('Logo');
$objDrawing->setDescription('Logo');
$objDrawing->setPath('./images/officelogo.jpg');
$objDrawing->setHeight(36);
$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());
$objDrawing = new PHPExcel_Worksheet_Drawing();
来源:oschina
链接:https://my.oschina.net/u/2393241/blog/468724