POI 提供了对2003版本的Excel的支持 ---- HSSFWorkbook
POI 提供了对2007版本以及更高版本的支持 ---- XSSFWorkbook
只有2007版的才能导出百万级别的数据2003只能到处20多万的数据
Controllerc层
/**
* 根据日期打印Excel表格
*
* @param endTime
* @param startTime
* @param startTime 1:到处惠州 2:深圳 3:总表
* @param userName 客户代码
* @param type 1:导出惠州 2:深圳 3:总表
* @param exportType 导出类型 1:是到处明细 2:是导出总表 (默认是导出总表)
* @param mobileOperator 所属移动商 1:北京移动 2:江门移动 TODO 查看明细的这个字段变为Integer类型
*/
@GetMapping("/exportExcel.json")
public void exportExcel(String endTime, String startTime, HttpServletResponse response, Integer type, String userName,
Integer exportType, Integer mobileOperator) {
//当wb中的数据大于或等于20000条会暂时放在内存中,写完后会自动删除
SXSSFWorkbook wb = new SXSSFWorkbook(20000);
// 存储要导入的记录
List<CountNewCard> countNewCardList = new LinkedList<>();
boolean flag = true;
while (flag) {
//每次只查询20000条数据
List<CountNewCard> list = importExcelService.exportHZExcel(endTime + Consts.time[0],
startTime + Consts.time[1], type, page, userName, mobileOperator);
page++;
if (!CollectionUtils.isEmpty(list)) {
countNewCardList.addAll(list);
//如果不满20000条说明已经查询完毕
if (list.size() < Consts.numberOfDbs) {
flag = false;
}
list.clear();
} else {
flag = false;
}
}
if (CollectionUtils.isEmpty(countNewCardList)) {
log.info("无数据");
return;
}
//导出方法
if (type == 0) {
importExcelCommon.exportExcel(countNewCardList, wb, Consts.dataType.get(0), exportType);
} else if (type == 1) {
importExcelCommon.exportExcel(countNewCardList, wb, Consts.dataType.get(1), exportType);
} else {
importExcelCommon.exportExcel(countNewCardList, wb, Consts.dataType.get(2), exportType);
}
try {
export.export(Consts.exportTip, response, wb, 0);
} catch (IOException e) {
return;
}
long time1 = System.currentTimeMillis() - time;
log.info("花费的时间" + time1);
}
service层
/**
* 明细分期导出
*
* @param exportList
* @param wb
* @param name
*/
public void exportExcel(List<CountNewCard> exportList, SXSSFWorkbook wb, String name,
Integer exportType) {
log.info("开始写入信息");
for (CountNewCard list : exportList) {
t++;
//逻辑操作省列
if (i1 > 1000000) {
try {
//因为文件最多写100多万行,所以大于100万行就换也,只要wb对象一样他们就是卸载同一个文件
Sheet sheet = wb.createSheet("table" + sum1);
if (i1 == exportList.size()) {
} else {
//用于导出的方法
exportExcel.exportExcel(listList, wb, sheet, 1);
sum1++;
}
listList.clear();
i1 = 0;
log.info("一页的总条数" + i1);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
导出的方法
/**
* 汇总表后把数据冲数据库中导出
*
* @param list1
* @param wb
* @param sheet
* @param list1
* @param type1
* @param wb
* @param sheet
* @param type1 是到处明细 否则到处总表
* @throws IOException
*/
public void exportExcel(List<CountNewCard> list1,
Workbook wb, Sheet sheet, Integer type1) throws IOException {
//导出前进行按照出货日期进行排序
list1.sort(Comparator.comparing(CountNewCard::getShippingDate));
Row row;
Cell cell;
if (type1 == 1) {
Object[][] datas = {{"", "", "", "", "", "区分新开卡、续费、叠加包、套餐变更", "",
"公司出货给客户的时间", "", "", "", ""}
, {"账务日期", "客户归属", "客户代码", "规格", "卡号", "年限", "卡类型", "所属移动商",
"收入金额", "成本金额(移动)", "毛利", "毛利率"}};
for (int i = 0; i < datas.length; i++) {
//创建表格行
row = sheet.createRow(i);
for (int j = 0; j < datas[i].length; j++) {
//根据表格行创建单元格
cell = row.createCell(j);
cell.setCellValue(String.valueOf(datas[i][j]));
CellStyle cellStyle = wb.createCellStyle();
// 居中
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//设置自动换行
cellStyle.setWrapText(true);
//用于设置样式
// if (i == 1) {
// if (j == 1 || j == 7 || j == 8 || j == 11) {
// //bgIndex 背景颜色下标值
// cellStyle.setFillForegroundColor(HSSFColor.RED.index);
// cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
// }
// if (j == 2) {
// //bgIndex 背景颜色下标值
// cellStyle.setFillForegroundColor(HSSFColor.YELLOW.index);
// cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
// }
// }
cell.setCellStyle(cellStyle);
//创建表格之后设置行高与列宽
row.setHeightInPoints(50);
for (int j1 = 0; j1 < datas[0].length; j1++) {
sheet.setColumnWidth(j1, MSExcelUtil.pixel2WidthUnits(160));
}
}
}
int sum = datas.length - 1;
//根据表格行创建单元格
int s = 0;
CellStyle cellStyle = wb.createCellStyle();
// 居中
cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
//设置自动换行
cellStyle.setWrapText(true);
for (CountNewCard list : list1) {
s++;
//创建表格行
row = sheet.createRow(++sum);
// CountNewCard countNewCard = list.get(i);
int j = 0;
//账务日期
cell = row.createCell(j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getShippingDate());
//客户归属
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getCustomerAttribution());
//客户代码
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getUserName());
//规格
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getSpecifications());
//卡号
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getSim());
//年限
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getYears());
//卡类型
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getType());
//所属移动商
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getMobileOperator());
//收入金额
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getAmountIncome());
//成本金额(移动)
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getCostSumOfCompany());
//毛利
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getGrossProfit());
//毛利率
cell = row.createCell(++j);
cell.setCellStyle(cellStyle);
cell.setCellValue(list.getGrossProfitMargin());
//用于设置样式
//创建表格之后设置行高与列宽
row.setHeightInPoints(25);
for (int j1 = 0; j1 < datas[0].length; j1++) {
sheet.setColumnWidth(j1, MSExcelUtil.pixel2WidthUnits(160));
}
// log.info("写入的行数" + s);
}
}
把文件变成流在浏览器中进行下载
/**
* 用于最后的导出
*
* @param fileName
* @param response
* @param wb
* @param type
*/
public void export(String fileName, HttpServletResponse response, SXSSFWorkbook wb, Integer type) throws IOException {
if (type == 1) {
loadResponse(fileName, response, wb, ".xls");
} else {
loadResponse(fileName, response, wb, ".xlsx");
}
}
/**
* 下载导出excel的流
*
* @param excelName
* @param response
* @param wb
* @throws IOException
*/
private void loadResponse(String excelName, HttpServletResponse response, Workbook wb, String type) throws IOException {
//到这里,excel就已经生成了,然后就需要通过流来写出去
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//将excel写入流
wb.write(byteArrayOutputStream);
//设置文件标题
String dateTime = DateUtils.dateToStr( "yyyyMMddHHmm",new Date());
// String outFile = excelName + dateTime + ".xls";
String outFile = excelName + dateTime + type;
//设置返回的文件类型
response.setContentType("application/vnd.ms-excel;charset=utf-8");
//对文件编码
outFile = response.encodeURL(new String(outFile.getBytes("gb2312"), "iso8859-1"));
//使用Servlet实现文件下载的时候,避免浏览器自动打开文件
response.addHeader("Content-Disposition", "attachment;filename=" + outFile);
//设置文件大小
response.setContentLength(byteArrayOutputStream.size());
//创建Cookie并添加到response中
Cookie cookie = new Cookie("fileDownload", "true");
cookie.setPath("/");
response.addCookie(cookie);
//将流写进response输出流中
ServletOutputStream outputstream = response.getOutputStream();
byteArrayOutputStream.writeTo(outputstream);
byteArrayOutputStream.close();
outputstream.flush();
}