SSM+mybatis数据库实现百万数据分页取出并分页插入Excel中

刚开始的情况是一条sql语句将数据库中的所有数据一次全部查询出来,每一条放到一个map中,最后放在list中,刚开始写的代码由于数据不多,没出现问题,后来数据达到百万后,客服在导出数据的时候直接内存溢出,于是开始查找原因,最后找到,在查询数据把数据放到map的过程中,会占用内存,百万的数据想想也是醉了,于是重新sql语句,自定义分页,查一次数据将数据插入一次Excel中,分页查询数据很好实现,在分页插入Excel这竟然被卡了足足一天,蛋疼。。。。

Excel插入数据选用的xlsx,支持插入100万多点数据,xls就不行了。上一个测试类代码:

package com.hyfd.test;
/**
 * 功能:测试Excel中数据的插入
 * @author yinguichun
 */
import java.io.File;
import java.io.FileInputStream;    
import java.io.FileOutputStream;    
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
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.poifs.filesystem.POIFSFileSystem;  
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class TestExceLAppend {
	static XSSFWorkbook wbb = new XSSFWorkbook();
    public static void main(String[] args) throws Exception {  
//    	testXlsAppend();
    	String fname="d://test7.xlsx";
    	fastWrite(fname,SetDate());
    	for(int i=0;i<5;i++){
    		testXlsxAppend(fname,wbb);
    	}
    }
   /**
    * 编造的符合项目的数据
    * @return
    */
    public static Map  SetDate(){
    	String[][] agentData = new String[5+1][6];
		agentData[0][0] = "手机号";
		agentData[0][1] = "SIM号";
		agentData[0][2] = "激活时间";
		agentData[0][3] = "卡状态";
		agentData[0][4] = "账户余额";
		agentData[0][5] = "月累计消费";

		for (int i = 0; i < 5; i++) {
				agentData[i + 1][0] = "1";
				agentData[i + 1][1] = "2";
				agentData[i + 1][2] = "3";
				agentData[i + 1][3] = "4";
				agentData[i + 1][4] = "5";
				agentData[i + 1][5] = "6";
			
		}
		Map m = new HashMap();
		m.put("pikaiData", agentData);
		return m;
    }
    
    /**
     * 将数据写入xls中
     * @param wbb
     * @throws Exception
     */
    public static void testXlsAppend(XSSFWorkbook wbb) throws Exception{
    	String fname="d://test.xls";
        FileInputStream fs=new FileInputStream(fname);  //获取d://test.xls  
        POIFSFileSystem ps=new POIFSFileSystem(fs);  //使用POI提供的方法得到excel的信息  
        HSSFWorkbook wb=new HSSFWorkbook(ps);    
        HSSFSheet sheet=wb.getSheetAt(0);  //获取到工作表,因为一个excel可能有多个工作表  
        HSSFRow row=sheet.getRow(0);  //获取第一行(excel中的行默认从0开始,所以这就是为什么,一个excel必须有字段列头),即,字段列头,便于赋值  
        System.out.println(sheet.getLastRowNum()+" "+row.getLastCellNum());  //分别得到最后一行的行号,和一条记录的最后一个单元格  
          
        FileOutputStream out=new FileOutputStream(fname);  //向d://test.xls中写数据  
        row=sheet.createRow((short)(sheet.getLastRowNum()+1)); //在现有行号后追加数据  
        row.createCell(0).setCellValue("ttttaaa1"); //设置第一个(从0开始)单元格的数据  
        row.createCell(1).setCellValue(24); //设置第二个(从0开始)单元格的数据
        
        out.flush();  
        wb.write(out);    
        out.close();    
        System.out.println(row.getPhysicalNumberOfCells()+" "+row.getLastCellNum()); 
    }
    
    /**
     * 将数据写入Xlsx中
     * @param fname
     * @param wbb
     * @throws Exception
     */
    public static void testXlsxAppend(String fname,XSSFWorkbook wbb) throws Exception{
    	FileInputStream fis=new FileInputStream(new File(fname));
		// 工作区
    	wbb = new XSSFWorkbook(fis); 
		XSSFSheet sheet =  wbb.getSheetAt(0);
		XSSFRow row=(XSSFRow) sheet.getRow(0);  //获取第一行(excel中的行默认从0开始,所以这就是为什么,一个excel必须有字段列头),即,字段列头,便于赋值  
        System.out.println(sheet.getLastRowNum()+" "+row.getLastCellNum());  //分别得到最后一行的行号,和一条记录的最后一个单元格 
        
        FileOutputStream os=new FileOutputStream(fname);  //向d://test.xls中写数据  
        row=(XSSFRow) sheet.createRow((short)(sheet.getLastRowNum()+1)); //在现有行号后追加数据  
        row.createCell(0).setCellValue("vvvvvaaa1"); //设置第一个(从0开始)单元格的数据  
        row.createCell(1).setCellValue(88); //设置第二个(从0开始)单元格的数据
        
        wbb.write(os);
        fis.close();
        os.close();    
        System.out.println(row.getPhysicalNumberOfCells()+" "+row.getLastCellNum()); 
    }
    
	/**
	 * 海量数据写入Excel表格
	 * @param fname
	 * @param m
	 * @throws Exception
	 */
	public static void fastWrite(String fname, Map m)
			throws Exception {

		OutputStream os = new FileOutputStream(fname);
		// 工作区
		SXSSFWorkbook wb = new SXSSFWorkbook();
		SXSSFSheet sheet = (SXSSFSheet) wb.createSheet("1");
		for (Map.Entry entry : m.entrySet()) {
			SXSSFRow row = null;
			String[][] sheetData = entry.getValue();
			for (int rowIndex = 0; rowIndex < sheetData.length; rowIndex++) {
				// 创建列时需注意,不要写成固定值

				row = (SXSSFRow) sheet.createRow(rowIndex);
				for (int column = 0; column < sheetData[rowIndex].length; column++) {
					if (sheetData[rowIndex][column] == null) {
						break;
					}
					row.createCell(column).setCellValue(
							sheetData[rowIndex][column]);
				}
			}
		}
		// 写文件
		wb.write(os);
		// 关闭输出流
		os.close();
	}
}

需要几个jar包:

poi-3.12-20150511.jar
poi-3.6-20091214.jar
poi-ooxml-3.12-20150511.jar
poi-ooxml-schemas-3.12-20150511.jar
poi-scratchpad-3.12-20150511.jar
xmlbeans-2.6.0.jar

下载地址



你可能感兴趣的:(SSM+mybatis数据库实现百万数据分页取出并分页插入Excel中)