WEB下载数据量大的EXCEL解决方案

思路:需要2次请求,第一次ajax请求把数据查询出来,按照1000条数据一个sheet,在后台生成临时文件,并把文件名称返回给web,第二次请求直接下载临时文件下载完成后,删除临时文件

代码如下web端:

// 导出
function cmd_toExcel() {
	$.messager.progress({ 
	    title: '请等待', 
	    msg: "<span style='color:green'>人生若只如初见</span>", 
	    text: '努力下载中.......' 
	});
	$.ajax({
		type : "post",
		url : cmd.toexport,
		data : formToObject('.searchBox'),
		dataType : "json",
		success : function(data) {
	     location.href = _ctx + "/rest/download/getfile?name=" + data + "&originFileName=" + "车辆统计.xls";
			$.messager.progress('close');
		}
	});
}

 后台服务端,生成临时文件接口:

/**
	 * 导出
	 * 
	 * @throws Exception
	 */
	@RequestMapping(value = "/toexport", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public String export(HttpServletRequest request, String area, Integer trans, String org, String no,
			AnalysisDate analysisdate, @RequestParam(required = false, defaultValue = "VEH_ID") String sort,
			@RequestParam(required = false, defaultValue = "asc") String order) throws Exception {
		Pageable pageable = new PageRequest(0, 1000000, new Sort("asc".equalsIgnoreCase(order) ? Direction.ASC
				: Direction.DESC, sort, "VEH_ID"));
		List<Map<String, Object>> list = manager.statistics(area, trans, org, no, analysisdate,
				SpringSecurityUtils.getCurrentUserArea(), pageable).getContent();
		String title = "车辆统计表";
		String[] rowsName = new String[] {"序号", "道路运输证号", "车牌", "企业名称", "所属区域", "运输行业分类", "车辆类型", "上线时长", "断开时长", "报警次数"};
		List<Object[]> dataList = new ArrayList<Object[]>();
		Object[] objs = null;
		for (int i = 0; i < list.size(); i++) {
			Map<String, Object> man = list.get(i);
			objs = new Object[rowsName.length];
			objs[0] = i;
			objs[1] = man.get("RTPN");
			objs[2] = man.get("VEH_ID") == null ? "" : man.get("VEH_ID");
			objs[3] = man.get("ORG_NAME") == null ? "" : man.get("ORG_NAME");
			objs[4] = man.get("AREANAME");
			objs[5] = man.get("TRANS_TYPE");
			objs[6] = man.get("VTYPE");
			objs[7] = durationFormatter(((BigDecimal)man.get("ONLINE_TIME")).intValue());
			objs[8] = durationFormatter(((BigDecimal)man.get("OFF_TIME")).intValue());
			objs[9] = man.get("WARN_AMOUNT");
			dataList.add(objs);
		}
		ExportExcel ex = new ExportExcel(title, rowsName, dataList, request);
		return ex.export();
	}
package com.wttech.gnss.utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.hssf.util.HSSFColor;

/**
 * 导出Excel公共方法
 * 
 *
 */
public class ExportExcel {

	// 显示的导出表的标题
	private String title;

	// 导出表的列名
	private String[] rowName;

	private List<Object[]> dataList = new ArrayList<Object[]>();

	HttpServletRequest request;

	// 构造方法,传入要导出的数据
	public ExportExcel(String title, String[] rowName, List<Object[]> dataList, HttpServletRequest request) {
		this.request = request;
		this.dataList = dataList;
		this.rowName = rowName;
		this.title = title;
	}

	/*
	 * 导出数据
	 */
	@SuppressWarnings("deprecation")
	public String export() throws Exception {
		String uuid = "/temp_" + UUID.randomUUID().toString() + ".xls";
		String filename = Properties.UPLOAD_ADDRESS + uuid;
		try {
			HSSFWorkbook workbook = new HSSFWorkbook(); // 创建工作簿对象
			int sheets = dataList.size() / 50000 + 1;
			for (int m = 0; m < sheets; m++) {
				HSSFSheet sheet = workbook.createSheet(title + m); // 创建工作表

				// 产生表格标题行
				HSSFRow rowm = sheet.createRow(0);
				HSSFCell cellTiltle = rowm.createCell(0);

				// sheet样式定义【getColumnTopStyle()/getStyle()均为自定义方法 - 在下面 - 可扩展】
				HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);// 获取列头样式对象
				HSSFCellStyle style = this.getStyle(workbook); // 单元格样式对象
				HSSFCellStyle headerStyle = getHeaderStyle(workbook);
				sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (rowName.length - 1)));
				cellTiltle.setCellStyle(headerStyle);
				cellTiltle.setCellValue(title);
				// 定义所需列数
				int columnNum = rowName.length;

				HSSFRow rowRowName = sheet.createRow(2); // 在索引3的位置创建行(最顶端的行开始的第3行)

				// 将列头设置到sheet的单元格中
				for (int n = 0; n < columnNum; n++) {
					HSSFCell cellRowName = rowRowName.createCell(n); // 创建列头对应个数的单元格
					cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING); // 设置列头单元格的数据类型
					HSSFRichTextString text = new HSSFRichTextString(rowName[n]);
					cellRowName.setCellValue(text); // 设置列头单元格的值
					cellRowName.setCellStyle(columnTopStyle); // 设置列头单元格样式
				}

				// 将查询出的数据设置到sheet对应的单元格中
				List<Object[]> sub = dataList.subList(m * 50000, (m + 1) * 50000 < dataList.size() ? (m + 1) * 50000
						: dataList.size());
				for (int i = 0; i < sub.size(); i++) {

					Object[] obj = sub.get(i);// 遍历每个对象
					HSSFRow row = sheet.createRow(i + 3);// 创建所需的行数

					for (int j = 0; j < obj.length; j++) {
						HSSFCell cell = null; // 设置单元格的数据类型
						if (j == 0) {
							cell = row.createCell(j, HSSFCell.CELL_TYPE_NUMERIC);
							cell.setCellValue(i + 1);
						} else {
							cell = row.createCell(j, HSSFCell.CELL_TYPE_STRING);
							if (obj[j] != null) {
								cell.setCellValue(obj[j].toString()); // 设置单元格的值
							} else {
								cell.setCellValue(""); // 设置单元格的值
							}
						}
						cell.setCellStyle(style); // 设置单元格样式
					}
				}
				// 让列宽随着导出的列长自动适应
				for (int colNum = 0; colNum < columnNum; colNum++) {
					switch (colNum) {
					case 0:
						sheet.setColumnWidth(colNum, 6 * 256);
						break;
					default:
						sheet.setColumnWidth(colNum, 20 * 256);
						break;
					}

				}

			}
			if (workbook != null) {
				try {
					File file = new File(filename);
					// 以流的形式下载文件。
					BufferedOutputStream fis = new BufferedOutputStream(new FileOutputStream(file));

					workbook.write(fis);
					fis.flush();// 刷新流
					fis.close();// 关闭流
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return uuid;
	}

	/*
	 * 表头单元格样式
	 */
	public HSSFCellStyle getHeaderStyle(HSSFWorkbook workbook) {

		// 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体大小
		font.setFontHeightInPoints((short) 11);
		// 字体加粗
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Courier New");
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		return style;

	}

	/*
	 * 表头单元格样式
	 */
	public HSSFCellStyle getRightStyle(HSSFWorkbook workbook) {

		// 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体大小
		font.setFontHeightInPoints((short) 11);
		// 字体加粗
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Courier New");
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		return style;

	}

	/*
	 * 列头单元格样式
	 */
	public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {

		// 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体大小
		font.setFontHeightInPoints((short) 11);
		// 字体加粗
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Courier New");
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 设置底边框;
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		// 设置底边框颜色;
		style.setBottomBorderColor(HSSFColor.BLACK.index);
		// 设置左边框;
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		// 设置左边框颜色;
		style.setLeftBorderColor(HSSFColor.BLACK.index);
		// 设置右边框;
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		// 设置右边框颜色;
		style.setRightBorderColor(HSSFColor.BLACK.index);
		// 设置顶边框;
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		// 设置顶边框颜色;
		style.setTopBorderColor(HSSFColor.BLACK.index);
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		return style;

	}

	/*
	 * 表头单元格样式
	 */
	public HSSFCellStyle getFootStyle(HSSFWorkbook workbook) {

		// 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体大小
		font.setFontHeightInPoints((short) 11);
		// 字体加粗
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Courier New");
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		return style;

	}

	/*
	 * 列数据信息单元格样式
	 */
	public HSSFCellStyle getStyle(HSSFWorkbook workbook) {
		// 设置字体
		HSSFFont font = workbook.createFont();
		// 设置字体大小
		// font.setFontHeightInPoints((short)10);
		// 字体加粗
		// font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 设置字体名字
		font.setFontName("Courier New");
		// 设置样式;
		HSSFCellStyle style = workbook.createCellStyle();
		// 设置底边框;
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		// 设置底边框颜色;
		style.setBottomBorderColor(HSSFColor.BLACK.index);
		// 设置左边框;
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		// 设置左边框颜色;
		style.setLeftBorderColor(HSSFColor.BLACK.index);
		// 设置右边框;
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		// 设置右边框颜色;
		style.setRightBorderColor(HSSFColor.BLACK.index);
		// 设置顶边框;
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		// 设置顶边框颜色;
		style.setTopBorderColor(HSSFColor.BLACK.index);
		// 在样式用应用设置的字体;
		style.setFont(font);
		// 设置自动换行;
		style.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 设置垂直对齐的样式为居中对齐;
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		return style;

	}
}

接口2下载临时文件,并删除

@RequestMapping(value = "/getfile")
	@ResponseBody
	public void getfile(HttpServletRequest request,HttpServletResponse response,String name,String originFileName) throws ParseException {
		String path =  Properties.UPLOAD_ADDRESS + name ;
		File file = new File(path);
		// 以流的形式下载文件。
		InputStream fis;
		try {
			fis = new BufferedInputStream(new FileInputStream(path));
			
			byte[] buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
			response.reset();
			response.addHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(originFileName, "UTF-8"));
			response.setCharacterEncoding("utf-8");
			response.addHeader("Content-Length", "" + file.length());
			OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
			response.setContentType("application/octet-stream");
			
			toClient.write(buffer);
			toClient.flush();
			toClient.close();
			if (name.contains("temp")) {
				file.delete();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

转载于:https://my.oschina.net/chuibilong/blog/845053

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值