Export.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace app\common\service;
  13. use app\common\model\Express;
  14. use app\common\model\member\MemberCooperationCoupon;
  15. use app\store\model\OrderGoods as OrderGoodsModel;
  16. use PhpOffice\PhpSpreadsheet\Cell\DataType;
  17. use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
  18. use PhpOffice\PhpSpreadsheet\Reader\Xls;
  19. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  20. use PhpOffice\PhpSpreadsheet\IOFactory;
  21. use PhpOffice\PhpSpreadsheet\Style\Alignment;
  22. use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
  23. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  24. /**
  25. * 短信服务类
  26. * Class Order
  27. * @package app\common\service
  28. */
  29. class Export extends BaseService {
  30. /**
  31. * 导出示例
  32. * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
  33. */
  34. public function testExport(){
  35. $data = [
  36. ['title'=>'张三', 'content' => '张三的内容', 'prices' => '100', 'create_time' => '2017.10.12', 'end_time' =>'2020.12.12'],
  37. ['title'=>'李四', 'content' => '李四的内容', 'prices' => '222', 'create_time' => '2017.10.12', 'end_time' =>'2020.12.12'],
  38. ['title'=>'王莽', 'content' => '王莽的内容', 'prices' => '343', 'create_time' => '2017.10.12', 'end_time' =>'2022.03.12'],
  39. ];
  40. $header = ['名称', '内容', '金额', '开始时间', '结束时间'];
  41. self::export($data, $header, $title = 'test', $filename = 'test', $file_type = 'Csv');
  42. }
  43. /**
  44. * 下载导出文件
  45. * @param array $data 数据二维数组
  46. * @param array $header 表头
  47. * @param string $filename 文件名称
  48. * @param string $title excel标题
  49. * @param string $format
  50. * @param bool $isDelivery 发货导出
  51. * @return array
  52. * @throws \PhpOffice\PhpSpreadsheet\Exception
  53. * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
  54. */
  55. public static function export(array $data, array $header, $filename = '导出订单', $title = 'test', $format = 'Xls',$isDelivery=false)
  56. {
  57. $expressOptions = '';
  58. if ($isDelivery == true){
  59. $expressOptions = Express::getExpressNames();
  60. }
  61. set_time_limit(0);
  62. $title_key = [];
  63. foreach ($data[0] as $key=>$val){
  64. $title_key[] = $key;
  65. }
  66. $unit = array(
  67. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
  68. 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN',
  69. 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ'
  70. );
  71. $line_count = count($header);
  72. $newExcel = new Spreadsheet(); //创建一个新的excel文档
  73. $objSheet = $newExcel->getActiveSheet(); //获取当前操作sheet的对象
  74. $objSheet->setTitle($title); //设置当前sheet的标题
  75. $n = 1;
  76. for ($i = 0; $i < $line_count; ++$i){
  77. $objSheet->setCellValue($unit[$i].$n, $header[$i]);
  78. foreach ($data as $key=>$val){
  79. $objSheet->getColumnDimension($unit[$i])->setAutoSize(true);//自动计算列宽--有问题不会自动
  80. // $objSheet->getColumnDimension($unit[$i])->setWidth(20);//固定列宽
  81. $m = $key + 2;
  82. if ($isDelivery == true && $unit[$i] == "K"){//表示是快递公司列
  83. self::setValidation($objSheet,$unit[$i] . $m,$expressOptions);
  84. }
  85. if ($unit[$i] == "N" || $unit[$i] == "O" || $unit[$i] == "P"){
  86. $objSheet->getStyle($unit[$i].$m)->getAlignment()->setWrapText(true);
  87. }
  88. $objSheet->getStyle($unit[$i].$m)->getAlignment()->setWrapText(true);//自动换行 使用换行 PHP_EOL或者\n
  89. $styleArray = [
  90. 'alignment' => [
  91. // 'horizontal' => Alignment::HORIZONTAL_LEFT,//左右位置
  92. 'vertical' => Alignment::VERTICAL_CENTER,//上下位置
  93. ],
  94. ];
  95. $objSheet->getStyle($unit[$i].$m)->applyFromArray($styleArray);
  96. $objSheet->setCellValueExplicit($unit[$i] . $m, $val[$title_key[$i]],DataType::TYPE_STRING);
  97. }
  98. }
  99. ob_end_clean() ;
  100. // $format只能为 Xlsx 或 Xls
  101. if ($format == 'Xlsx') {
  102. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  103. } elseif ($format == 'Xls') {
  104. header('Content-Type: application/vnd.ms-excel');
  105. }else{
  106. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  107. }
  108. $filename = $filename .'-'. date('YmdHis') . '.' . strtolower($format);
  109. header("Content-Disposition: attachment;filename=" . $filename);
  110. header('Cache-Control: max-age=0');
  111. header('Access-Control-Allow-Origin:*');
  112. $objWriter = IOFactory::createWriter($newExcel, $format);
  113. ob_start(); //打开缓冲区
  114. $objWriter->save('php://output');
  115. $xlsdata =ob_get_contents();
  116. ob_end_clean();
  117. $data = [];
  118. $data['filename'] = $filename;
  119. $data['file'] = "data:application/vnd.ms-excel;base64,".base64_encode($xlsdata);
  120. return $data;
  121. //通过php保存在本地的时候需要用到
  122. // $objWriter->save($filename);
  123. //以下为需要用到IE时候设置
  124. // If you're serving to IE 9, then the following may be needed
  125. // header('Cache-Control: max-age=1');
  126. // //If you're serving to IE over SSL, then the following may be needed
  127. // header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
  128. // header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
  129. // header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
  130. // header('Pragma: public'); // HTTP/1.0
  131. // exit;
  132. }
  133. public static function setValidation(Worksheet $sheet, $cellPoint, $format)
  134. {
  135. $validation = $sheet -> getCell($cellPoint) -> getDataValidation();
  136. $validation -> setType(DataValidation::TYPE_LIST);
  137. $validation -> setErrorStyle(DataValidation::STYLE_INFORMATION);
  138. $validation -> setAllowBlank(false);
  139. $validation -> setShowInputMessage(true);
  140. $validation -> setShowErrorMessage(true);
  141. $validation -> setShowDropDown(true);
  142. $validation -> setErrorTitle('输出错误');
  143. $validation -> setError('值不在列表中');
  144. $validation -> setPromptTitle('请选择');
  145. $validation -> setPrompt('');
  146. $validation -> setFormula1('"'.$format.'"');
  147. // $validation->setFormula1('=major');//使用某个公式
  148. //$validation->setFormula1('"顺丰,圆通,韵达"');//可以直接写列表,用逗号分隔,最多255字符
  149. // $objValidation->setFormula1('=INDIRECT(F5)');//indirect间接的,以某个坐标为依托,联级
  150. }
  151. public static function importDemo(){
  152. $expressOptions = Express::getExpressNames();
  153. //dd($expressOptions);
  154. $spreadsheet = new Spreadsheet();
  155. $sheet = $spreadsheet->getActiveSheet();
  156. //self::setValidation($sheet,'A1',null);
  157. $unit = array(
  158. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
  159. 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN',
  160. 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ'
  161. );
  162. $n = 1;
  163. for ($i = 0; $i < 10; ++$i){
  164. $sheet->getColumnDimension($unit[$i])->setAutoSize(true);
  165. $sheet->setCellValue($unit[$i].$n, 'hearder'.$unit[$i]);
  166. for ($j=0;$j<5;$j++){
  167. $m = $j+2;
  168. if ($unit[$i] == "A"){
  169. self::setValidation($sheet,$unit[$i] . $m,$expressOptions);
  170. }
  171. $sheet->setCellValueExplicit($unit[$i] . $m, "顺丰",DataType::TYPE_STRING);
  172. }
  173. }
  174. $writer = new Xlsx($spreadsheet);
  175. $name = 'hello'.rand(10000,99999).'.xlsx';
  176. $writer->save($name);
  177. }
  178. /**
  179. * 导入批量发货
  180. * @param $fileName
  181. * @return int[]
  182. * @throws \PhpOffice\PhpSpreadsheet\Exception
  183. * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
  184. * @throws \think\db\exception\DataNotFoundException
  185. * @throws \think\db\exception\DbException
  186. * @throws \think\db\exception\ModelNotFoundException
  187. */
  188. public static function import($fileName){
  189. $reader = new Xls();
  190. $file = runtime_root_path().'/storage/'.$fileName;
  191. $excel = $reader->load($file);
  192. //$sheetCount = $excel->getSheetCount();
  193. $sheet = $excel->getSheet(0);
  194. $sheetRows = $sheet->getHighestRow();
  195. $exp = Express::getAllList();
  196. $expEs = array_column($exp,'express_name','express_id');
  197. $failure = $success = 0;
  198. $model = new OrderGoodsModel();
  199. for ($i = 2; $i <= $sheetRows; $i++) {
  200. //order_goods_id
  201. $orderGoodsId = trim($sheet->getCell('A' . $i)->getValue()??'');
  202. //快递公司
  203. $expressName = trim($sheet->getCell('K' . $i)->getValue()??'');
  204. if (!$expressName){
  205. $failure += 1;
  206. continue;
  207. }
  208. $expressId = array_search($expressName,$expEs);
  209. if ($expressId == false){
  210. $failure += 1;
  211. continue;
  212. }
  213. //快递单号
  214. $expressNo = trim($sheet->getCell('L' . $i)->getValue()??'');
  215. if (!$expressNo){
  216. $failure += 1;
  217. continue;
  218. }
  219. if ($model->delivery(['order_goods_id'=>[$orderGoodsId],'express_id'=>$expressId,'express_no'=>$expressNo,'is_update'=>0])) {
  220. $success += 1;
  221. }else{
  222. $failure += 1;
  223. }
  224. }
  225. return ['failure'=>$failure,'success'=>$success];
  226. }
  227. /**
  228. * 导入批量发货
  229. * @param $welfareId
  230. * @param $fileName
  231. * @return bool
  232. * @throws \PhpOffice\PhpSpreadsheet\Exception
  233. * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
  234. */
  235. public static function importCooperationCodes($welfareId,$fileName): bool
  236. {
  237. if (!$fileName)return false;
  238. //$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
  239. $reader = new Xls();
  240. $excel = $reader->load($fileName);
  241. //$sheetCount = $excel->getSheetCount();
  242. $sheet = $excel->getSheet(0);
  243. $sheetRows = $sheet->getHighestRow();
  244. $datas = [];
  245. $now = time();
  246. $model = new MemberCooperationCoupon();
  247. for ($i = 2; $i <= $sheetRows; $i++) {
  248. $datas[] = [
  249. 'coupon_id'=>trim(strval($sheet->getCell('B' . $i)->getValue()??'')),
  250. 'coupon_name'=>trim(strval($sheet->getCell('C' . $i)->getValue()??'')),
  251. 'create_time'=>$now,
  252. 'update_time'=>$now,
  253. 'welfare_id'=> $welfareId,
  254. 'code'=>trim(strval($sheet->getCell('D' . $i)->getValue()??'')),
  255. 'provider'=>trim(strval($sheet->getCell('E' . $i)->getValue()??'')),
  256. ];
  257. if (count($datas) >3000){
  258. $model->insertAll($datas);
  259. unset($datas);
  260. $datas = [];
  261. }
  262. }
  263. if (count($datas)){
  264. $model->insertAll($datas);
  265. }
  266. return true;
  267. }
  268. }