phpexcel 读取公式失败,超时等问题

mahuatengBC 2019-08-17 02:20:53
在读取公式的时候,使用了getCalculatedValue() 函数,如果是通一个sheet里面的公式,可以读出结果,但是如果公式调用了其他sheet的字段,使用该函数会出现读取失败,超时等情况。改如何解决呢?










...全文
510 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
mahuatengBC 2019-08-23
  • 打赏
  • 举报
回复
就没人回复?
mahuatengBC 2019-08-19
  • 打赏
  • 举报
回复

public function test(){

		if(IS_POST){
	 
			$upload = new \Think\Upload();// 实例化上传类
			$upload->maxSize   =     10485760 ;// 设置附件上传大小
			$upload->exts      =     array('xls', 'xlsx', 'csv');// 设置附件上传类型
			$upload->savePath  =      '/default/'; // 设置附件上传目录
			$info   =   $upload->upload($_FILES);
		
			if(!$info) {
				$this->ajaxReturn(array('status'=>0,'info'=>$upload->getError(),'data'=>''));
			}else{
				$fileName = 'Uploads'.$info['file']['savepath'].$info['file']['savename'];
		
				require 'vendor/autoload.php';
				
				$inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($fileName);
				$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); //实例化阅读器对象。
				$spreadsheet = $reader->load($fileName);  //将文件读取到到$spreadsheet对象中
				
				//加载所有工作表
				$reader->setLoadAllSheets();
				//只读数据,忽略格式
				$reader->setReadDataOnly(true);
				
				$sheet = $spreadsheet->getActiveSheet(); // 读取活动工作表

				$highest_row = $sheet->getHighestRow(); // 取得总行数
				
				$highest_column = $sheet->getHighestColumn(); ///取得列数  字母abc...
// 				echo $highest_column;
				$highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highest_column);  //转化为数字;

				$mergeCells = $sheet->getMergeCells(); //获取合并的单元格
				
				//判断是否有合并单元格
				/* if(!empty($mergeCells)){
					 foreach ($mergeCells as $val){
					echo "$val"."<br/>";
					$sheet->unmergeCells("$val");//拆除合并
				}
				} */
				
				//判断表头个数
				$titleCount = false;
				if(!empty($mergeCells)){
					//多表头
					
					foreach ($mergeCells as $cells){
						if(strpos($cells, '3') !== false){
							$titleCount = true;
						}
					}
				
					if($titleCount){
						echo json_encode(['status'=>0,'info'=>'目前只支持双表头'],JSON_UNESCAPED_UNICODE);
						return false;
					}
				}

				$isset = 0;
				for ($row = 1; $row <= $highest_row; $row++) {
					$isNull = true;
					for ($column = 1; $column <= $highestColumnIndex; $column++) {
						$cellName = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($column);
						
						$val = $sheet->getCell($cellName.$row)->getValue();
	        			
						//如果val是对象
						if(is_object($val)){
							$val = $val->__toString();
						}
						
	        			//如果有公式
	        			if(strpos($val, '=') !== false){
	        				$val = $sheet->getCell($cellName.$row)->getCalculatedValue();
	        				//保留两位小数
	        				$val = round($val,2);
	        			}
	        			
	        			//判断是否有手机号或者邮箱
	        			if($val === '手机' || $val === '手机号' || $val === '手机号码' || $val === '电话' || $val === '电话号码'){
	        				$isset = 1;
	        			}

						if (!empty($val)) {
							$isNull = false;
						}
						
						$data[$row][$cellName] = $val;
					}

					/* 判断是否整行数据为空,是的话删除该行数据 */
					if ($isNull) {
						unset($data[$row]);
					}
	
				}

// 				print_r($data);

				//判断是否有手机号字段
				if($isset === 0){
					//删除源文件
					unlink($fileName);
					// 返回JSON数据格式到客户端 包含状态信息
	                echo json_encode(['status'=>0,'info'=>'没有匹配到手机号'],JSON_UNESCAPED_UNICODE);
	                return false;
				}

				//剩余可发送条数
				$result = M('company_pay_stup')->where(['company_id'=>$this->company['id']])->find();
				$leftCount = $result['type'] == 1 ? intval($result['free_count']) : intval($result['count']);
				
				//本次发薪条数
				$count = empty($mergeCells) ? count($data) -1 : count($data)-2;
				//首先验证身份,是否可发
				if($count - $leftCount > 0){
					//删除源文件
					unlink($fileName);
					echo json_encode(['status'=>-2,'info'=>'可发工资条数量不足,请去充值'],JSON_UNESCAPED_UNICODE);
					return false;
				}
				
				//文件正确读取,返回结果
				echo json_encode(['status'=>1,'info'=>'','data'=>$fileName],JSON_UNESCAPED_UNICODE);

			}
		}
	
	}
网上找了一些资料,用 php spreadsheet ,重写了一个,可以实现读取非当前sheet的数据了,至少没报错。。。 但是读出来的数据是0,也就是没有读出正确的值。。。 先这样,读出来再贴代码吧。
mahuatengBC 2019-08-17
  • 打赏
  • 举报
回复
现在逛论坛的人这么少了,哎! 自己试过读取多个sheet,但是依然报错,所以又改回了,只读当前活动的sheet ,代码如下
if(IS_POST){

        	//判断是否完善资料
      		$company = M('company')->where(['id'=>$this->company['id']])->find();
      		if(empty($company['name']) || empty($company['phone']) || empty($company['short']) || empty($company['contact'])){
      			$this->ajaxReturn(['status'=>-1,'info'=>'还没有完善资料,请先去完善资料']);
      		}  	

        	//获取参数
        	$date = I('date'); //日期
        	$type = I('type');//标题
        	
	        $upload = new \Think\Upload();// 实例化上传类    
	        $upload->maxSize   =     10485760 ;// 设置附件上传大小    
	        $upload->exts      =     array('xls', 'xlsx', 'csv');// 设置附件上传类型    
	        $upload->savePath  =      '/default/'; // 设置附件上传目录     
	        $info   =   $upload->upload($_FILES);
	
	        if(!$info) {       
	            $this->ajaxReturn(array('status'=>0,'info'=>$upload->getError(),'data'=>''));    
	        }else{
	        	$fileName = 'Uploads'.$info['file']['savepath'].$info['file']['savename'];

	        	//加载excel类库
	        	import("Org.Util.PHPExcel");
	        	
	        	//创建PHPExcel对象
	        	$PHPExcel = new \PHPExcel();
	        	 
	        	//文件后缀
	        	$exts = explode('.', $fileName)[1];
	        	 
	        	//如果excel文件后缀名为.xls,导入这个类
	        	if ($exts == 'xls') {
	        		import("Org.Util.PHPExcel.Reader.Excel5");
	        		$PHPReader = new \PHPExcel_Reader_Excel5();
	        		//$PHPReader = \PHPExcel_IOFactory::createReader('Excel5');
	        	} else if ($exts == 'xlsx') {
	        		import("Org.Util.PHPExcel.Reader.Excel2007");
	        		$PHPReader = new \PHPExcel_Reader_Excel2007();
	        		//$PHPReader = \PHPExcel_IOFactory::createReader('Excel2007');
	        	}
	        	
	        	$PHPReader->setReadDataOnly(TRUE);
	        	$PHPExcel = $PHPReader->load($fileName);
	        	
	        	/* $objWriter = new \PHPExcel_Writer_HTML($PHPExcel);
	        	$objWriter->setSheetIndex(0);
	        	$objWriter->save(str_replace('.php', '.htm', __FILE__)); */

	        	//当前活动工作表
// 	        	$currentSheet = $PHPExcel->getSheet(0);
	        	$currentSheet = $PHPExcel->getActiveSheet();
	        	
// 	        	$aaa= $currentSheet->getMergeCells();
// 	        	print_r($aaa);
	        	//获取总行数
	        	$allRow = $currentSheet->getHighestRow();

	        	//获取最大列
	        	$allColumn = $currentSheet->getHighestColumn();
	        	
	        	//获取最大列的count
	        	$heightIndex = \PHPExcel_Cell::columnIndexFromString($allColumn);
	        	
	        	/* 循环读取每个单元格的数据 */
	        	$boolen = false;
	        	for ($currentRow = 1; $currentRow <= $allRow; $currentRow++){
	        		 for ($currentColumn = 0; $currentColumn < $heightIndex; $currentColumn++) {
                    	//转换列
                    	$col_name = \PHPExcel_Cell::stringFromColumnIndex($currentColumn);//由列数反转列名(0->'A')
                    	
	        			$val = $currentSheet->getCell($col_name.$currentRow)->getValue();
	        			
	        			//如果有公式
	        			if(strpos($val, '=') !== false){
	        				$val = $currentSheet->getCell($col_name.$currentRow)->getCalculatedValue();
	        				//保留两位小数
	        				$val = round($val,2);
	        			}
	        			
	        			//判断是否有手机号或者邮箱
	        			if($val === '手机' || $val === '手机号' || $val === '手机号码' || $val === '电话' || $val === '电话号码'){
	        				$boolen = true;
	        			}
	        			
	        			$data[$currentRow][] = $val;
	        		}
	        	}

	        	//清除空数组
        	    foreach ($data as $k => $v){
        	    	$data[$k] = array_filter($v);
        	    }
        	    
	        	$titles = [];
	        	$dataArr = [];
	        	foreach ($data as $k => $v){
	        		if(empty($v)){
	        			unset($data[$k]);
	        		}else{
	        			if(in_array('手机',$data[$k],true)||in_array('手机号',$data[$k],true)||in_array('手机号码',$data[$k],true)||in_array('电话',$data[$k],true)||in_array('电话号码',$data[$k],true)){
	        				$titles[] = $v;
	        			}elseif(empty($v[0]) && empty($v[1]) && empty($v[2])){
	        				//判断前3个都为空,即为双表头?
	        				$titles[] = $v;
	        			}else{
	        				$dataArr[] = $v;
	        			}
	        		}	
	        	}
如何判断是表头还是数据?如果读取其他sheet的列? 如何读取合并的列?(如果是多表头!) 路过的给点提示也行...

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧