导出excel需要用到aiexcel-1.4.jar包,这个jar包是公司项目中现有的。
原有的大数据分析中心,导出功能仅实现了固定10000条记录的单表excel导出。现在根据最新需求,要求导出全部的数据(多的有几百万条)。将全部数据按每10000条数据分割成n个excel表格导出显然不现实,想到这里,出现2中解决办法:
(一) 将全部数据按10000条/sheet 分割装在一个excel表中;
(二) 按10000条/excel表分割成多个excel表,并压缩成zip包供用户下载
分析:
10000条数据的excel表格就已经有5-6M了,若是按第一种方法导出数据,遇到大量数据,比如300W条左右,一个excel表就有1G以上了,先不说excel能不能打开这个文件,就算能,光打开估计就得一天,因此排除第一种方法;第二种方法,假如需要导出300W条数据,会分割为300张excel表格,压缩到zip包中,压缩后的zip包也不到500M的样子,大大减少了文件大小。毕竟,虽然在导出后,会在服务器路径下删除文件,但是在导出过程中,是先将文件放在服务器路径下,再开IO流传到网络的,也减轻了服务器的压力。因此,选择第二种方式。
关键实现代码:
1.前端js导出代码:
//获取资源详情总数目
var dataCountPath = CONTEXT_PATH+"/intelligence/getIntelligenceTestCount";
//获得json格式的参数
function getQueryParams(){
return JSON.stringify({provinceCode:$("#provinceCode").val(),cityCode:$("#cityCode").val(),schoolCode:$("#schoolCode").val(),startDate:$("#startDate").val(),endDate:$("#endDate").val(),"page":page,"rows":rows});
}
//开始点击页面导出按钮,导出开始
$(".btn.btn-red").bind("click",function(){
doExport()});
function doExport()
{
//****导出开始*****
var query_params = getQueryParams();
//资源总数默认为0
var dataCounts = 0;
//在本次项目中设置的每张excel表中最大存放10000条记录
var excelSize = 10000;
$.ajax({
url : dataCountPath,
type : "POST",
async: false,
dataType:'json',
contentType :"application/json",
data:query_params,
success : function(data) {
dataCounts = parseInt(data.total);
},
error:function(XMLHttpRequest, textStatus, errorThrown){
}
});
if(dataCounts){
$(".btn.btn-red").attr("disabled",true);
//浏览器显示下载的文件名
var realFileName = encodeURIComponent(encodeURIComponent("智能测验统计"+".zip"));
//每张excel表的名字
var excelName = encodeURIComponent(encodeURIComponent("智能测验统计-"));
//导出链接,自带参数,最重要的就是reportId,format,realFileName,dataCounts,excelName,excelSize
var url = CONTEXT_PATH+"/Report?reportId=intelligenceExport&format=excel&";
window.location.href = url + $.param({provinceCode:$("#provinceCode").val(),cityCode:$("#cityCode").val(),schoolCode:$("#schoolCode").val(),startDate:$("#startDate").val(),endDate:$("#endDate").val(),"page":page,"rows":rows}) + "&realFileName=" + realFileName+"&dataCounts="+dataCounts+"&excelName="+excelName+"&excelSize="+excelSize;
$(".btn.btn-red").attr("disabled",false);
}else{
$(".btn.btn-red").attr("disabled",false);
$.messager.alert(PageI18n.tip, "导出内容不能为空");
}
//****导出结束*****
}
2.前端跳转到aiexcel-1.4.jar中的AiReportServlet.class。这里要在web.xml中配置下才会生效
web.xml配置如下:
<servlet>
<servlet-name>AiReportServlet</servlet-name>
<servlet-class>com.tianwen.eeducation.aireport.servlet.AiReportServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AiReportServlet</servlet-name>
<url-pattern>/Report/*</url-pattern>
</servlet-mapping>
3.通过web.xml中的配置,会跳转到AiReportServlet.class。进行导出处理。如下:
package com.tianwen.eeducation.aireport.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.tianwen.eeducation.aireport.ReportRunner;
import com.tianwen.eeducation.aireport.XmlReportRunner;
import com.tianwen.eeducation.aireport.xml.ExportService;
import com.tianwen.eeducation.aireport.xml.XmlConfigUtil;
/**
* 客户端服务分发类;
*
* @version [版本号, 2014-3-13]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class AiReportServlet extends HttpServlet
{
/**
*
*/
private static final long serialVersionUID = 1L;
private static Logger log = Logger.getLogger(AiReportServlet.class);
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String reportId = request.getParameter("reportId");
// 如果XML里有配置,则优先去使用XML方式
ExportService exportService = XmlConfigUtil.xmlConfigMap.get(reportId);
if (exportService != null && exportService.isOpenExport())
{
XmlReportRunner xmlRunner = new XmlReportRunner(exportService);
xmlRunner.create(request);
try
{
xmlRunner.run(request, response);
}
catch (Exception e)
{
log.error("报表生成出错(XML配置)"+e.getMessage());
e.printStackTrace();
}
}
else
{
ReportRunner runner = new ReportRunner();
runner.create(request);
try
{
runner.run(request, response);
}
catch (Exception e)
{
log.error("报表生成出错"+e.getMessage());
e.printStackTrace();
}
}
}
}
ReportRunner类为自定义扩展的:
/**
* This software is under the license of GNU Lesser General Public License(LGPL).
* You may obtain a copy of the License at
* http://www.gnu.org/copyleft/lesser.html.
*/
package com.tianwen.eeducation.aireport;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;