Download VMMap (626 KB) Run now from Sysinternals Live. Introduction VMMap is a process virtual and physical memory analysis utility. It shows a breakdown of a process’s committed virtual memory types as well as the amount of physical memory (working set) assigned by the operating system to those types. Besides graphical representations of memory usage, VMMap also shows summary information and a detailed process memory map. Powerful filtering and refresh capabilities allow you to identify the sources of process memory usage and the memory cost of application features. Besides flexible views […]
View Details前世今生: Dubbo源于阿里的淘宝网开源的分布式的服务架构,致力于提供高性能和透明化的RPC远程服务调用方案,是SOA服务化治理方案的核心框架。淘宝网将其开源之后,得到了很多的拓展和支持(比较出名的有:当当网的扩展版本dubbox,京东的扩展版本jd-hydra等) Dubbox(即Dubbo eXtensions)是当当网Fork基于dubbo2.x的升级版本,兼容原有的dubbox。其中升级了zookeeper和spring版本,并且支持restfull风格的远程调用。。 版本: Dubbo目前已停止更新; Dubbox目前还在更新。 说明:dubbox和dubbo 2.x是兼容的, 没有改变dubbo的任何已有的功能和配置方式(除了升级了Spring之类的版本)。 据说淘宝网dubbo与一个非开源的框架HSF有争执,导致dubbo的团队已经解散了,但是其扩展的版本dubbox却得到不断的发展(升级更新); <!——--升级详情——--|——————-- dubbox-2.8.0:该版本已经在生产环境中使用,主要支持REST风格远程调用、支持Kryo和FST序列化、升级了Spring和Zookeeper客户端、调整了demo应用等等 dubbox-2.8.1:主要支持基于嵌入式tomcat的http-remoting,优化了REST客户端性能,在REST中支持限制服务端接纳的最大HTTP连接数等等 dubbox-2.8.2: 支持REST中的HTTP logging,包括HTTP header的字段和HTTP body中的消息体,方便调试、日志纪录等等 提供辅助类便于REST的中文处理 改变使用@Reference annotation配置时的异常处理方式,即当用annotation配置时,过去dubbo在启动期间不抛出依赖服务找不到的异常,而是在具体调用时抛出NPE,这与用XML配置时的行为不一致。 较大的充实了Dubbo REST的文档 dubbox-2.8.3: 在REST中支持dubbo统一的方式用bean validation annotation作参数校验(沈理) 在RpcContext上支持获取底层协议的Request/Response(沈理) 支持采用Spring的Java Config方式配置dubbo(马金凯) 在Dubbo协议中支持基于Jackson的json序列化(Dylan) 在Spring AOP代理过的对象上支持dubbo annotation配置(Dylan) 修正Dubbo管理界面中没有consumer时出现空指针异常(马金凯) 修正@Reference annotation中protocol设置不起作用的bug(沈理) 修正@Reference annotation放在setter方法上即会出错的bug(Dylan) 详见:https://github.com/dangdangdotcom/dubbox/releases ———/> 嵌入: dubbo:嵌入式Jetty dubbox:基于嵌入式tomcat实现dubbo的 HTTP remoting体系(即dubbo-remoting-http) 对Servlet API的支持: dubbo:2.5 dubbox:升级到3.1 序列化: dubbo: dubbox:基于Dubbo默认的RPC协议添加新的JSON序列化实现; 支持基于Kryo和FST的Java高效序列化实现; Zookeeper注册中心: dubbo:Dubbo提供了Zookeeper注册中心,在整个Dubbo的设计里面充分考虑到了各类用户的需求,一些底层的通讯或者是信息存储都提供有大量的不同的存储方案; dubbox:升级ZooKeeper客户端到最新版本; 使用场景: dubbo:使用Dubbo的RPC调用方式,服务间仍然会存在API强依赖; dubbox:相对于Dubbo支持了REST风格的原创调用(HTTP +JSON/XML); ——————————————————- ——简言之(dubbox基于dubbo的升级): ——————- 支持REST风格远程调用(HTTP + JSON/XML); 支持基于Kryo和FST的Java高效序列化实现; 支持基于Jackson的JSON序列化; 支持基于嵌入式Tomcat的HTTP remoting体系; 升级Spring至3.x; 升级ZooKeeper客户端; 支持完全基于Java代码的Dubbo配置; ————————————————- 附录: Dubbo: 官网首页:http://dubbo.io/ , 官方用户指南: http://dubbo.io/User+Guide-zh.htm可以当做SOA架构的学习资料 Dubbox: dubbox入门:http://www.cnblogs.com/yjmyzz/p/dubbox-demo.html dubbox架构: http://www.cnblogs.com/Javame/p/3632473.html 当当网dubbox学习参考文档:http://dangdangdotcom.github.io/dubbox/ 分布式服务框架 dubbo/dubbox 入门示例:http://www.cnblogs.com/wanghang/p/6298957.html ———————- […]
View Details图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。 与早期计算机使用的命令行界面相比,图形界面对于用户来说在视觉上更易于接受。然而这界面若要通过在显示屏的特定位置,以”各种美观而不单调的视觉消息“提示用户”状态的改变“,势必得比简单的消息呈现花上更多的计算能力。 图形用户界面是一种人与计算机通信的界面显示格式,允许用户使用鼠标等输入设备操纵屏幕上的图标或菜单选项,以选择命令、调用文件、启动程序或执行其它一些日常任务。与通过键盘输入文本或字符命令来完成例行任务的字符界面相比,图形用户界面有许多优点。图形用户界面由窗口、下拉菜单、对话框及其相应的控制机制构成,在各种新式应用程序中都是标准化的,即相同的操作总是以同样的方式来完成,在图形用户界面,用户看到和操作的都是图形对象,应用的是计算机图形学的技术。 GUI 即人机交互图形化用户界面设计。纵观国际相关产业在图形化用户界面设计方面的发展现状,许多国际知名公司早已意识到 GUI 在产品方面产生的强大增值功能,以及带动的巨大市场价值,因此在公司内部设立了相关部门专门从事 GUI 的研究与设计,同业间也成立了若干机构,以互相交流 GUI 设计理论与经验为目的。随着中国 IT 产业,移动通讯产业,家电产业的迅猛发展,在产品的人机交互界面设计水平发展上日显滞后,这对于提高产业综合素质,提升与国际同等业者的竞争能力等等方面无疑起了制约的作用。 GUI的广泛应用是当今计算机发展的重大成就之一,它极大地方便了非专业用户的使用。人们从此不再需要死记硬背大量的命令,取而代之的是可以通过窗口、菜单、按键等方式来方便地进行操作。而嵌入式GUI具有下面几个方面的基本要求:轻型、占用资源少、高性能、高可靠性、便于移植、可配置等特点。 from:https://baike.baidu.com/item/GUI/479966
View Details个人外贸企业需要访问国外的网络,怎么办?如果您想尝试建立您自己的 VPN,但是不确定从哪里开始,那么您来对地方了,我将比较 6 个在您自己的服务器上搭建和使用 VPN 的最好的自由和开源工具。不管您是想为您的企业建立站点到站点的 VPN,还是只是想创建一个远程代理访问以解除访问限制并对 ISP 隐藏你的互联网流量,都可以通过 VPN 来达成。 根据您的需求和条件,并参考您自己的技术特长、环境以及您想要通过 VPN 实现的目标。需要考虑以下因素: •VPN 协议 •客户端的数量和设备类型 •服务端的兼容性 •需要的技术专业能力 Algo Algo 是从下往上设计的,可以为需要互联网安全代理的商务旅客创建 VPN 专用网。它“只包括您所需要的最小化的软件”,这意味着为了简单而牺牲了可扩展性。Algo 是基于 StrongSwan 的,但是删除了所有您不需要的东西,这有另外一个好处,那就是去除了新手可能不会注意到的安全漏洞。 作为额外的奖励,它甚至可以屏蔽广告! Algo 只支持 IKEv2 协议和 Wireguard。因为对 IKEv2 的支持现在已经内置在大多数设备中,所以它不需要像 OpenVPN 这样的客户端应用程序。Algo 可以使用 Ansible 在 Ubuntu (首选选项)、Windows、RedHat、CentOS 和 FreeBSD 上部署。 使用 Ansible 可以自动化安装,它会根据您对一组简短的问题的回答来配置服务。卸载和重新部署也非常容易。 Algo 可能是在本文中安装和部署最简单和最快的 VPN。它非常简洁,考虑周全。如果您不需要其他工具提供的高级功能,只需要一个安全代理,这是一个很好的选择。请注意,Algo 明确表示,它不是为了解除地理封锁或逃避审查,主要是为了加密。 Streisand Streisand 可以使用一个命令安装在任何 Ubuntu 16.04 服务器上;这个过程大约需要 10 分钟。它支持 L2TP、OpenConnect、OpenSSH、OpenVPN、Shadowsocks、Stunnel、Tor bridge 和 WireGuard。根据您选择的协议,您可能需要安装客户端应用程序。 在很多方面,Streisand 与 Algo 相似,但是它提供了更多的协议和定制。这需要更多的工作来管理和维护,但也更加灵活。注意 Streisand 不支持 IKEv2。因为它的多功能性,我认为 Streisand 在某国和土耳其这样的地方绕过审查制度更有效,但是 Algo 的安装更容易和更快。 使用 Ansible 可以自动化安装,所以不需要太多的专业技术知识。通过向用户发送自定义生成的连接指令,包括服务器 SSL 证书的嵌入副本,可以轻松添加更多用户。 卸载 Streisand 是一个快速无痛的过程,您也可以随时重新部署。 OpenVPN OpenVPN 要求客户端和服务器应用程序使用其同名的协议建立 VPN 连接。OpenVPN […]
View Detailsphp7.1以上. mcrypt_generic_open is deprecated 这个错误, 就是因为mcrypt扩展,在php7.1以上被废弃,服务器不设置报错等级的话, 这个错误会被框架拦截,然后报出微信demo里的40007错误, 具体解决方案,所有 mcrypt扩展的代码,全部加上 错误抑制符 ,例如 //使用BASE64对需要解密的字符串进行解码 原来的代码
|
1 2 3 4 5 6 7 8 9 10 |
//使用BASE64对需要解密的字符串进行解码 $ciphertext_dec = base64_decode($encrypted); $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); $iv = substr($this->key, 0, 16); mcrypt_generic_init($module, $this->key, $iv); //解密 $decrypted = mdecrypt_generic($module, $ciphertext_dec); mcrypt_generic_deinit($module); mcrypt_module_close($module); |
修改的代码
|
1 2 3 4 5 6 7 8 9 10 |
//使用BASE64对需要解密的字符串进行解码 $ciphertext_dec = base64_decode($encrypted); @$module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); $iv = substr($this->key, 0, 16); @mcrypt_generic_init($module, $this->key, $iv); //解密 @$decrypted = mdecrypt_generic($module, $ciphertext_dec); @mcrypt_generic_deinit($module); @mcrypt_module_close($module); |
然后我的问题就解决了。 我的问题主要出在微信的加解密函数上,遇到的坑有几个 1.文档给的class默认有的是小写, 2.一个文件有多个class得拆开 3.构造函数获取的变量名称不对得修改… 这些用断点调试都可以进行解决 还有一种方案是, 我听我朋友说可以用 openssl代替mcrypt扩展的方案(mcrypt编码,openssl解码), 得重写编写微信demo里的代码,虽然我没成功… from:https://blog.csdn.net/qq_38686693/article/details/81388329
View Details参考地址:http://blog.csdn.net/sanbingyutuoniao123/article/details/71124655 关于“SSL证书问题:无法获取本地颁发者证书”错误。很明显,这适用于发送CURL请求的系统(并且没有服务器接收请求) 1)从https://curl.haxx.se/ca/cacert.pem下载最新的cacert.pem 2)将以下行添加到php.ini(如果这是共享托管,并且您无法访问php.ini,那么可以在public_html中添加到.user.ini) curl.cainfo=/path/to/downloaded/cacert.pem from:https://www.cnblogs.com/haoxuanchen2014/p/8067484.html
View Details##从前台获取文件: 前台代码
|
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 DetailsSpring Boot 内嵌容器Undertow参数设置 配置项:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 # 不要设置过大,如果过大,启动项目会报错:打开文件数过多 server.undertow.io-threads=16 # 阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程 # 它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数*8 server.undertow.worker-threads=256 # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 # 每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可 server.undertow.buffer-size=1024 # 每个区分配的buffer数量 , 所以pool的大小是buffer-size * buffers-per-region server.undertow.buffers-per-region=1024 # 是否分配的直接内存(NIO直接分配的堆外内存) server.undertow.direct-buffers=true |
来看看源代码: https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/Undertow.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
ioThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2); workerThreads = ioThreads * 8; //smaller than 64mb of ram we use 512b buffers if (maxMemory < 64 * 1024 * 1024) { //use 512b buffers directBuffers = false; bufferSize = 512; } else if (maxMemory < 128 * 1024 * 1024) { //use 1k buffers directBuffers = true; bufferSize = 1024; } else { //use 16k buffers for best performance //as 16k is generally the max amount of data that can be sent in a single write() call directBuffers = true; bufferSize = 1024 * 16 - 20; //the 20 is to allow some space for protocol headers, see UNDERTOW-1209 } |
很显然,Undertow认为它的运用场景是在IO密集型的系统应用中,并且认为多核机器是一个比较容易满足的点,Undertow初始化假想应用的阻塞系数在0.8~0.9之间,所以阻塞线程数直接乘了个8,当然,如果对应用较精确的估测阻塞系数,可以配置上去。 Spring Boot内嵌容器支持Tomcat、Jetty、Undertow。为什么选择Undertow? 这里有一篇文章,时间 2017年1月26日发布的: Tomcat vs. Jetty vs. Undertow: Comparison of Spring Boot Embedded Servlet Containers 1. Setup Spring Boot Application We will use Maven to setup a new project in Eclipse with the appropriate dependencies. We will use the starter parent for this example but the dependencies in a production application will likely be altered to streamline, optimize or customize. 1.1 Setup Spring Boot Dependencies The default embedded servlet container is Tomcat. This version of Spring Web […]
View Details