##从前台获取文件: 前台代码
1 2 3 4 |
<input id='location' type="text" class="controls" disabled>//用来显示选择的文件 <input type="button" id="i-check" value="选择报名表" class="btn btn-sm btn-success" onclick="$('#i-file').click();" style="margin-top: -2px"> <input type="file" id='i-file' name="examfile" accept=".xlsx,.xls" onchange="$('#location').val($('#i-file').val());" style="display: none"> //隐藏的存文件的目录 |
前台获取文件为3个input框: 第一个type=“text”,用来显示获取到文件的路径; 第二个type="button"点击按钮; 第三个type="file"隐藏的获取文件的表单。 流程: 当button 触发click事件,则调用$(’#i-file’).click();触发file,当file类型的input获取到值(文件路径),则change事件将路径值显示在location。 jQuery的 .val() – 设置或返回表单字段的值。 ##后台接收文件: 获取: 通过调用request对象的file()方法获取。
1 2 3 4 5 6 7 |
if(request()->isPost()){ $file = request()->file('examfile'); if (!$file) { return $this->error('未选择任何文件','JoinController/joinMultiple'); } } |
移动(上传): 内置的上传只是上传到本地服务器,上传到远程或者第三方平台的话需要自己扩展。
1 2 3 4 5 6 7 |
// 移动到框架应用根目录/public/uploads/ 目录下 $file_url = ROOT_PATH . 'public' . DS . 'upload'; //. DS . 'excel' $config = [ 'size' => 2097152, 'ext' => 'xlsx,xls' ]; $info = $file->validate($config)->move($file_url); //2MB |
其中validata()是一个格式验证,传入参数为最大字节size和限定的后缀ext;
1 2 3 4 5 6 7 8 9 10 |
/** * 设置上传文件的验证规则 * @param array $rule 验证规则 * @return $this */ public function validate($rule = []) { $this->validate = $rule; return $this; } |
move 方法成功的话返回的是一个 \think\File 对象,你可以对上传后的文件进行后续操作, move方法如果只传入一个路径则默认会在目录下生成时间目录,且文件名为自动生成的。 例如:20180926\bbc624371e90924a8483b5421acc2e43.xlsx 时间目录20180926下的这个文件 如果不想生成时间目录,且用原始文件名,则通过传入其他参数。 原始文件名采用:move($file_url,")
1 2 3 4 5 6 7 8 |
/** * 移动文件 * @param string $path 保存路径 * @param string|bool $savename 保存的文件名 默认自动生成 * @param boolean $replace 同名文件是否覆盖 * @return false|SplFileInfo false-失败 否则返回SplFileInfo实例 */ public function move($path, $savename = true, $replace = true) |
后续操作: 对move()方法获取到的返回值$info可以执行: getExtension()获得扩展名(后缀名) getSaveName()域名 getFilename()文件名 好的可以获取文件地址通过:
1 |
$url=$info->getSaveName(); |
注意:在文档中查到 getSaveName 方法返回的是图片的服务器文件地址,并不能直接用于图片的URL地址,尤其在 windows平台上必须做转换才能正常显示图片。 所以正确的获取路径的方法为:
1 2 |
$url=$info->getSaveName(); $file_url .= "\\" . $url; |
getSaveName()得到的其实就是文件名加后缀名,要得到的file_url为可用的URL地址。则 $file_url .= "\\" . $url其中 **.=**为连接符 ,双斜杠为转义字符,本意为单斜杆。 则将**$file_url**传入到真正的文件文件处理的方法中,这里是import()方法。 上述过程完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
public function upload() { if(request()->isPost()){ $file = request()->file('examfile'); if (!$file) { return $this->error('未选择任何文件','JoinController/joinMultiple'); } // 移动到框架应用根目录/public/uploads/ 目录下 $file_url = ROOT_PATH . 'public' . DS . 'upload'; //. DS . 'excel' $config = [ 'size' => 2097152, 'ext' => 'xlsx,xls' ]; $info = $file->validate($config)->move($file_url); //2MB if ($info) { $url=$info->getSaveName(); $file_url .= "\\" . $url; try{ chmod($file_url, 0777); }catch(\Exception $e){} $result = $this->import($file_url,$info->getExtension()); try{ //使用文件对象的时候没有完全关闭句柄,导致无法删除该文件。 //解决方法只需要在上传逻辑完成之后清空释放一下变量 会在public/upload下多一些空文件夹 unset($info); unlink($file_url); }catch(\Exception $e){} if (!$result) //为"" { return $this->success('导入成功','JoinController/joinMultiple'); }else { return $this->error($result,'JoinController/joinMultiple'); } } else { // 上传失败获取错误信息 return $this->error($file->getError(),'JoinController/joinMultiple'); } }else { return $this->error("非法请求",'JoinController/joinMultiple'); } } |
##处理文件: 我处理的为Excel文件,经过上述步骤将一个Excel的URL地址,和其扩展名传入了处理函数import()。 一.PHPExcel的安装和引用: 注意在处理之前必须采用使用composer安装PHPExcel。 教程 Git地址 use一下全套服务:
1 2 3 |
use PHPExcel; use PHPExcel_IOFactory; use PHPExcel_Cell; |
或者:
1 2 3 |
//引入PHPExcel header("content-type:text/html; charset=utf-8"); vendor("phpoffice.phpexcel.Classes.PHPExcel"); |
就完成了引用! 二.开始处理: 1.通过实例化的PHPExcel_IOFactory对象调用createReader()方法获得Reader对象;
1 |
$PHPReader = PHPExcel_IOFactory::createReader('Excel5'); //use excel2007 for 2007 format |
2.Reader对象的load方法调用URL地址获取到存放文件内容的PHPExcel;
1 |
$PHPExcel = $PHPReader->load($filename); |
3.通过PHPExcel的getActiveSheet方法获取sheet当前工作sheet sheet可以存在多个,通过索引getActiveSheet(0)
1 |
$sheet = $PHPExcel->getActiveSheet(0);//获得sheet |
1 |
$highestRow = $sheet->getHighestRow(); // 取得共有数据数 |
4.将sheet转化为数组进行处理,则Excel中的内容就变成了一个二维数组,方便处理了。 […]
View Details在开发过程中,经常会遇到导入导出的需求,利用phpexcel类实现起来也是比较容易的,下面,我们一步一步实现 提前将phpexcel类下载,并放在扩展目录中,如图所示 一、Excel导出 导出功能,相对复杂,复杂就复杂在设置导出的excel文件的样式以及内容如何循环赋值,而且导出之后的处理结果,一般是直接在通过浏览器下载到本地,或者发送邮件,在此,以下载到本地为例,下面是源码实现 1、首先是获取待导出的数据,这一步比较简单
1 2 3 4 5 6 7 8 9 10 |
//首先获取所有待发货的订单 $where['status'] = 2; $order_model = new OrderModel(); $res = $order_model ->with('OGModel') ->where($where) ->select()->toArray(); if(!$res) $this->error('暂无待发货的记录'); //dump($res);die; $count = count($res); |
2、设置Excel导出文件的样式以及为每个单元格赋值,这一步是导出最重要最复杂的一步,好在我都做了注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
1 //引入Excel类 2 $objPHPExcel = new \PHPExcel(); 3 // 设置excel文档的属性 4 $objPHPExcel->getProperties()->setCreator("cyf") 5 ->setLastModifiedBy("cyf Test") 6 ->setTitle("order") 7 ->setSubject("Test1") 8 ->setDescription("Test2") 9 ->setKeywords("Test3") 10 ->setCategory("Test result file"); 11 //设置excel工作表名及文件名 12 $title = '待发货订单'; 13 $excel_filename = '待发货订单_'.date('Ymd_His'); 14 // 操作第一个工作表 15 $objPHPExcel->setActiveSheetIndex(0); 16 //第一行设置内容 17 $objPHPExcel->getActiveSheet()->setCellValue('A1',$excel_filename); 18 //合并 19 $objPHPExcel->getActiveSheet()->mergeCells('A1:AC1'); 20 //设置单元格内容加粗 21 $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true); 22 //设置单元格内容水平居中 23 $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); 24 //设置excel的表头 25 $sheet_title = array('订单编号','下单时间','订单金额','订单状态','支付方式','付款时间','支付单号','配送方式', 26 '收货人','联系电话','省','市','区','地址','运费','商品名称','商品货号','商品规格','商品数量','商品单价', 27 '发货单号','卖家备注','实付金额','微信/支付宝金额','余额支付','优惠金额','买家备注','物流公司','物流单号'); 28 // 设置第一行和第一行的行高 29 $objPHPExcel->getActiveSheet()->getRowDimension('1')->setRowHeight(20); 30 $objPHPExcel->getActiveSheet()->getRowDimension('2')->setRowHeight(25); 31 $letter = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 32 'Q','R','S','T', 'U','V','W','X','Y','Z','AA','AB','AC'); 33 //设置单元格 34 $objPHPExcel->getActiveSheet()->getStyle('A2:AC2')->getBorders()->getAllBorders()->setBorderStyle(\PHPExcel_Style_Border::BORDER_THIN); 35 //首先是赋值表头 36 for ($k=0;$k<29;$k++) { 37 $objPHPExcel->getActiveSheet()->setCellValue($letter[$k].'2',$sheet_title[$k]); 38 $objPHPExcel->getActiveSheet()->getStyle($letter[$k].'2')->getFont()->setSize(10)->setBold(true); 39 //设置单元格内容水平居中 40 $objPHPExcel->getActiveSheet()->getStyle($letter[$k].'2')->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); 41 //设置每一列的宽度 42 $objPHPExcel->getActiveSheet()->getColumnDimension($letter[$k])->setWidth(18); 43 $objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(30); 44 45 } 46 //开始赋值 47 for ($i=0;$i<$count;$i++) { 48 //先确定行 49 $row = $i+3;//再确定列,最顶部占一行,表头占用一行,所以加3 50 $temp = $res[$i]; 51 for ($j = 0;$j<29;$j++) { 52 //开始为每个单元格赋值 53 //初始化地址数据 54 $address_arr = []; 55 $address_arr = explode(',',$temp['address_address']); 56 //初始化商品数据 57 $product_name = $product_number = $product_attr = $product_num = $product_price = ''; 58 $cl = ','.chr(10); 59 foreach ($temp['o_g_model'] as $v) { 60 $product_name .= $v['title'].$cl; 61 $product_number .= $v['attrid'].$cl; 62 $attr = []; 63 $attr = json_decode($v['attr_name'],true); 64 if ($attr) { 65 foreach ($attr as $vv) { 66 $product_attr .= $vv.' '; 67 } 68 $product_attr .= $cl; 69 } 70 $product_num .= $v['num'].$cl; 71 $product_price .= $v['user_price'].$cl; 72 } 73 switch ($j) { 74 case 0 : 75 //订单编号 76 $cellvalue = $temp['order_num']; 77 break; 78 case 1 : 79 //下单时间 80 $cellvalue = date('Y-m-d H:i:s',$temp['addtime']); 81 break; 82 case 2 : 83 //订单金额 84 $cellvalue = $temp['price_sum']; 85 break; 86 case 3 : 87 //订单状态 88 $cellvalue = lang('ORDER_STATUS')[$temp['status']]; 89 break; 90 case 4 : 91 //支付方式 92 $cellvalue = lang('ORDER_PAY')[$temp['pay_type']]; 93 break; 94 case 5 : 95 //付款时间 96 $cellvalue = ''; 97 break; 98 case 6 : 99 //支付单号 100 $cellvalue = ''; 101 break; 102 case 7 : 103 //配送方式 104 $cellvalue = lang('POST_TYPE')[$temp['post_type']]; 105 break; 106 case 8 : 107 //收货人姓名 108 $cellvalue = $temp['address_name']; 109 break; 110 case 9 : 111 //联系电话 112 $cellvalue = $temp['address_phone']; 113 break; 114 case 10 : 115 //省 116 $cellvalue = $address_arr[0]; 117 break; 118 case 11 : 119 //市 120 $cellvalue = $address_arr[1]; 121 break; 122 case 12 : 123 //区 124 $cellvalue = $address_arr[2]; 125 break; 126 case 13 : 127 //地址 128 $cellvalue = $address_arr[3]; 129 break; 130 case 14 : 131 //运费 132 $cellvalue = $temp['p_price']; 133 break; 134 case 15 : 135 //商品名称 136 $cellvalue = $product_name; 137 break; 138 case 16 : 139 //商品货号 140 $cellvalue = $product_number; 141 break; 142 case 17 : 143 //商品规格 144 $cellvalue = $product_attr; 145 break; 146 case 18 : 147 //商品数量 148 $cellvalue = $product_num; 149 break; 150 case 19 : 151 //商品单价 152 $cellvalue = $product_price; 153 break; 154 case 20 : 155 //发货单号 156 $cellvalue = '已废弃'; 157 break; 158 case 21 : 159 //卖家备注 160 $cellvalue = ''; 161 break; 162 case 22 : 163 //实付金额 164 $cellvalue = $temp['pay_money']; 165 break; 166 case 23 : 167 //微信支付宝金额 168 $cellvalue = $temp['pay_money']; 169 break; 170 case 24 : 171 //余额支付 172 $cellvalue = $temp['static_money']; 173 break; 174 case 25 : 175 //优惠金额 176 $cellvalue = $temp['coupon']; 177 break; 178 case 26 : 179 //买家备注 180 $cellvalue = ''; 181 break; 182 case 27 : 183 //物流公司 184 $cellvalue = ''; 185 break; 186 case 28 : 187 //物流单号 188 $cellvalue = ''; 189 break; 190 } 191 //赋值 192 $objPHPExcel->getActiveSheet()->setCellValue($letter[$j].$row, $cellvalue); 193 //设置字体大小 194 $objPHPExcel->getActiveSheet()->getStyle($letter[$j].$row)->getFont()->setSize(10); 195 //设置单元格内容水平居中 196 $objPHPExcel->getActiveSheet()->getStyle($letter[$j].$row)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); 197 //设置自动换行 198 if ((in_array($j,[15,16,17,18,19])) && "" != $cellvalue) { 199 $objPHPExcel->getActiveSheet()->getStyle($letter[$j].$row)->getAlignment()->setWrapText(true); // 自动换行 200 $objPHPExcel->getActiveSheet()->getStyle($letter[$j].$row)->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); // 垂直方向上中间居中 201 } 202 } 203 // 设置行高 204 $objPHPExcel->getActiveSheet()->getRowDimension($row)->setRowHeight(21); 205 } 206 unset($res); |
3、设置完之后,将生成的excel文件,通过浏览器下载到本地
1 2 3 4 5 6 7 |
1 //赋值结束,开始输出 2 $objPHPExcel->getActiveSheet()->setTitle($title); 3 header('Content-Type: application/vnd.ms-excel'); 4 header('Content-Disposition: attachment;filename="'.$excel_filename.'.xls"'); 5 header('Cache-Control: max-age=0'); 6 $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); 7 $objWriter->save('php://output'); |
4、也可以在服务器上生成excel文件,然后发送到用户邮箱
1 2 3 |
1 $filename = __ROOT__.'/upload/files/'.$excel_filename; 2 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); 3 $objWriter->save($filename); |
二、Excel导入 相比导出,导入就简单多了,废话不多说,直接上源码 1、利用form表单获取上传的excel文件
1 2 3 4 5 6 7 |
1 $file = $_FILES['file']; 2 if ($file['error'] == 4) $this->error('请选择上传excel文件'); 3 $file_types = explode ( ".", $file['name'] ); 4 $excel_type = array('xls','csv','xlsx'); 5 if (!in_array(strtolower(end($file_types)),$excel_type)){ 6 $this->error("不是Excel文件,请重新上传"); 7 } |
2、然后,读取excel文件里面的数据,这里是边读取边处理,或者全部读取出来再处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
1 //设置获取excel对象 2 $objReader = \PHPExcel_IOFactory::createReader('Excel5');//配置成2003版本,因为office版本可以向下兼容 3 $objPHPExcel = $objReader->load($file['tmp_name'],$encode='utf-8');//$file 为解读的excel文件 4 //dump($objPHPExcel);die; 5 $sheet = $objPHPExcel->getSheet(0); 6 $highestRow = $sheet->getHighestRow(); // 取得总行数 7 $success_item = $fail_item = 0; 8 //发货 9 $order_model = new OrderModel(); 10 //开始读取数据 11 for($j=3;$j<=$highestRow;$j++) 12 { 13 $order_num = $objPHPExcel->getActiveSheet()->getCell('A'.$j)->getValue(); 14 $poster = $objPHPExcel->getActiveSheet()->getCell("AB".$j)->getValue();//物流公司 15 $logistics = $objPHPExcel->getActiveSheet()->getCell("AC".$j)->getValue();//物流单号 16 $comm = $objPHPExcel->getActiveSheet()->getCell("V".$j)->getValue();//卖家备注 17 //判断条件 18 if(!is_null($order_num) && $order_num){ 19 $res = $order_model->where('order_num',$order_num)->field('itemid,status')->find(); 20 if ($res && $res['status'] == 2) { 21 if ((!is_null($poster) && $poster) || (!is_null($logistics) && $logistics)) { 22 //更改状态 23 OrderPlanModel::addLog($res['itemid'],'确认发货',$comm); 24 $order_model->Update([ 25 'status'=>3, 26 'poster'=>$poster, 27 'logistics'=>$logistics, 28 ],['itemid'=>$res['itemid']]); 29 $success_item ++; 30 } else { 31 $fail_item ++; 32 } 33 } else { 34 $fail_item ++; 35 } 36 } else { 37 $fail_item++; 38 } 39 } 40 $this->success('成功条数:'.$success_item.',失败条数:'.$fail_item); |
多学、 多记、 多练、 from:https://www.cnblogs.com/cyfblogs/p/10115541.html
View Details在之前有写过一篇文章讲述了使用PHP快速生成excel表格文件并下载,这种方式生成Excel文件,生成速度很快,但是有缺点是: 1.单纯的生成Excel文件,生成的文件没有样式,单元格属性(填充色,宽度,高度,边框颜色…)不能自定义; 2.生成的文件虽然可以打开,但是兼容性很差,每次打开,都会报一个警告: 今天使用一个第三方的SDK(PHPExcel)实现Excel文件的导入和导出。 准备工作: 1.下载PHPExcel的SDK,下载地址:https://github.com/PHPOffice/PHPExcel。 2.将SDK解压之后的Class文件拷贝到自己的项目。 一.Excel文件读取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
function excelToArray(){ require_once dirname(__FILE__) . '/Lib/Classes/PHPExcel/IOFactory.php'; //加载excel文件 $filename = dirname(__FILE__).'/result.xlsx'; $objPHPExcelReader = PHPExcel_IOFactory::load($filename); $sheet = $objPHPExcelReader->getSheet(0); // 读取第一个工作表(编号从 0 开始) $highestRow = $sheet->getHighestRow(); // 取得总行数 $highestColumn = $sheet->getHighestColumn(); // 取得总列数 $arr = 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'); // 一次读取一列 $res_arr = array(); for ($row = 2; $row <= $highestRow; $row++) { $row_arr = array(); for ($column = 0; $arr[$column] != 'F'; $column++) { $val = $sheet->getCellByColumnAndRow($column, $row)->getValue(); $row_arr[] = $val; } $res_arr[] = $row_arr; } return $res_arr; } |
或者:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
function excelToArray(){ require_once dirname(__FILE__) . '/Lib/Classes/PHPExcel/IOFactory.php'; //加载excel文件 $filename = dirname(__FILE__).'/result.xlsx'; $objPHPExcelReader = PHPExcel_IOFactory::load($filename); $reader = $objPHPExcelReader->getWorksheetIterator(); //循环读取sheet foreach($reader as $sheet) { //读取表内容 $content = $sheet->getRowIterator(); //逐行处理 $res_arr = array(); foreach($content as $key => $items) { $rows = $items->getRowIndex(); //行 $columns = $items->getCellIterator(); //列 $row_arr = array(); //确定从哪一行开始读取 if($rows < 2){ continue; } //逐列读取 foreach($columns as $head => $cell) { //获取cell中数据 $data = $cell->getValue(); $row_arr[] = $data; } $res_arr[] = $row_arr; } } return $res_arr; } |
1 |
两种方法均可将表格数据转化为数组,然后哦再进行相关的操作就简单了。 二.Excel文件导出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
/** * 创建(导出)Excel数据表格 * @param array $list 要导出的数组格式的数据 * @param string $filename 导出的Excel表格数据表的文件名 * @param array $indexKey $list数组中与Excel表格表头$header中每个项目对应的字段的名字(key值) * @param array $startRow 第一条数据在Excel表格中起始行 * @param [bool] $excel2007 是否生成Excel2007(.xlsx)以上兼容的数据表 * 比如: $indexKey与$list数组对应关系如下: * $indexKey = array('id','username','sex','age'); * $list = array(array('id'=>1,'username'=>'YQJ','sex'=>'男','age'=>24)); */ function exportExcel($list,$filename,$indexKey,$startRow=1,$excel2007=false){ //文件引入 require_once APP_ROOT.'/Api/excel/PHPExcel.php'; require_once APP_ROOT.'/Api/excel/PHPExcel/Writer/Excel2007.php'; if(empty($filename)) $filename = time(); if( !is_array($indexKey)) return false; $header_arr = 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'); //初始化PHPExcel() $objPHPExcel = new PHPExcel(); //设置保存版本格式 if($excel2007){ $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel); $filename = $filename.'.xlsx'; }else{ $objWriter = new PHPExcel_Writer_Excel5($objPHPExcel); $filename = $filename.'.xls'; } //接下来就是写数据到表格里面去 $objActSheet = $objPHPExcel->getActiveSheet(); //$startRow = 1; foreach ($list as $row) { foreach ($indexKey as $key => $value){ //这里是设置单元格的内容 $objActSheet->setCellValue($header_arr[$key].$startRow,$row[$value]); } $startRow++; } // 下载这个表格,在浏览器输出 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"); $objWriter->save('php://output'); } |
导出文件,还可以设置模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
function exportExcel($list, $filename, $indexKey = array()) { require_once dirname(__FILE__) . '/Lib/Classes/PHPExcel/IOFactory.php'; require_once dirname(__FILE__) . '/Lib/Classes/PHPExcel.php'; require_once dirname(__FILE__) . '/Lib/Classes/PHPExcel/Writer/Excel2007.php'; $header_arr = 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'); //$objPHPExcel = new PHPExcel(); //初始化PHPExcel(),不使用模板 $template = dirname(__FILE__) . '/template.xls'; //使用模板 $objPHPExcel = PHPExcel_IOFactory::load($template); //加载excel文件,设置模板 $objWriter = new PHPExcel_Writer_Excel5($objPHPExcel); //设置保存版本格式 //接下来就是写数据到表格里面去 $objActSheet = $objPHPExcel->getActiveSheet(); $objActSheet->setCellValue('A2', "活动名称:江南极客"); $objActSheet->setCellValue('C2', "导出时间:" . date('Y-m-d H:i:s')); $i = 4; foreach ($list as $row) { foreach ($indexKey as $key => $value) { //这里是设置单元格的内容 $objActSheet->setCellValue($header_arr[$key] . $i, $row[$value]); } $i++; } // 1.保存至本地Excel表格 //$objWriter->save($filename.'.xls'); // 2.接下来当然是下载这个表格了,在浏览器输出就好了 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 . '.xls"'); header("Content-Transfer-Encoding:binary"); $objWriter->save('php://output'); } |
先弄一个excel模板 然后使用该模板导出数据 from:https://www.jianshu.com/p/f7c07763a16e
View Details第一种开机执行命令法: 直接修改/etc/rc.d/rc.local文件 编辑文件/etc/rc.d/rc.local vi /etc/rc.d/rc.local 比如要将zookeeper添加为开机自启动就在最后加上“/usr/local/zookeeper-3.4.5/bin/zkServer.sh start” 配置好之后,重启centos,会发现命令被执行了。前提条件是当前机器环境变量中有java命令即$JAVA_HOME/bin的路径,否则zookeeper也启动不了。 Bash
1 2 3 4 5 6 7 8 9 10 11 |
[root@zookeeper ~]# vim /etc/rc.d/rc.local #!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local # /usr/local/zookeeper-3.4.5/bin/zkServer.sh start |
第二种服务自启动法: 这次换个jetty吧 1、进入到/etc/rc.d/init.d目录下,新建一个jetty脚本 Bash
1 |
vi /etc/rc.d/init.d/jetty |
将以下脚本写入文件中,可以看出这是一个case语句判断,当我们使用"service jetty start"启动服务的时候"start"参数就会变成$1传入下面的脚本,从而做出对应的操作。 # chkconfig: 345 99 99 (这个比较有意思,345代表在设置在那个level中是on的,如果一个都不想on,那就写一个横线"-",比如:chkconfig: – 99 99。后面两个数字当然代表S和K的默认排序号啦,基本都写99,排后面启动安全保险) Bash
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#!/bin/bash #chkconfig: 345 99 99 #description:jetty server #processname:jetty JETTY_HOME=/app/jetty9_4_8 case $1 in start) su root $JETTY_HOME/bin/jetty.sh start;; stop) su root $JETTY_HOME/bin/jetty.sh stop;; check) su root $JETTY_HOME/bin/jetty.sh check;; restart) su root $JETTY_HOME/bin/jetty.sh restart;; *) echo "require start|stop|check|restart" ;; esac |
2、最后保存jetty文件后别忘了设置文件的执行权限 Bash
1 |
chmod +x jetty |
3、至此服务已经创建好了,可以用"service jetty start"来启动jetty了,但我们要设置自启动还需要添加到chkconfig来管理 Bash
1 2 3 |
chkconfig --add jetty chkconfig --list jetty |
看到3是启动状态就说明在文本界面启动方式下该服务已经设置为自启动了,5是图形化界面 如果不是启动状态需要用命令开启自启动 Bash
1 2 3 |
chkconfig --level 345 jetty on chkconfig --list jetty |
这样就没问题了。 from:https://blog.csdn.net/e_wsq/article/details/79885180
View Details一、CentOS7添加自定义脚本服务说明 在CentOS7下,已经不再使用chkconfig命令管理系统开机自启动服务和条件自定义脚本服务了,而是使用管理unit的方式来控制开机自启动服务和添加自定义脚本服务。在/usr/lib/systemd/system目录下包含了各种unit文件,有service后缀的服务unit,有target后缀的开机级别unit等。这里介绍自定义脚本服务,如果想把自定义的脚本变成服务进程,都需要写对应的service配置文件,这样才能被unit所管理(注意:自定义开机自启动服务的.service配置文件必须放在/usr/lib/systemd/system这个目录下面)。服务类别又分为服务又分为系统服务(system)和用户服务(user)。 系统服务:开机不登陆就能运行的程序(常用于开机自启)。 用户服务:需要登陆以后才能运行的程序。 二、编写.service配置文件说明 1、[unit]区块:设置管理启动顺序与依赖关系 Description=服务描述 给出当前服务的简单描述 Documentation=路径或url 给出文档位置 After=服务.target或服务.service 定义在某些服务之后启动。例如sshd服务启动必须在network.target sshd-keygen.service服务开启之后才能启动,可以使用如下命令查看sshd服务的配置 cat /usr/lib/systemd/system/sshd.service Before=服务.target 定义在某些服务之前启动 Wants=服务.service 弱依赖,表示等号填写服务启动或失败,不影响此配置文件服务的启动 Requires=服务.service 强依赖,表示等号填写服务启动或失败,那么此配置文件的服务将启动失败 注意:如果After、Before、Wants、Requires等号后面需要填写多个服务可以用空格隔开。After和Before字段只涉及启动顺序,不涉及依赖关系。Wants字段与Requires字段只涉及依赖关系,与启动顺序无关,默认情况下是同时启动的。 2、[Service]区块:设置启动行为 •启动命令 ExecStart=命令 定义启动进程时执行的命令 ExecReload=命令 重启服务时执行的命令 ExecStop=命令 停止服务时执行的命令 ExecStartPre=命令 启动服务之前执行的命令 ExecStartPost=命令 启动服务之后执行的命令 ExecStopPost=命令 停止服务之后执行的命令 所有的启动设置之前,都可以加上一个连词号(-),表示"抑制错误",即发生错误的时候,不影响其他命令的执行。例如:ExecStop=-/bin/sh /server/scripts/xx.sh •启动类型 Type字段定义启动类型。它可以设置的值如下: simple(默认值) ExecStart字段启动的进程为主进程 forking ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程(后台运行) oneshot 类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务 dbus 类似于simple,但会等待 D-Bus 信号后启动 notify 类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务 idl 类似于simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合 •重启行为 KillMode字段,定义Systemd如何停止服务,它可以设置的值如下 control-group(默认值) 当前控制组里面的所有子进程,都会被杀掉 process 只杀主进程 mixed 主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号 none 没有进程会被杀掉,只是执行服务的 stop 命令 Restart字段,定义了服务退出后,Systemd的重启方式,它可以设置的值如下 no(默认值) 退出后不会重启 on-success 只有正常退出时(退出状态码为0),才会重启 on-failure 非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启 on-abnormal 只有被信号终止和超时,才会重启 on-abort 只有在收到没有捕捉到的信号终止时,才会重启 on-watchdog 超时退出,才会重启 always 不管是什么退出原因,总是重启 •service区块的其他一些字段 […]
View Details在写shell脚本的时候发现cd切换目录的时候无法切换,代码是下面的。
1 2 3 4 5 6 7 |
#!/bin/bash #changedir.sh cd /home/firefox pwd |
我仔细一想,我执行的时候是./changedir.sh来执行的,这样执行的话终端会产生一个子shell,子shell去执行我的脚本,在子shell中已经切换了目录了,但是子shell一旦执行完,马上退出,子shell中的变量和操作全部都收回。回到终端根本就看不到这个过程的变化。那么怎么验证上面的猜想呢?看下面的代码
1 2 3 4 5 6 7 8 9 10 11 |
#!/bin/bash #changedir.sh history cd /home/firefox sleep 1 pwd |
首先按照 ./changedir.sh执行,这时候终端没有切换目录,history执行的结果是空的,说明子shell里面没有历史命令(这是肯定的)。然后按照 source changedir.sh执行,这时候就是直接在终端的shell执行脚本了,没有生成子shell,执行的结果就是输出历史命令,并且切换了目录。 from:https://blog.csdn.net/firefoxbug/article/details/7317279
View Details命令行下执行 sql 文件有两种方法 一、第一中方法 (未连接数据库) 不推荐这样使用 因为在密码带有特殊字符时会报错
1 |
mysql -h localhost -u username -ppassword < filepath #filepath 为绝对路径 |
二、第二中方法(已链接数据库 当提示符为 mysql> 时) 这里的 yourDatavase 为你的数据库名 filepath 为 sql 文件的绝对路径
1 2 |
use yourDatabase; source filepath; |
附: 一、命令行下创建数据库
1 |
CREATE DATABASE IF NOT EXISTS yourDatabaseName DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; |
二、命令行下创建数据表 下面的 id、title、author、date 这些字段根据实际需求填写
1 2 3 4 5 6 7 |
CREATE TABLE IF NOT EXISTS `yourTableName`( `id` INT UNSIGNED AUTO_INCREMENT, `title` VARCHAR(100) NOT NULL, `author` VARCHAR(40) NOT NULL, `date` DATE, PRIMARY KEY ( `id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
三、删除数据库 yourDatabaseName 为你要删除的数据库名
1 |
drop database yourDatabaseName; |
四、删除数据表 yourTableName 为你要删除的数据表名
1 |
DROP TABLE yourTableName; |
五、允许远程连接mysql数据库
1 2 |
grant all privileges on *.* to 'admin'@'%' identified by '123456' with grant option; flush privileges; |
允许任何ip地址(%表示允许任何ip地址)的电脑用admin帐户和密码(123456)来访问这个mysql server。 注意admin账户不一定要存在。 六、修改表引擎方法
1 |
alter table table_name engine=innodb; |
其它数据库操作请自行查询 from:https://blog.csdn.net/ming_xiaoxiami/article/details/81905388
View Details在生产环境下启动Weblogic时,发现原来好好的nohup信息输出到指定文件中的功能,突然出问题了。现象是控制台输出的信息一部分输出到了我指定的文件,另一部分却输出到了nohup.out,而我是不想让它产生nohup.out文件,不知道是什么原因。 我的启动命令是这样的: nohup bin/startManagedServer.sh myserver htp://192.168.0.1 -Xms2048m -Xmx2048m > logs/myserver.out &现在指行这个命令,会给我产生两个文件,一个中logs/myserver.out,另一个是nohup.out文件。 怎样才能让它不产生nohup.out文件呢。 网上搜了半天,据说好象可以把后面的 “&” 改成 “2>&1 &”,于是把启动命令改成如下: nohup bin/startManagedServer.sh myserver htp://192.168.0.1 -Xms2048m -Xmx2048m > logs/myserver.out 2>&1 &再次执行,问题解决。 解释如下: 2> 表示把标准错误(stderr)重定向,标准输出(stdout)是1。 尖括号后面可以跟文件名,或者是&1, &2,分别表示重定向到标准输出和标准错误。 2> &1 1> &2 2> stderr.log 1> stdout.log from:https://www.xuebuyuan.com/2205812.html?mobile=0
View Details阅读目录 第一种:我们知道端口号用下面这种方法 第二种:我们知道服务名称 比如查询tomcat 如何通过pid看端口 window下杀死进程 window下自启 第一种:我们知道端口号用下面这种方法 有时候我们知道某个服务端口正在后台运行,想关掉它。比如说我tomcat是8080端口,在后台运行。怎么关掉它呢? 根据端口查看这个进程的pid
1 |
netstat -lnp|grep 8080 #8080请换为你的apache需要的端口 |
查看进程的详细信息
1 |
ps 1777 #1777就是上一步得到的pid |
杀掉进程
1 |
例如: kill -9 [PID] #-9 表示强迫进程立即停止 |
第二种:我们知道服务名称 比如查询tomcat 根据pid查看进程的详细信息
1 |
ps -ef|grep redis |
root 7474 1 0 14:58 ? 00:00:01 /usr/local/redis/redis-4.0.11/src/redis-server 127.0.0.1:6379 root 7794 2175 0 15:30 pts/0 00:00:00 grep --color=auto redis 7474就是pid 如何通过pid看端口
1 |
netstat -antup |grep 2711 |
jar类型的项目后台执行
1 2 3 4 5 |
nohup java -jar XX.jar >temp.text & //nohup 意思是不挂断运行命令,当账户退出或终端关闭时,程序仍然运行 //当用 nohup 命令执行作业时,缺省情况下该作业的所有输出被重定向到nohup.out的文件中 //除非另外指定了输出文件。 // 这种方法会把日志文件输入到你指定的文件中,没有则会自动创建 |
window下杀死进程
1 2 3 4 |
netstat -ano | findstr 9999 taskkill /f /pid 12612 |
window下自启
1 |
%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 放快捷方式 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
1、Windows平台 在windows命令行窗口下执行: 1.查看所有的端口占用情况 C:\>netstat -ano 协议 本地地址 外部地址 状态 PID TCP 127.0.0.1:1434 0.0.0.0:0 LISTENING 3236 TCP 127.0.0.1:5679 0.0.0.0:0 LISTENING 4168 TCP 127.0.0.1:7438 0.0.0.0:0 LISTENING 4168 TCP 127.0.0.1:8015 0.0.0.0:0 LISTENING 1456 TCP 192.168.3.230:139 0.0.0.0:0 LISTENING 4 TCP 192.168.3.230:1957 220.181.31.225:443 ESTABLISHED 3068 TCP 192.168.3.230:2020 183.62.96.189:1522 ESTABLISHED 1456 TCP 192.168.3.230:2927 117.79.91.18:80 ESTABLISHED 4732 TCP 192.168.3.230:2929 117.79.91.18:80 ESTABLISHED 4732 TCP 192.168.3.230:2930 117.79.91.18:80 ESTABLISHED 4732 TCP 192.168.3.230:2931 117.79.91.18:80 ESTABLISHED 4732 2.查看指定端口的占用情况 C:\>netstat -aon|findstr "9050" 协议 本地地址 外部地址 状态 PID TCP 127.0.0.1:9050 0.0.0.0:0 LISTENING 2016 P: 看到了吗,端口被进程号为2016的进程占用,继续执行下面命令: (也可以去任务管理器中查看pid对应的进程) 3.查看PID对应的进程 C:\>tasklist|findstr "2016" 映像名称 PID 会话名 会话# 内存使用 ========================= ======== ================ tor.exe 2016 Console 0 16,064 K P:很清楚吧,tor占用了你的端口。 4.结束该进程 C:\>taskkill /f /t /im tor.exe |
from:https://www.cnblogs.com/coder-lzh/p/8977232.html
View Details关键字: linux 查进程、杀进程、起进程 1.查进程 ps命令查找与进程相关的PID号: ps a 显示现行终端机下的所有程序,包括其他用户的程序。 ps -A 显示所有程序。 ps c 列出程序时,显示每个程序真正的指令名称,而不包含路径,参数或常驻服务的标示。 ps -e 此参数的效果和指定"A"参数相同。 ps e 列出程序时,显示每个程序所使用的环境变量。 ps f 用ASCII字符显示树状结构,表达程序间的相互关系。 ps -H 显示树状结构,表示程序间的相互关系。 ps -N 显示所有的程序,除了执行ps指令终端机下的程序之外。 ps s 采用程序信号的格式显示程序状况。 ps S 列出程序时,包括已中断的子程序资料。 ps -t<终端机编号> 指定终端机编号,并列出属于该终端机的程序的状况。 ps u 以用户为主的格式来显示程序状况。 ps x 显示所有程序,不以终端机来区分。 最常用的方法是ps aux,然后再通过管道使用grep命令过滤查找特定的进程,然后再对特定的进程进行操作。 ps aux | grep program_filter_word,ps -ef |grep tomcat ps -ef|grep java|grep -v grep 显示出所有的java进程,去处掉当前的grep进程。 2.杀进程 使用kill命令结束进程:kill xxx 常用:kill -9 324 Linux下还提供了一个killall命令,可以直接使用进程的名字而不是进程标识号,例如:# killall -9 NAME 3.进入到进程的执行文件所在的路径下,执行文件 ./文件名 附: 这是本人花了两天时间整理得来的,一些最常用的地球人都知道的命令就省去啦!最后提供pdf手册下载 1. 更改档案拥有者 命令 : chown [-cfhvR] [--help] [--version] user[:group] file… 功能 : 更改文件或者文件夹的拥有者 参数格式 […]
View Details