利用form.submit提交表单导出文件到客户端浏览器, 提示下载!
本来是想利用ajax提交json数据到服务端, 让服务端生成一个excel文件并提示客户端浏览器下载的. 但是搞了很久发现ajax方式是无法触发浏览器弹出文件下载的.
网上很多的方案都是说利用form提交, 还有就是纯客户端js去生成excel文件. 这两种方案都是可行的, 今天只演示第一种.
浏览器上展示了一堆数据, 有个按钮是导出按钮,点击后触发一个事件, 提交数据到服务端, 由服务端来生成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 | onExportExcel = () => { ....... 这里准备好需要提交到服务端的数据 const inputs = { data, header, columnWidth, filename, }; this .exportExcel( '/xx1/xx2/exportExcel' , inputs); } exportExcel(url, data) // 导出数据到excel文件 { const form = document.createElement( 'form' ); form.style = "display:none;" ; form.method = "post" ; form.action = url; const input = document.createElement( 'input' ); input.type = 'hidden' ; input.name = 'values' ; input.value = Base64.encode(JSON.stringify(data)); form.appendChild(input); $( 'body' ).append(form); form.submit(); form.remove(); } |
这里用了一个Base64.encode()接口(下载), 这里是关键, 因为普通的input表单一般是用于传递字符串的, 但是因为我这里要传递的是一个object对象(也可认为是json数据), 所以我就想到了将json序列化后并base64编码下(不编码的话, 服务端接收到的值有可能json_decode会失败). ==> 所以服务端在接收时要采取相反的方向先base64_decode, 再调用json_decode才能得到原始的json数据!
服务端代码(php, thinkcmf5.0):
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 | public function exportExcel() { $values = request()->post( 'values' ); $values = base64_decode ( $values ); $list = json_decode( $values , true); if (! $list ) { _return(1, '没有数据, 无法导出到文件' ); } log_message( $list ); $data = $list [ 'data' ]; $header = $list [ 'header' ]; $columnWidth = $list [ 'columnWidth' ]; $filename = $list [ 'filename' ]; if ( empty ( $data ) || empty ( $header ) || empty ( $filename )) { $this ->success( 'success' ); return ; } ExcelModule::exportFile( $data , $header , $columnWidth , $filename ); } |
ExcelModule::exportFile是我自已写的一个类, 封装的一个静态接口函数
1 class ExcelModule 2 { 3 /** 4 * 导出数据到excel文件并提供下载 5 * @param array $data 6 * @param array $fileheader 7 * @param array $columnWidth 8 * @param $savefile 9 * @param string $sheetname 10 * @throws \PHPExcel_Exception 11 * @throws \PHPExcel_Reader_Exception 12 * @throws \PHPExcel_Writer_Exception 13 */ 14 public static function exportFile(array $data, array $fileheader, array $columnWidth, $savefile, $sheetname = 'MySheet') 15 { 16 Vendor('PHPExcel.PHPExcel.IOFactory'); 17 $excel = new \PHPExcel(); 18 //防止中文命名,下载时ie9及其他情况下的文件名称乱码 19 // iconv('UTF-8', 'GB2312', $savefile); 20 $objActSheet = $excel->getActiveSheet(); 21 //根据有生成的excel多少列,$letter长度要大于等于这个值 22 $letter = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'); 23 //设置当前的sheet 24 $excel->setActiveSheetIndex(0); 25 //设置sheet的name 26 $objActSheet->setTitle($sheetname); 27 //设置表头 28 for ($i = 0; $i < count($fileheader); $i++) { 29 // 单元宽度自适应,1.8.1版本phpexcel中文支持勉强可以,自适应后单独设置宽度无效 30 // $objActSheet->getColumnDimension("$letter[$i]")->setAutoSize(true); 31 $objActSheet->getColumnDimension("$letter[$i]")->setWidth($columnWidth[$i]); 32 // 设置表头值,这里的setCellValue第二个参数不能使用iconv,否则excel中显示false 33 $objActSheet->setCellValue("{$letter[$i]}1", $fileheader[$i]); 34 // 设置表头字体样式 35 $objActSheet->getStyle("{$letter[$i]}1")->getFont()->setName('微软雅黑'); 36 //设置表头字体大小 37 $objActSheet->getStyle("{$letter[$i]}1")->getFont()->setSize(12); 38 //设置表头字体是否加粗 39 // $objActSheet->getStyle("{$letter[$i]}1")->getFont()->setBold(true); 40 //设置表头文字垂直居中 41 $objActSheet->getStyle("{$letter[$i]}1")->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); 42 //设置文字上下居中 43 $objActSheet->getStyle("$letter[$i]")->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER); 44 //设置表头外的文字垂直居中 45 $excel->setActiveSheetIndex(0)->getStyle("$letter[$i]")->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER); 46 } 47 48 $j = 2; 49 foreach ($data as $k => $v) { 50 $i = 0; 51 foreach ($v as $key => $value) { 52 $objActSheet->setCellValue($letter[$i] . $j, $value); 53 // $objActSheet->getColumnDimension("$letter[$i]")->setAutoSize(true); 54 $objActSheet->getColumnDimension("$letter[$i]")->setWidth($columnWidth[$i]); 55 $i++; 56 } 57 $j++; 58 } 59 header('Content-Type: application/vnd.ms-excel'); 60 //下载的excel文件名称,为Excel5,后缀为xls,不过影响似乎不大 61 header('Content-Disposition: attachment;filename="' . $savefile . '.xls"'); 62 header('Cache-Control: max-age=0'); 63 // 用户下载excel 64 $objWriter = \PHPExcel_IOFactory::createWriter($excel, 'Excel2007'); 65 $objWriter->save('php://output'); 66 exit; 67 } 68 }
我这个php服务端是thinkcmf5.0框架下的, 包含了很多现成的库!
最终效果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)