PHP에서 그림이 포함된 Excel 표를 가져오는 방법은 무엇입니까? 사진을 Excel로 내보내는 방법은 무엇입니까? 내보낸 Excel의 스타일을 정의하여 더욱 아름답게 만드는 방법은 무엇입니까? 다음 글을 통해 하나씩 해결해 보시길 바랍니다.
Excel은 데이터 수집 및 통계에 일반적으로 사용되는 도구입니다. 일반적으로 일부 정보 플랫폼에서는 종이 없는 환경을 구현하거나 클라우드로 이동하려면 사무실 데이터를 사무실 컴퓨터에서 플랫폼으로 마이그레이션해야 합니다. 또는 개발자가 아닌 사람이 사용하기 위해 플랫폼에서 데이터를 다운로드하려면 필연적으로 데이터 가져오기 및 내보내기가 수반되며 데이터 형식은 Excel이어야 합니다.
이 문서에서는 실제 개발 요구 사항을 결합하고 개발 프로세스 중 Excel 가져오기 및 내보내기를 요약합니다. 관련 개발 프레임워크:
배포 시 Excel에 그림이 많은 데이터의 경우 시간 초과 또는 실행 시간을 늘리고 업로드 크기 제한을 늘려야 합니다
코드 웨어하우스: https://github.com/QuintionTang/crayon-thinkphp
데이터 가져오기 시작하기 전에 가져온 데이터의 형식을 정의해야 하며, 데이터를 올바르게 구문 분석하려면 규정된 형식 프로그램을 엄격히 따라야 합니다. 일반적인 데이터 가져오기는 일반 텍스트 데이터입니다. 이 기사에서는 가져오기 요구 사항을 최대한 충족하기 위해 Excel에서 그림과 함께 데이터를 가져옵니다.
템플릿은 데이터 가져오기의 기초입니다. 아래에는 다음 형식으로 간단한 데이터 템플릿이 정의되어 있습니다.
텍스트와 그림이 있는 경우 데이터를 가져오기 위한 첫 번째 선택은 Excel 파일을 읽는 것입니다. 따라서 파일도 포함되어야 합니다. 파일이 성공적으로 업로드된 후 먼저 이미지 열을 감지하고 코드를 직접 살펴보세요.
public function excel_import(){ $usedfor = empty($_GET['usedfor']) ? 'picture' : trim($_GET['usedfor']); $used_for = $usedfor; import('ORG.Net.UploadFile'); $upload = $this->_upload_init(new \Org\Net\UploadFile(),$usedfor);// 实例化上传类 $attach = array(); $attachment = array(); $attach["success"] = 0; $info = ""; if(!$upload->upload()) { // 上传错误提示错误信息 $upload_error = $upload->getErrorMsg(); $attach["msg"] = $upload_error; }else{ // 上传成功 获取上传文件信息 $info = $upload->getUploadFileInfo(); } // 上传成功后开始处理 if(is_array($info)){ $info = $info[0]; // PHPExcel 类引入 import("Org.Util.PHPExcel"); import("Org.Util.PHPExcel.Reader.Excel5"); import("Org.Util.PHPExcel.Reader.Excel2007"); import("Org.Util.PHPExcel.IOFactory.php"); $filePath = $info["savepath"] . $info["savename"]; $input_file_type = \PHPExcel_IOFactory::identify($filePath); // 开始读取Excel数据 $objExcel = new \PHPExcel(); $objReader = \PHPExcel_IOFactory::createReader($input_file_type); // 加载Excel文件 $objPHPExcel = $objReader->load($filePath); $objWorksheet = $objPHPExcel->getActiveSheet(); $data = $objWorksheet->toArray(); $attach_path = C('attach_path'); $subpath = date('YmdHm', time()); // Excel图片存储路径 $imageFileRealPath = $attach_path . "excel_img/".$subpath ."/" ; mkdirs($imageFileRealPath); $i = 0; $rebarRows = array(); // 下面开始处理图片 foreach ($objWorksheet->getDrawingCollection() as $img) { list($startColumn, $startRow) = \PHPExcel_Cell::coordinateFromString($img->getCoordinates()); //获取图片所在行和列 $imageFileName = uniqid(); try { switch($img->getExtension()) { case 'jpg': case 'jpeg': $imageFileName .= '.jpeg'; $source = imagecreatefromjpeg($img->getPath()); imagejpeg($source, $imageFileRealPath.$imageFileName,100); break; case 'gif': $imageFileName .= '.gif'; $source = imagecreatefromgif($img->getPath()); $width = imagesx($source); $height = imagesy($source); if (function_exists("imagecreatetruecolor")) { $newImg = imagecreatetruecolor($width, $height); /* --- 用以处理缩放png图透明背景变黑色问题开始 --- */ $color = imagecolorallocate($newImg,255,255,255); imagecolortransparent($newImg,$color); imagefill($newImg,0,0,$color); ImageCopyResampled($newImg, $source, 0, 0, 0, 0, $width, $height, $width, $height); } else { $newImg = imagecreate($width, $height); ImageCopyResized($newImg, $source, 0, 0, 0, 0, $width, $height, $width, $height); } imagejpeg($source, $imageFileRealPath.$imageFileName,100); break; case 'png': $imageFileName .= '.png'; $source = imagecreatefrompng($img->getPath()); $width = imagesx($source); $height = imagesy($source); if (function_exists("imagecreatetruecolor")) { $newImg = imagecreatetruecolor($width, $height); /* --- 用以处理缩放png图透明背景变黑色问题开始 --- */ $color = imagecolorallocate($newImg,255,255,255); imagecolortransparent($newImg,$color); imagefill($newImg,0,0,$color); ImageCopyResampled($newImg, $source, 0, 0, 0, 0, $width, $height, $width, $height); } else { $newImg = imagecreate($width, $height); ImageCopyResized($newImg, $source, 0, 0, 0, 0, $width, $height, $width, $height); } imagejpeg($newImg, $imageFileRealPath.$imageFileName,100); break; } $startColumn = $this->ABC2decimal($startColumn); $data[$startRow-1][$startColumn] = $imageFileRealPath . $imageFileName; } catch (\Throwable $th) { throw $th; } } $rowsData = array(); foreach ($data as $key => $rowData) { $serial = safty_value($rowData[0],0,'intval'); // 第一列 序号 $title = safty_value($rowData[1],'','trim'); // 第二列 名称 $logo_save_path = safty_value($rowData[2],'','trim'); // logo图形保存路径 $remark = safty_value($rowData[3],'','trim'); //备注 if ($serial >0 && $logo_save_path!=="" && $title!==""){ array_push($rowsData,array( "serial"=>$serial, "title"=>$title, "logo_path"=>$logo_save_path, "remark"=>$remark )); } } // 将导入的数据生成文件缓存 $this->update_excel_data($rowsData); $upload_result = array( "count" => count($rowsData), "success" => 1, "state"=>"SUCCESS" ); } else { $upload_result = array( "message" => "上传失败!", "success" => 0 ); } echo json_encode($upload_result); }
다음 작업 과정은 다음과 같습니다.
파일을 선택합니다. 업로드하고 가져오려면 내보내기가 성공하면 현재 목록 페이지가 표시되고 새로 고쳐집니다.
내보내기 성공 후 목록:
이 시점에서 데이터 가져오기가 완료되었습니다.
불충분합니다. 가져온 Excel 파일은 데이터를 가져온 후 처리되지 않았으므로 삭제하는 것이 좋습니다.
이제 위 데이터를 내보내고 Excel의 형식 정의를 내보내겠습니다. :
$first_cells = array( array("serial","序号"), array("title","名称"), array("logo","logo"), array("remark","描述") );
다음 단계는 다음과 같이 테이블 헤더 형식에 따라 데이터를 캡슐화하는 것입니다.
foreach ($excel_data as $key => $row_info) { array_push($first_rows_data,array( "serial"=>$row_info['serial'], "title"=>$row_info['title'], "logo"=>$row_info['logo_path'], "remark"=>$row_info['remark'] )); }
이 시점에서 데이터 캡슐화가 완료되었으며 전체 코드는 다음과 같습니다. :
public function export(){ $excel_detail = array( "author"=>"devpoint", "date"=>join(" ",$artifacts_full) ); // 定义导出Excel表格信息 $sheets = array(); // Excel表信息,一维代表一个数据表 // 定义表头 $first_cells = array( array("serial","序号"), array("title","名称"), array("logo","logo"), array("remark","描述") ); // 为表增加数据 $excel_data = get_file_cache("excel_data"); $first_rows_data = array(); // 数据与上面表头对应 foreach ($excel_data as $key => $row_info) { array_push($first_rows_data,array( "serial"=>$row_info['serial'], "title"=>$row_info['title'], "logo"=>$row_info['logo_path'], "remark"=>$row_info['remark'] )); } array_push($sheets,array( "title"=>"前端项目流行框架", "cells"=>$first_cells, "rows"=>$first_rows_data )); $xlsName = "Excel数据导出"; $xlsName = $xlsName . date('YmdHis'); $this->exportExcel($xlsName,$sheets,$excel_detail); }
Function exportExcel
은 데이터를 Excel에 기록하고 테이블의 스타일을 정의합니다. 전체 코드는 다음과 같습니다. exportExcel
将数据写入到Excel,并定义表格的样式,完整代码如下:
protected function exportExcel($expTitle,$xlsSheets,$detail){ import("Org.Util.PHPExcel"); import("Org.Util.PHPExcel.Writer.Excel5"); import("Org.Util.PHPExcel.IOFactory.php"); $fileName = $expTitle; $objPHPExcel = new \PHPExcel(); $objPHPExcel->getDefaultStyle()->getFont()->setName('宋体'); // Excel列名称 $cellName = 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','AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM', 'AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ' ); foreach ($xlsSheets as $index => $sheet_info) { $sheet_title = $sheet_info['title']; if ($index>0){ // Excel默认已经建好的数据表,超过一张需要执行这里创建一个工作表 $newSheet = new \PHPExcel_Worksheet($objPHPExcel, $sheet_title); //创建一个工作表 $objPHPExcel->addSheet($newSheet); } else { $objPHPExcel->getActiveSheet($index)->setTitle($sheet_title); } $expCellName = $sheet_info['cells']; $expTableData = $sheet_info['rows']; $cellNum = count($expCellName); $dataNum = count($expTableData); $cellmerget = ""; $cellWidths = array(); $sheet_head_title = $sheet_title; // 下面需要为每个工作表定义宽度 switch ($index) { case 1: // 每张表的索引从 0 开始计算 $cellmerget = 'A1:E1'; $cellWidths=array(16,16,16,28,16); break; default: $cellmerget = 'A1:D1'; $sheet_head_title = $sheet_title ; $cellWidths=array(16,16,16,36); break; } $activeSheet = $objPHPExcel->setActiveSheetIndex($index); for($i=0;$i<$cellNum;$i++){ $currentCellName = $cellName[$i]; $activeSheet->getRowDimension(1)->setRowHeight(36); $activeSheet->getColumnDimension($currentCellName)->setWidth($cellWidths[$i]); $activeSheet->getStyle($currentCellName.'1')->getFont()->setSize(12)->setBold(true); $activeSheet->getStyle($currentCellName.'1')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); } $activeSheet->mergeCells($cellmerget);//合并单元格 $activeSheet->setCellValue('A1', $sheet_head_title); $activeSheet->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); $activeSheet->getStyle('A1')->getFont()->setSize(20); $activeSheet->getRowDimension(1)->setRowHeight(50); $styleThinBlackBorderOutline = array( 'borders' => array ( 'outline' => array ( 'style' => \PHPExcel_Style_Border::BORDER_MEDIUM, //设置border样式 'color' => array ('argb' => 'FF9b9b9b'), //设置border颜色 ), ), ); for($i=0;$i<$cellNum;$i++){ $currentCellName = $cellName[$i]; $activeSheet->getRowDimension(2)->setRowHeight(36); $activeSheet->getColumnDimension($currentCellName)->setWidth($cellWidths[$i]); $activeSheet->setCellValue($currentCellName.'2', $expCellName[$i][1]); $activeSheet->getStyle($currentCellName.'2')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); $activeSheet->getStyle($currentCellName.'2')->getFill()->getStartColor()->setARGB('FFc6efcd'); $activeSheet->getStyle($currentCellName.'2')->getFont()->setSize(12)->setBold(true); $activeSheet->getStyle($currentCellName.'2')->applyFromArray($styleThinBlackBorderOutline); $activeSheet->getStyle($currentCellName.'2')->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); $activeSheet->freezePane($currentCellName.'3'); // 锁定表头,3 意味着锁定第3行上面的 } switch ($index) { case 1: break; default: $start_row_index = 3; // 数据开始索引行 for($i1=0;$i1<$dataNum;$i1++){ $objPHPExcel->getActiveSheet()->getRowDimension($i1+3)->setRowHeight(60); for($j1=0;$j1<$cellNum;$j1++){ if ($j1===2){ $logo_path = $expTableData[$i1][$expCellName[$j1][0]]; if ($logo_path!=="" && file_exists($logo_path)){ $objDrawing = new \PHPExcel_Worksheet_Drawing(); $objDrawing->setPath($logo_path); $objDrawing->setHeight(60); $objDrawing->setWidth(60); $objDrawing->setOffsetX(5); $objDrawing->setOffsetY(5); $objDrawing->setCoordinates($cellName[$j1].($i1+$start_row_index)); $objDrawing->setWorksheet($objPHPExcel->getActiveSheet()); } else { $objPHPExcel->getActiveSheet()->setCellValue($cellName[$j1].($i1+$start_row_index), ""); $objPHPExcel->getActiveSheet()->getStyle($cellName[$j1].($i1+$start_row_index))->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); $objPHPExcel->getActiveSheet()->getStyle($cellName[$j1].($i1+$start_row_index))->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT); $objPHPExcel->getActiveSheet()->getStyle($cellName[$j1].($i1+$start_row_index))->getAlignment()->setWrapText(true); } } else { $objPHPExcel->getActiveSheet()->setCellValue($cellName[$j1].($i1+$start_row_index), $expTableData[$i1][$expCellName[$j1][0]]); $objPHPExcel->getActiveSheet()->getStyle($cellName[$j1].($i1+$start_row_index))->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); $objPHPExcel->getActiveSheet()->getStyle($cellName[$j1].($i1+$start_row_index))->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT); $objPHPExcel->getActiveSheet()->getStyle($cellName[$j1].($i1+$start_row_index))->getAlignment()->setWrapText(true); } } } break; } } $objPHPExcel->setActiveSheetIndex(0); header('pragma:public'); header('Content-type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8;name="'.$fileName.'.xlsx"'); header("Content-Disposition:attachment;filename=$fileName.xlsx"); // attachment新窗口打印inline本窗口打印 $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); $objWriter->save('php://output'); exit; }
导出后的格式如下:
锁定表头
锁定表头是Excel比较常见的功能,可以方便查阅者查阅数据,使用 phpExcel
设置表头的代码如下:
$activeSheet->freezePane($currentCellName.'3'); // 3 意味着锁定第3行上面的行数
表格边框样式
上面的代码设置表格边框样式的代码为PHPExcel_Style_Border::BORDER_MEDIUM
,在 phpExcel
中有14个配置可选项目。
PHPExcel_Style_Border::BORDER_NONE; PHPExcel_Style_Border::BORDER_THIN; PHPExcel_Style_Border::BORDER_MEDIUM; PHPExcel_Style_Border::BORDER_DASHED; PHPExcel_Style_Border::BORDER_DOTTED; PHPExcel_Style_Border::BORDER_THICK; PHPExcel_Style_Border::BORDER_DOUBLE; PHPExcel_Style_Border::BORDER_HAIR; PHPExcel_Style_Border::BORDER_MEDIUMDASHED; PHPExcel_Style_Border::BORDER_DASHDOT; PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; PHPExcel_Style_Border::BORDER_DASHDOTDOT; PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; PHPExcel_Style_Border::BORDER_SLANTDASHDOT;
1. BORDER_NONE
对应的完整配置项为 PHPExcel_Style_Border::BORDER_NONE
\PHPExcel_Style_Border::BORDER_THIN
헤더 잠금
헤더 잠금은 Excel 기능에서 흔히 사용되는 기능으로, 독자가 데이터를 쉽게 확인할 수 있습니다. phpExcel
을 사용하여 헤더 코드를 다음과 같이 설정하세요. :
\PHPExcel_Style_Border::BORDER_MEDIUM
표 테두리 스타일
위 코드에서 표 테두리 스타일을 설정하는 코드는PHPExcel_Style_Border::BORDER_MEDIUM
입니다. phpExcel
에는 14설정 선택 항목이 있습니다.
\PHPExcel_Style_Border::BORDER_DASHED
1.BORDER_NONE
해당 전체 구성 항목은 PHPExcel_Style_Border::BORDER_NONE
이며, 효과는 다음과 같습니다:
2.
3. BORDER_MEDIUM
\PHPExcel_Style_Border::BORDER_DOTTED
4. BORDER_DASHED
\PHPExcel_Style_Border::BORDER_THICK
5. 7. BORDER_DOUBLE
\PHPExcel_Style_Border::BORDER_DOUBLE
\PHPExcel_Style_Border::BORDER_HAIR
9. BORDER_MEDIUMDASHED
\PHPExcel_Style_Border::BORDER_MEDIUMDASHED
10. BORDER_DASHDOT
\PHPExcel_Style_Border::BORDER_DASHDOT
11. BORDER_MEDIUMDASHDOT
\PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT
12. BORDER_DASHDOTDOT
\PHPExcel_Style_Border::BORDER_DASHDOTDOT
13. BORDER_MEDIUMDASHDOTDOT
\PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT
14. BORDER_SLANTDASHDOT
\PHPExcel_Style_Border::BORDER_SLANTDASHDOT
部署
在部署上,通常的架构是 nginx + php-fpm
,对于Excel中图片比较多的数据导入需要设置加大上传文件的限制和超时时间。
在文件上传上,通常会出现 413 request Entity too Large
错误,解决的办法是在 nginx
配置中增加以下配置:
client_max_body_size 2048m;
相应的 PHP 配置也需要修改,需要修改 php.ini
:
upload_max_filesize = 2048M post_max_size = 2048M
Excel数据导入,通常会触发504错误,这种情况一般是执行时间太短,涉及的 nginx
配置:
fastcgi_connect_timeout 600;
php-fpm
中的 www.conf
request_terminate_timeout = 1800
环境问题个人觉得是后台开发经常发生的,最佳的方式是实际运行出一个最佳的配置,将其制作成 docker
镜像,这样可以确保环境迁移或者其他场合需要,可以快速完成环境配置,而且不容易出问题。
原文地址:https://juejin.cn/post/6982953271933550628
作者:天行无忌
推荐学习:《PHP视频教程》
위 내용은 ThinkPHP+phpExcel을 사용하여 Excel 데이터를 가져오고 내보내는 방법을 단계별로 가르칩니다(연습)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!