<?php
use PHPExcel;
class PhpOperateExcel
{
public $excel;
public $excel_sheet;
public $file_type;
public function __construsct($optaer = 'create',$file_type ='Excel2007',$path = null)
{
if ($optaer == 'load') {
$path = iconv('UTF-8','GB2312',$path);
if (!empty($path) && file_exists($path)) {
$file_type = \PHPExcel_IOFactory::identify($path);//获取文本类型
if ($file_type) {
$excel_io = \PHPExcel_IOFactory::createReader($file_type);
$this->excel = $excel_io->load($path);
} else {
throw '请上传正确的excel文件';
}
$this->file_type = $file_type;
} else {
throw '请输入正确的文件路径';
}
} else {
$this->excel = new PHPExcel();
$this->file_type = $file_type;
}
}
/**
* @description: 在表格中插入数据
* @param xls_contents array 表数据数组 [0 => ['xu'=>'1','val1'=>'123'],1 => ['xu'=>'2','val1'=>'456']]
* @param content_column 数据插入的初始行
* @param xls_header array 表头数据数组 [['xu','序号'],['val','值1']]
* @param header_colmun 表头插入的初始行 默认为第一行
* @return:
*/
public function set_excel_header($xls_contents,$content_column,$xls_header,$header_colmun = 1)
{
$this->set_default_width_height();
foreach ($xls_header as $key => $header) {
$index = $this->int_index_conver($key,$header_colmun);
$this->set_cell_value($index,$header[1]);
}
$header_count = count($xls_header);
foreach ($xls_contents as $content) {
for ($i = 0;$i < $header_count;$i++) {
$index = $this->int_index_conver($i,$content_column);
$value = $content[$xls_header[$i][0]];
if (is_array($value)) {
if ($value['type'] == 'url') { // url
$this->set_cell_url($index, $value['url'], $value['text'] ?? $value['url']);
} elseif ($value['type'] == 'img') { // 图片
$this->set_cell_img($index, $value['path'], $value['width'], $value['height'], $value['title'] ?? '', $value['descript'] ?? '');
} elseif ($value['type'] == 'shhet') { // sheet
$this->set_cell_sheet($index, $value['value'], $value['sheet_name'], $value['cell_index']);
}
} else {
$this->set_cell_value($index, $value);
}
}
$content_column++;
}
}
/**
* @description: 设置单元格的内容
* @param index string 设置的位置
* @param index string 设置的内容
* @param cell_style string 单元格格式 默认为false
* @return:
*/
public function set_cell_value($index, $value)
{
if (is_numeric($value) && strlen($value) >= 11) { // 超长数字
$this->excel_sheet->setCellValueExplicit($index, $value, $this->get_cell_style('text'));
} else {
$this->excel_sheet->setCellValue($index, $value);
}
}
/**
* @description: 单元格内容设置为url
* @param cell_index string 设置的单元格索引 A1
* @param url_text string 设置的单元格内容
* @param url string 内容跳转的url
* @return:
*/
public function set_cell_url($cell_index, $url_text, $url)
{
$this->set_cell_value($cell_index,$url_text);
$this->excel_sheet->getCell($cell_index)->getHyperlink()->setUrl($url);
}
/**
* @description: 在单元格插入图片
* @param cel_index string 单元格的索引,图片所有的位置要设置高度,否则可能图片不显示
* @param img_path string 图片的全路径
* @param img_weight string 图片的宽度
* @param img_height string 图片的高度
* @param img_title string 图片名字,不传显示空
* @param $img_descript string 图片描述,不传显示空
* @return:
*/
public function set_cell_img($cel_index, $img_path, $img_weight, $img_height, $img_title = ' ', $img_descript = '')
{
$draw = new \PHPExcel_Worksheet_Drawing();
$draw->setName($img_title);
$draw->setDescription($img_descript);
$draw->setPath($img_path);
$draw->setWidth($img_weight);
$draw->setHeight($img_height);
$draw->setCoordinates($cel_index);
$draw->setWorksheet($this->excel_sheet);
}
/**
* @description: 单元格内容跳转到另一个sheet
* @param cell_index string 设置的单元格索引 A1
* @param sheet_text string 设置的单元格内容
* @param sheet_name string 内容跳转的sheet的名字
* @param sheet_cell_index string 内容跳转的sheet的的单元格位置
* @return:
*/
public function set_cell_sheet($cell_index, $sheet_text, $sheet_name, $sheet_cell_index)
{
$sheet = "sheet://'$sheet_name'!$sheet_cell_index";
$this->set_cell_url($cell_index, $sheet_text, $sheet);
}
/**
* @description: 合并指定单元格
* @param start string 起始单元格 A1
* @param end string 结束单元格 G1
* @return:
*/
public function merge_cell($start, $end)
{
$this->excel_sheet->mergeCells($start.':'.$end);
}
/**
* @description: 拆分指定单元格
* @param start string 起始单元格 A1
* @param end string 结束单元格 G1
* @return:
*/
public function unmerge_cell($start, $end)
{
$this->excel_sheet->unmergeCells($start.':'.$end);
}
/**
* @description: 判断指定单元格是否为合并的单元格
* @param cell_index string 单元格 A1
* @return:
*/
public function merge_cell_judge($cell_index)
{
$cell = $this->excel_sheet->getCell($cell_index);
$merges = $this->excel_sheet->getMergeCells();
foreach ($merges as $cells) {
if ($cell->isInRange($cells)) {
return true;
}
}
return false;
}
/**
* @description: 设置表格默认宽高
* @param int $column_width 列宽
* @param int $row_height 行高 默认为-1 自适应高度
* @return {*}
*/
public function set_default_width_height($column_width = 10, $row_height = -1)
{
$this->excel_sheet->getDefaultRowDimension()->setRowHeight($row_height);
$this->excel_sheet->getDefaultColumnDimension()->setWidth($column_width);
}
/**
* @description: 设置指定列单元格宽度或高度
* @param column_index string 指定列 A
* @param width int 宽度
* @return:
*/
public function set_column_width($column_index, $width)
{
$this->excel_sheet->getColumnDimension($column_index)->setWidth($width);
}
/**
* @description: 设置行高
* @param int $row 行数 从1开始
* @param int $width
* @return {*}
*/
public function set_row_height($row, $width)
{
$this->excel_sheet->getRowDimension($row)->setRowHeight($width);
}
/**
* @description: 设置单元格内容自动换行
* @param start string 开始的位置 A1
* @param end string 结束的位置 Z100
* @return:
*/
public function set_word_wrap($start,$end)
{
$this->excel_sheet->getStyle($start.':'.$end)->getAlignment()->setWrapText(true);
}
/**
* @description: 设置单元格内容垂直样式
* @param start string 开始的位置 A1
* @param end string 结束的位置 Z100
* @param vertical_style string 垂直样式 center:垂直居中
* @return:
*/
public function set_vertical_style($start, $end, $vertical_style)
{
$style = $this->get_cell_style('vertical_'.$vertical_style);
$this->excel_sheet->getstyle($start.":".$end)->getAlignment()->setVertical($style);
}
/**
* @description: 设置单元格内容水平样式
* @param start string 开始的位置 A1
* @param end string 结束的位置 Z100
* @param horizontal_style string 水平样式 center:水平居中 top:水平居上
* @return:
*/
public function set_horizontal_style($start, $end, $horizontal_style)
{
$style = $this->get_cell_style('horizontal_'.$horizontal_style);
$this->excel_sheet->getstyle($start.":".$end)->getAlignment()->setHorizontal($style);
}
/**
* @description: 获取单元格格式
* @param type string 要获取的格式类型
* @return:
*/
public function get_cell_style($type)
{
$styles = [
'text' => \PHPExcel_Cell_DataType::TYPE_STRING, //单元格设置为文本格式
'vertical_center' => \PHPExcel_Style_Alignment::VERTICAL_CENTER, //单元格内容垂直居中
'horizontal_center' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER, //单元格内容水平居中
'vertical_top' => \PHPExcel_Style_Alignment::VERTICAL_TOP, //单元格内容垂直居上
];
return $styles[$type];
}
/**
* @description: 设置单元格背景颜色
* @param start string 起始单元格 A1
* @param end string 结束单元格 G2
* @param color string ARGB颜色 A代表透明度 FF表示不透明(FF808080)00表示透明
* @return:
*/
public function set_cell_back_color($start,$end,$color)
{
$cell_index = $start . ':' . $end;
$this->excel_sheet->getStyle($cell_index)->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
$this->excel_sheet->getStyle($cell_index)->getFill()->getStartColor()->setARGB($color);
}
/**
* @description: 设置单元格的边框
* @param start string 开始的位置 A1
* @param end string 结束的位置 Z100
* @return:
*/
public function set_border_style($start, $end)
{
$style_array = [
'borders' => [
'allborders' => [
'style' => \PHPExcel_Style_Border::BORDER_THIN
]
]
];
$this->excel_sheet->getStyle($start.':'.$end)->applyFromArray($style_array);
}
/**
* @description: 设置字体
* @param string $cell_index 单元格索引 A1
* @param string $font 字体
* @param int $size 字体大小
* @param string $color 字体颜色 ARGB颜色 A代表透明度 FF表示不透明(FF808080)00表示透明;\PHPExcel_Style_Color类中有颜色常量
* @param bool $bold 字体加粗
* @param bool $unline 字体下划线
* @return {*}
*/
public function set_font($cell_index, $font = '', $size = '', $color = '', $bold = false, $unline = false)
{
$sheet_font = $this->excel_sheet->getStyle($cell_index)->getFont();
if ($font) {
$sheet_font->setName($font);
}
if ($size) {
$sheet_font->setSize($size);
}
if ($color) {
$sheet_font->getColor()->setARGB(\PHPExcel_Style_Color::COLOR_WHITE);
}
if ($bold) {
$sheet_font->setBold(true);
}
if ($unline) {
$sheet_font->setUnderline(\PHPExcel_Style_Font::UNDERLINE_SINGLE);
}
}
/**
* @description: 设置sheet 获取sheet对象
* @param index int sheet的索引 默认为0 第一个sheet
* @return:
*/
public function set_sheet_index($index = 0)
{
try {
$this->excel->setActiveSheetIndex($index);
} catch (\Exception $e) {
$this->excel->createSheet($index); //创建sheet
$this->excel->setActiveSheetIndex($index);
}
$this->excel_sheet = $this->excel->getActiveSheet();
}
/**
* @description: 设置/获取sheet的名字
* @param sheet_name string sheet的名字
* @return:
*/
public function sheet_name($sheet_name = '')
{
if ($sheet_name) {
$this->excel_sheet->setTitle($sheet_name);
} else {
return $this->excel_sheet->getTitle();
}
}
/**
* @description: 获取sheet数
* @return:
*/
public function get_sheet_count()
{
return $this->excel->getSheetCount();
}
/**
* @description: 设置sheet的颜色
* @param color string sheet的颜色, ARGB颜色 A代表透明度 FF表示不透明(FF808080)00表示透明;\PHPExcel_Style_Color类中有颜色常量
* @return:
*/
public function set_sheet_color($color)
{
$this->excel_sheet->getTabColor()->setARGB($color);
}
/**
* @description: 复制sheet到另一个excel对象;
* 复制sheet时,如果被复制的excel对象还需要使用,则需要clone原excel对象和sheet对象,
* 否则复制后,原对象会被修改,导致原excel对象发生变化,之后对于原对象的数据获取可能发生错误
* @param path string 文件的路径
* @param sheet_title string 复制后的sheet的名字,同一个excel对象中sheet名称重复会报错
* @param index int 要复制到的索引位置
* @return:
*/
public function copy_sheet_to_other($path,$sheet_title,$index = 0)
{
/* 克隆sheet对象
$excel1 = clone $this->excel;
$sheet1 = clone $excel1->getSheet($sheet_index);*/
$sheet = (new self)->sheet;
$sheet->setTitle($sheet_title);
if ($index) {
$this->excel->addExternalSheet($sheet,$index);
} else {
$this->excel->addExternalSheet($sheet);
}
}
/**
* @description: 删除sheet
* @param index int sheet索引,默认0
* @return:
*/
public function del_sheet($index = 0)
{
$this->excel->removeSheetByIndex($index);
}
/**
* @description: 行/列的添加与删除
* @param int $start 起始行/列
* @param int $number 行/列数
* @param int $type 1、行/列前添加 2、行/列后删除
* @param int $row_column 1、行 2、列
* @return {*}
*/
public function insert_del_row_column($start, $number, $type, $row_column)
{
if ($type == 1) {
$func = $row_column == 1 ? 'insertNewRowBefore' : 'insertNewColumnBefore';
} else if ($type == 2) {
$func = $row_column == 1 ? 'removeRow' : 'removeColumn';
}
$this->excel_sheet->$func($start, $number);
}
/**
* @description: 获取表格列数
* @return: string A
*/
public function get_height_column()
{
return $this->excel_sheet->getHighestColumn();
}
/**
* @description: 获取表格行数
* @return:
*/
public function get_height_row()
{
return $this->excel_sheet->getHighestRow();
}
/**
* @description: 数字转列索引(字母),获取单元格位置
* @param key excel的表头位置 第一个是0(A)
* @param column 要获取的excel的行数,默认为第一行
* @return:
*/
public function int_index_conver($key, $column = 1)
{
return \PHPExcel_Cell::stringFromColumnIndex($key) . $column;
}
/**
* @description: 将列索引转换为数字
* @param str string 列 A
* @return:
*/
public function index_conver_int($str)
{
return \PHPExcel_Cell::columnIndexFromString($str);
}
/**
* @description: 设置单元格显示与隐藏
* @param column_index string 列索引 A
* @param show bool false:隐藏 true:显示
* @return:
*/
public function column_visible_show($column_index,$show = false)
{
if ($show == false) {
$this->excel_sheet->getColumnDimension($column_index)->setVisible(false);
} else if ($show == true) {
$this->excel_sheet->getColumnDimension($column_index)->setOutlineLevel(1);
}
}
/**
* @description: 固定表格指定行
* @param cell_index string 行索引 B2
* @return:
*/
public function fixed_row($cell_index)
{
$this->excel_sheet->freezePane($cell_index);
}
/**
* @description: 设置密码保护表格
* @param password string 密码
* @return:
*/
public function set_excel_pass($password)
{
$this->excel_sheet->getProtection()->setPassword($password);
$this->excel_sheet->getProtection()->setSheet(true);
$this->excel_sheet->getProtection()->setSort(true);
$this->excel_sheet->getProtection()->setInsertRows(true);
$this->excel_sheet->getProtection()->setFormatCells(true);
}
/**
* @description: 设置单选的下拉选项
* @param spectials array 需要加下拉框的单元格信息 [['column'=>'A','select_options'=>['是','否']]]
* @param colummn int 要设置的行数
* @return:
*/
public function set_excel_radio($spectials,$colummn)
{
foreach($spectials as $spectial)
{
$optionsString = implode(',', $spectial['select_options']);
$n = 0;
while($n < $colummn) {
//这一句为要设置数据有效性的单元格
$objValidation = $this->excel_sheet->getCell($spectial['column'].(string)$n)->getDataValidation();
$objValidation->setType(\PHPExcel_Cell_DataValidation::TYPE_LIST)
->setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_STOP)
->setAllowBlank(true)
->setShowInputMessage(true)
->setShowErrorMessage(true)
->setShowDropDown(true)
->setErrorTitle('输入的值有误')
->setError('您输入的值不在下拉框列表内.')
->setPromptTitle('')
->setPrompt('')
->setOperator(\PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN)
->setFormula1('"'.$optionsString.'"');
$n++;
}
}
}
/**
* @description:保存excel
* @param filename string 直接下载时文件名
* @param type string 保存类型 默认为xls或xlxs(根据文件类型保存);PDF、HTML、CSV、
* @param save_path string 保存excel的路径,默认为直接下载
* @return:
*/
public function save_excel($filename,$type='',$save_path = 'php://output')
{
$type = strtolower($type);
if ($type == '') {
$save_object = \PHPExcel_IOFactory::createWriter($this->excel, $this->file_type);
} else if ($type == 'pdf') {
$save_object = new \PHPExcel_Writer_PDF($this->excel);
} else if ($type == 'html') {
$save_object = new \PHPExcel_Writer_HTML($this->excel);
} else if ($type == 'csv') {
$save_object = new \PHPExcel_Writer_CSV($this->excel);
} else {
throw '请导出正确的文件类型';
}
if ($save_path == 'php://output') {
$filename = str_replace("+", "%20", urlencode($filename));
ob_clean();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control:must-revalidate, post-check=0, pre-check=0");
header("Content-Type:application/force-download");
header("Content-Type:application/vnd.ms-execl");
header("Content-Type:application/octet-stream");
header("Content-Type:application/download");;
header('Content-Disposition:attachment;filename='.$filename);
header("Content-Transfer-Encoding:binary");
}
$save_object->save($save_path);
}
}
单选来源于方法:https://blog.csdn.net/qq_41277856/article/details/103634056
部分方法来源于:https://blog.csdn.net/lampsunny/article/details/79012173