在数据库中查询超大批量数据并个性化生成Excel
设计需求,能支持在数据库中查询上千万的数据并按照设计生成想要的Excel。
这儿选用的框架是poi,这是一款非常好用的生成Excel的框架,最新的SXSSFWorkbook已经支持,当超过设定的查询条数时候,自动写入硬盘中,减少了内存负担,且能很好的支持大批量数据转换为Excel。
本代码设计查询一千万条数据,每100万作为一个Sheet(poi在一个sheet中最高上限一百万),每次在数据库中查询1万(在数据库中不能一次查询条数过多,对内存压力过大)条数据。
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
public class ExcleUtil {
public void CreateExcleBIG(String fileName) throws ServletException, IOException {
Map<String, String> b = new HashMap<String, String>();
String savePath = "/home/text/downloads/";
if (!new File(savePath).isDirectory()) {
new File(savePath).mkdirs();
}
String oldds = DynamicDataSourceContextHolder.getDataSourceType();
DynamicDataSourceContextHolder.setDataSourceType("shandong1"); //切换数据源
try {
SXSSFWorkbook wb = new SXSSFWorkbook(10000); // 在内存当中保持 10000 行 ,
// 超过的数据放到硬盘中
int number = downloadMapper.getNumber();//获得查询数据的总条数,这儿为1000万
Map<String, Object> getNumber = new HashMap<String, Object>();
File outputFile = new File(savePath + fileName + ".xlsx");
// 创建文件
outputFile.createNewFile();
FileOutputStream out = new FileOutputStream(savePath + fileName + ".xlsx");
int p = 1;
int i = 0;
Sheet sh;
while (i < number) {
int yyy = 1;
sh = wb.createSheet("分表" + p);
Row row = sh.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("月份");
cell = row.createCell(1);
cell.setCellValue("编码");
cell = row.createCell(2);
cell.setCellValue("地市");
cell = row.createCell(3);
cell.setCellValue("用户编码");
while (yyy < 1000000 && i < number) {
int pagebegin = i + 1;
getNumber.put("pagebegin", pagebegin + "");
int pageend = i + 10000;
getNumber.put("pageend", pageend + "");
//数据库中查询数据,每次1万
List<Map<String, Object>> m = downloadMapper.getListByNumber(getNumber);
for (Map<String, Object> map : m) {
row = sh.createRow(yyy);
cell = row.createCell(0);
cell.setCellValue((String) map.get("MONTH_ID"));
cell = row.createCell(1);
cell.setCellValue((String) map.get("EPARCHY_CODE"));
cell = row.createCell(2);
cell.setCellValue((String) map.get("AREA_DESC"));
cell = row.createCell(3);
cell.setCellValue((String) map.get("USER_ID"));
yyy++;
i++;
}
}
System.out.println(i + " " + yyy);
p++;
}
wb.write(out);
out.close();
// dispose of temporary files backing this workbook on disk
wb.dispose();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
DynamicDataSourceContextHolder.setDataSourceType(oldds);
}
}
}