利用form.submit提交表单导出文件到客户端浏览器, 提示下载!
本来是想利用ajax提交json数据到服务端, 让服务端生成一个excel文件并提示客户端浏览器下载的. 但是搞了很久发现ajax方式是无法触发浏览器弹出文件下载的.
网上很多的方案都是说利用form提交, 还有就是纯客户端js去生成excel文件. 这两种方案都是可行的, 今天只演示第一种.
浏览器上展示了一堆数据, 有个按钮是导出按钮,点击后触发一个事件, 提交数据到服务端, 由服务端来生成excel文件流并提示浏览器下载!

按钮的点击:
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):
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是我自已写的一个类, 封装的一个静态接口函数
class ExcelModule
{
/**
* 导出数据到excel文件并提供下载
* @param array $data
* @param array $fileheader
* @param array $columnWidth
* @param $savefile
* @param string $sheetname
* @throws \PHPExcel_Exception
* @throws \PHPExcel_Reader_Exception
* @throws \PHPExcel_Writer_Exception
*/
public static function exportFile(array $data, array $fileheader, array $columnWidth, $savefile, $sheetname = 'MySheet')
{
Vendor('PHPExcel.PHPExcel.IOFactory');
$excel = new \PHPExcel();
//防止中文命名,下载时ie9及其他情况下的文件名称乱码
// iconv('UTF-8', 'GB2312', $savefile);
$objActSheet = $excel->getActiveSheet();
//根据有生成的excel多少列,$letter长度要大于等于这个值
$letter = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V');
//设置当前的sheet
$excel->setActiveSheetIndex(0);
//设置sheet的name
$objActSheet->setTitle($sheetname);
//设置表头
for ($i = 0; $i < count($fileheader); $i++) {
// 单元宽度自适应,1.8.1版本phpexcel中文支持勉强可以,自适应后单独设置宽度无效
// $objActSheet->getColumnDimension("$letter[$i]")->setAutoSize(true);
$objActSheet->getColumnDimension("$letter[$i]")->setWidth($columnWidth[$i]);
// 设置表头值,这里的setCellValue第二个参数不能使用iconv,否则excel中显示false
$objActSheet->setCellValue("{$letter[$i]}1", $fileheader[$i]);
// 设置表头字体样式
$objActSheet->getStyle("{$letter[$i]}1")->getFont()->setName('微软雅黑');
//设置表头字体大小
$objActSheet->getStyle("{$letter[$i]}1")->getFont()->setSize(12);
//设置表头字体是否加粗
// $objActSheet->getStyle("{$letter[$i]}1")->getFont()->setBold(true);
//设置表头文字垂直居中
$objActSheet->getStyle("{$letter[$i]}1")->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
//设置文字上下居中
$objActSheet->getStyle("$letter[$i]")->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
//设置表头外的文字垂直居中
$excel->setActiveSheetIndex(0)->getStyle("$letter[$i]")->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
} $j = 2;
foreach ($data as $k => $v) {
$i = 0;
foreach ($v as $key => $value) {
$objActSheet->setCellValue($letter[$i] . $j, $value);
// $objActSheet->getColumnDimension("$letter[$i]")->setAutoSize(true);
$objActSheet->getColumnDimension("$letter[$i]")->setWidth($columnWidth[$i]);
$i++;
}
$j++;
}
header('Content-Type: application/vnd.ms-excel');
//下载的excel文件名称,为Excel5,后缀为xls,不过影响似乎不大
header('Content-Disposition: attachment;filename="' . $savefile . '.xls"');
header('Cache-Control: max-age=0');
// 用户下载excel
$objWriter = \PHPExcel_IOFactory::createWriter($excel, 'Excel2007');
$objWriter->save('php://output');
exit;
}
}
我这个php服务端是thinkcmf5.0框架下的, 包含了很多现成的库!
最终效果:

利用form.submit提交表单导出文件到客户端浏览器, 提示下载!的更多相关文章
- submit()提交表单时,显示警示框
我同事在实现submit()提交表单时,想要页面弹出警示框. 但是折腾了几小时后发现,submit()始终不执行. 她的代码如下: $(document).ready(function(){ $(&q ...
- 用js怎么控制submit提交表单
需求: 1. 要在点击submit按钮的时候,弹出一个询问框,"你确定要修改?".如果按了"确定"那么就提交表单,否则就保留在原页面,既不提交不跳转. 2. 要 ...
- php使用jquery Form ajax 提交表单,并上传文件
在html5中我们通过FormData就可以ajax上传文件数据,不过因为兼容问题.我们选用jquery.form.min.js来进行ajax的表单提交. 一.jquery.form.js下载地址 ...
- submit提交表单后,不刷新当前页面
<form method="get" target="test" action="a.html"> <input type ...
- 使用jquery.form.js提交表单上传文件
方法: 1.formSerilize() 用于序列化表单中的数据,并将其自动整理成适合AJAX异步请求的URL地址格式. 2.clearForm() 清除表单中所有输入值的内容. 3.restF ...
- JS 控制 form是否提交表单
问题背景:用php删除数据,希望在点击“删除”(button)的时候JS弹出confirm来确认是否删除. 此段代码为php中的form: <form action="?form=de ...
- 利用iframe实现提交表单是页面部分刷新
直接上代码: <%@ page language="java" import="java.util.*" pageEncoding="utf-8 ...
- submit提交表单
<!DOCTYPE html><html><head> <script src="jquery-1.3.2.min.js">< ...
- 用layui的 form.on提交表单如何禁止刷新页面
答:只需要在 form.on里面的底部添加return false;即可 例如: form.on('submit(component-form-demo1)', function(data){ var ...
随机推荐
- 【Gamma阶段】第六次Scrum Meeting
冰多多团队-Gamma阶段第六次Scrum会议 工作情况 团队成员 已完成任务 待完成任务 卓培锦 编辑器风格切换(添加夜间模式) UI界面手势切换 牛雅哲 语音输入shell应用:基于pytorch ...
- hive 批量添加,删除分区
一.批量添加分区: use bigdata; alter table siebel_member add if not exists partition(dt='20180401') locati ...
- python 在cmd时执行celery -A tasks worker --loglevel=info报错:failed to create process怎么解决
在cmd命令前加 : python -m 命令(如:python -m celery -A tasks worker --loglevel=info) -m: 将库中的python模块用作脚本去运行, ...
- vim文本编辑器的使用
1.简介 vim是vi发展过来的一款文本编辑器,功能非常强大. 2.vim的工作模式 vim有三种工作模式,分别为命令模式.编辑模式.末行模式: 1)命令模式:打开文件之后,默认进入命令模式: 2)编 ...
- 镜像仓库 Nexus 3.18.1
说明:Nexus是Sonatype提供的仓库管理平台,Nuexus Repository OSS3能够支持Maven.npm.Docker.YUM.Helm等格式数据的存储和发布. 一.安装jdk 1 ...
- Akka-CQRS(8)- CQRS Reader Actor 应用实例
前面我们已经讨论了CQRS-Reader-Actor的基本工作原理,现在是时候在之前那个POS例子里进行实际的应用示范了. 假如我们有个业务系统也是在cassandra上的,那么reader就需要把从 ...
- StarGAN学习笔记
11 December 2019 20:32 来自 <https://zhuanlan.zhihu.com/p/44563641> StarGAN StarGAN是CVPR2018 ...
- Java自学-类和对象 包
Java中的 包 包: package 把比较接近的类,规划在同一个包下 步骤 1 : 把比较接近的类,规划在同一个包下 Hero,ADHero 规划在一个包,叫做charactor(角色) Item ...
- Python进阶----索引原理,mysql常见的索引,索引的使用,索引的优化,不能命中索引的情况,explain执行计划,慢查询和慢日志, 多表联查优化
Python进阶----索引原理,mysql常见的索引,索引的使用,索引的优化,不能命中索引的情况,explain执行计划,慢查询和慢日志, 多表联查优化 一丶索引原理 什么是索引: 索引 ...
- Boleto 银行付款
Boleto是由多家巴西银行共同支持的一种支付方式,在巴西占据绝对主导地位,客户可以到巴西任何一家银行.ATM机.caipiao网点或使用网上银行授权银行转账. 该支付渠道有如下特点:1. 一旦付款, ...