1.情景展示
如上图所示,该页面上的表格统计内容,需要增加一个导出功能,即:
将表格内容导出Excel当中。
如何实现?
2.具体分析
2.1传统解决方案
针对excel导出,有两种解决方式。
思路一:前端导出
如果仅仅是导出当前页数据的话,我们完全可以不与后台进行交互。
因为现有数据已经拿到了,只需要前端将HTML片段转成EXCEL文件,完成下载就可以了。
思路二:后端导出
由于前端往往展示的只是当前页的内容,而实际需求往往是,我们要导出所有符合查询条件的数据。
这样一来,我们就只能通过后端来生成EXCEL文件,并且,将该文件以流的形式返回给前端。
浏览器检测到,会自动下载服务器返回的excel文件。
2.2另类解决办法
如果你的页面使用的不是HTML而是JSP进行开发的话,我们完全可以使用JSP来实现数据转EXCEL的操作。
这样一来,就大大减轻了后端的工作量,也比较省心。
3.解决方案
前提:页面的展示使用JSP进行开发,而不是HTML。
具体实现流程如下:
JS代码
//导出
function exportExcel(){
var begin = document.getElementById("begindata").value;
var end = document.getElementById("enddata").value;
var myselect = document.getElementById("ORG_CODE");
var orgcode = myselect.options[myselect.selectedIndex].value;
var param = "begindata=" + begin +"&enddata=" + end + "&ORG_CODE=" + orgcode
window.open(baseUrl + "/ycyl/xd/api/orgDateExcel.do?" + param, "_self");
}
页面导出按钮,调用该函数,使用js打开一个新的标签,发送获取数据的请求。
HTML代码
<input id="exportButton" onm ouseover="javascript:this.className='ButtonOver'" onm ouseout="javascript:this.className='Button'"
value="导出" class="Button" type="button" onclick="javascript:exportExcel()" />
Controller代码
<action name="orgDataExcel" class="ycyl.web.actions.xd.XdApiAction" method="viewListOrgTsCount">
<result name="success" type="dispatcher">/ycyl/xd/jk/statistics/orgExcel.jsp</result>
</action>
这里使用的是struts2当做控制层。
该请求经过后台调用viewListOrgTsCount()方法后,会自动转发到orgExcel.jsp页面。
JAVA代码(viewListOrgTsCount方法具体内部实现)
public String viewListOrgTsCount() {
try{
Map map = WebUtils.getParameterMapWithPage();
String ORG_CODE = map.get("ORG_CODE").toString();
String[] ORG_CODES = ORG_CODE.split(",");
map.put("ORG_CODES", ORG_CODES);
if(!map.get("enddata").toString().isEmpty() ){
String begin = map.get("begindata").toString();
String end = map.get("enddata").toString();
map.put("begin", begin + " 00:00:00");
map.put("abort", end + " 23:59:59");
}
List<Map> list = boXdApi.getOrgXDTsCount(map);
// 返回的数据
model.put("data", list);
// 获取到Response对象
HttpServletResponse response = WebUtils.getResponse();
// 设置文件名
String wjm = "orgcode.xls";
// 告诉浏览器,返回的是.xls格式数据,以及文件的字符集
response.setContentType( "application/vnd.ms-excel;charset=UTF-8");
// 告诉浏览器,该文件的文件名
response.setHeader("content-disposition","attachment; filename=" +wjm );
} catch (Exception e) {
this.code = -1;
this.msg = e.getMessage();
this.expMsg = getExceptionMessage(e);
log.error(e.getMessage());
}
return "success";
}
JSP代码
<%@page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name=ProgId content=Excel.Sheet>
<meta name=Generator content="Microsoft Excel 11">
<link rel=File-List href="Book1.files/filelist.xml">
<link rel=Edit-Time-Data href="Book1.files/editdata.mso">
<link rel=OLE-Object-Data href="Book1.files/oledata.mso">
<title>机构统计数据导出</title>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
</head>
<body>
<table cellspacing="0" cellpadding="1" border="0" width="100%" height="100%">
<tbody>
<tr align="center">
<td>医疗机构</td>
<td>总数</td>
</tr>
<c:forEach var="row" items="${model.data}" varStatus="s">
<tr align="center">
<td>${row.ORGNAME}</td>
<td>${row.COUNT}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
当控制层,跳转到orgExcel.jsp页面时,所携带的数据,会回填到该页面。
最后,经tomcat将jsp转servlet,响应给浏览器的将是html网页。
而,我们已经通过后台Response,告诉浏览器它是一个excel文件,浏览器将自动将该网页当做一个EXCEL文件来下载。
3.测试
我们来到页面上,点击导出按钮,浏览器会自动下载一个excel格式的文件。
我们打开它,如果你是用的微软的excel工具打开,就会报如下错误:
但是,如果使用的是WPS打开的话,不会报错。
点击“是” ,就能正常打开啦。
4.扩展
这个XLS格式的excel文件,其实是一个HTML网页。
我们一起来看一下。
选中刚才下载的该文件,右键使用Notepad++打开。
我们可以看到,这完全就是一个html网页。
只不过是将JSP相关的代码给剔除了(JSP-->SERVLET-->HTML)。
需要说明的有三点:
第一,关于JSP页面。
<HEAD>标签里面的内容,需要全部携带。
不要使用外部CSS样式,即使用了,导出的EXCEL文件,样式就是默认样式,因为在网页当中,它可以获取到服务器的外部样式文件,当你下载到本地后,将无法引用服务器的CSS文件。
使用纯粹的HTML标签和属性就可以了。
最简单的方式,就是:
只将<BODY>标签当中内容,删掉,替换成你的HTML片段就可以啦。
第二点,关于控制层。
如果,你不想在控制层添加response对象,也是可以的。
可以在JSP头部添加小脚本:
<%
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-disposition","attachment; filename=orgcode.xls");
%>
其实现效果是一样的。
第三,仅支持XLS格式。
使用JSP导出EXCLE,仅仅支持.XLS,不支持.XLSX。
如果我们强行返回XLSX,将无法打开此文件。
写在最后
哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!