POI操作Excel2007实例二之“SXSSFWorkbook”处理海量数据
2012-12-06 17:51
411 查看
前文链接:POI实现读写Excel2007完整示例--每分钟约处理7000行数据
前文讲述了 POI 读取的基本操作,但后期 经过试验,当写入数据量超过5万条以上时,
很容易报错“内存溢出”,就算你调整JVM的xmx为 “2048MB”,也无效果。
后来查资料得知 SXSSFWorkbook 是专门用来处理大量数据写入 Excel2007的问题的。
实例如下,具体步骤神马的,请看前文。
读取仍然是“XSSFWorkbook”,写入则为“SXSSFWorkbook ”。
经试验 写入处理速度在 7000行左右,根据 Excel文件大小 会上下浮动。
Config.java
前文讲述了 POI 读取的基本操作,但后期 经过试验,当写入数据量超过5万条以上时,
很容易报错“内存溢出”,就算你调整JVM的xmx为 “2048MB”,也无效果。
后来查资料得知 SXSSFWorkbook 是专门用来处理大量数据写入 Excel2007的问题的。
实例如下,具体步骤神马的,请看前文。
读取仍然是“XSSFWorkbook”,写入则为“SXSSFWorkbook ”。
经试验 写入处理速度在 7000行左右,根据 Excel文件大小 会上下浮动。
Config.java
package com.excel.poi.gz10000; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; 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 org.apache.log4j.PropertyConfigurator; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** * <b> 数据匹配</b> <br> * <ul> * <li> 作者:C_Dream </li> * <li> 当前版本:4.0 </li> * <li> 修改时间: 2012-12-6 17:50 </li> * <li> 修改内容:<ol> * <li> 更换Excel2007写入方式,大幅提升性能。</li> * <li> 引入 log4j,局部提升性能。</li> * <li> 部分代码优化,CMD输出提示可选。</li> * </ol></li> * <li> 创建时间: 2012-11-08 19:22 </li> * </ul> */ public class Config extends HttpServlet{ private static final long serialVersionUID = 1L; //Config c = new Config();//此处决不能 new 本类,否则报错:java.lang.StackOverflowError String class_path = this.getClass().getResource("").getPath(); public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { this.doGet(request,response); //将 表单 post 方法传过来的参数,转给 get方法 去处理 } public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); //转码 String forms=(String)request.getParameter("forms"); if(forms.equals("if_3g")){ try { this.read_Excel(request,response); } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } response.sendRedirect("index.jsp?done=true"); } @SuppressWarnings("rawtypes") public void read_Excel(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, SQLException, ClassNotFoundException { PropertyConfigurator.configure(class_path+"log4j.properties");//获取 log4j 配置文件 Logger logger = Logger.getLogger(Config.class ); //获取log4j的实例 String startTmie = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); logger.debug("\n**********【准备处理,正在加载文件】**********");//7 logger.debug("\n\n**********每行数据间请不要有空行,以免程序误判**********");//7 logger.debug("\n\n**********由于处理Excel的插件本身性能局限,请控制文件大小,以免影响加载效率。**********");//7 logger.debug("\n\n**********大小在\t 7 MB \t以内,大约\t 21 万 \t行数据。**********");//7 logger.debug("\n\n**********本程序每分钟约处理 7000条数据,但根据文件大小会有影响。**********");//7 request.setCharacterEncoding("UTF-8"); //转码 String xls_read_Address=(String)request.getParameter("xls_read_Address");//读取 String xls_write_Address=(String)request.getParameter("xls_write_Address");//写入 String count_rows=(String)request.getParameter("count_rows");//自动编号 String tips_cmd=(String)request.getParameter("tips_cmd");//CMD窗口的提示方式 try { DataConvert dc = new DataConvert();//数据转换工具 DecimalFormat df = (DecimalFormat) NumberFormat.getPercentInstance(); ArrayList<ArrayList> ls = new ArrayList<ArrayList>(); File excel_file = new File(xls_read_Address);//读取的文件路径 FileInputStream input = new FileInputStream(excel_file); //读取的文件路径 XSSFWorkbook wb = new XSSFWorkbook(new BufferedInputStream(input)); int sheet_numbers = wb.getNumberOfSheets();//获取表的总数 logger.debug("\n\n**********共有工作表总数**********:"+sheet_numbers);//7 String[] sheetnames=new String[sheet_numbers]; Connection con=null; Statement stmt=null; ResultSet rs=null; String s_3g=null; Class.forName("oracle.jdbc.driver.OracleDriver"); con = DriverManager.getConnection("jdbc:oracle:thin:@12.12.12.123:1521:gz10000","gz12345","12345"); stmt = con.createStatement(); for(int i=0;i<sheet_numbers;i++){//遍历所有表 ArrayList<String[]> ls_a = new ArrayList<String[]>(); //用来存储某个表 读取出来的数据 Sheet sheet = wb.getSheetAt(i); //获取 某个表 sheetnames[i] = sheet.getSheetName();//获取表名,存入数组 logger.debug("\n\n---正在读取和匹配工作表\t《"+sheetnames[i]+"》\t的数据---\n");//7 int rows_num = sheet.getLastRowNum();//获取行数 logger.debug("\n\n---表\t《"+sheetnames[i]+"》\t 共有数据---:\t"+rows_num+"\t行");//7 for( int rows=0;rows<rows_num;rows++){ Row row = sheet.getRow(rows);//取得某一行 对象 if(row!=null&&!(row.equals(""))){ int columns_num = row.getLastCellNum();//获取列数 String[] s =new String[5];//初始化数组长度 for( int columns=0;columns<columns_num;columns++){ Cell cell = row.getCell(columns); if(cell!=null){ switch ( cell.getCellType()) { case XSSFCell.CELL_TYPE_STRING: // 字符串 s[columns] = cell.getStringCellValue(); if(s[columns]==null){ s[columns]=" "; } break; case XSSFCell.CELL_TYPE_NUMERIC: // 数字 double strCell = cell.getNumericCellValue(); if(String.valueOf(strCell)==null){ s[columns]=" "; } df.applyPattern("0"); s[columns] = df.format(strCell); if(Double.parseDouble(s[columns])!=strCell){ df.applyPattern(Double.toString(strCell)); s[columns] = df.format(strCell); } break; case XSSFCell.CELL_TYPE_BLANK: // 空值 s[columns]=" "; break; default: logger.debug("\n---单元格格式不支持---"); break; } } } if(count_rows.equals("是")&&rows>0){ s[0]=dc.intToString(rows);//自动编号 } /* ******** 访问数据库 ,并判断是否3G ******** */ String sql="select busiattr1 from ap_t_si_cus_spec_info where cus_phone='"+s[1]+"' and rownum=1"; rs = stmt.executeQuery(sql); if(rs.next()){ if(rs.getString("busiattr1")!=null){ s_3g = rs.getString("busiattr1").toString().toUpperCase(); } else{ s_3g=" "; } } else{ s_3g=" "; } /* ******** 访问结束 ******** */ if(s_3g.contains("3G")){ s[4]="是";//写入 “是否3G”这一列 的值,比如 “是” } if(s[4]==null){ s[4]="\t"; } /* CMD窗口提示方式 */ if(!(tips_cmd.equals("none"))&&tips_cmd!=null&&!(tips_cmd.equals(""))) { if(tips_cmd.equals("all")){ logger.debug("\n匹配中:"+s[0]+"\t"+s[1]+"\t"+s[2]+"\t"+s[3]+"\t"+ s[4]); }else if(rows%DataConvert.stringToInt(tips_cmd)==0){ logger.debug("\n匹配中:"+s[0]+"\t"+s[1]+"\t"+s[2]+"\t"+s[3]+"\t"+ s[4]); } } ls_a.add(s);//添加每行数据到 ls_a } } ls.add(ls_a); //添加 每个表 到 ls input.close(); write_Excel( xls_write_Address, ls, sheetnames ,tips_cmd) ; } } catch (IOException ex) { ex.printStackTrace(); } String endTmie = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); logger.debug("\n\n***************【处理完成,程序结束】***************");//7 logger.debug("\n开始时间:"+startTmie); logger.debug("\n结束时间:"+endTmie); logger.debug("\n新文件输出路径为:"+xls_write_Address); } @SuppressWarnings({ "rawtypes", "unchecked" }) public void write_Excel( String xls_write_Address,ArrayList<ArrayList> ls,String[] sheetnames,String tips_cmd ) throws IOException { PropertyConfigurator.configure(class_path+"log4j.properties");//获取 log4j 配置文件 Logger logger = Logger.getLogger(Config.class ); //获取log4j的实例 FileOutputStream output = new FileOutputStream(new File(xls_write_Address)); //读取的文件路径 SXSSFWorkbook wb = new SXSSFWorkbook(10000);//内存中保留 10000 条数据,以免内存溢出,其余写入 硬盘 for(int sn=0;sn<ls.size();sn++){ Sheet sheet = wb.createSheet(String.valueOf(sn)); wb.setSheetName(sn, sheetnames[sn]); ArrayList<String[]> ls2 = ls.get(sn); for(int i=0;i<ls2.size();i++){ Row row = sheet.createRow(i); String[] s = ls2.get(i); for(int cols=0;cols<s.length;cols++){ Cell cell = row.createCell(cols); cell.setCellType(XSSFCell.CELL_TYPE_STRING);//文本格式 sheet.setColumnWidth(cols, s[cols].length()*384); //设置单元格宽度 cell.setCellValue(s[cols]);//写入内容 } /* CMD窗口提示方式 */ if(!(tips_cmd.equals("none"))&&tips_cmd!=null&&!(tips_cmd.equals(""))) { if(tips_cmd.equals("all")){ logger.debug("\n写入中:"+s[0]+"\t"+s[1]+"\t"+s[2]+"\t"+s[3]+"\t"+ s[4]); }else if(i%DataConvert.stringToInt(tips_cmd)==0){ logger.debug("\n写入中:"+s[0]+"\t"+s[1]+"\t"+s[2]+"\t"+s[3]+"\t"+ s[4]); } } } } wb.write(output); output.close(); } }
相关文章推荐
- POI操作Excel2007实例二之“SXSSFWorkbook”处理海量数据
- POI操作Excel2007实例二之“SXSSFWorkbook”处理海量数据
- POI操作Excel2007 “SXSSFWorkbook”处理海量数据
- POI以SAX方式解析Excel2007大文件(包含空单元格的处理) Java生成CSV文件实例详解
- POI操作大数据量Excel时,new SXSSFWorkbook(1000)实例化失败问题解决
- Java-POI-sxssfWorkbook实例
- POI 海量数据/大数据文件生成SXSSFWorkbook使用简介
- 使用POI中的XSSFWorkbook操作excel2007(xlsx)的异常:找不到类解决
- org.apache.poi.hssf.usermodel.HSSFWorkbook 进行处理导出Excel操作
- 使用POI中的XSSFWorkbook操作excel2007(xlsx)的异常:找不到类解决
- 解决 struts2上传的excel2007文件,在用poi处理时通过new XSSFWorkbook(inputStream)出错
- 中等规模海量数据处理实例分析
- POI操作excel中的日期格式处理
- EPPLUS 操作Excel2007 入门实例
- EBS 发运管理操作实例9——发运例外处理(Ship Exceptions)
- POI操作excel2007 出现异常 java.lang.ClassNotFoundException: org.apache.xmlbeans.XmlOptions 解决方法
- Java-POI操作excel遇到文本字符问题处理
- poi 操作excel的处理
- POI以SAX方式解析Excel2007大文件(包含空单元格的处理)
- POI操作Excel2007的时 org.apache.xmlbeans.xmlexception 错误的解决方法