http://blog.csdn.net/little_stars/article/details/8210532
流程:(跟jxl相似,只是读取逻辑有点不同)
跟jxl的两处主要区别:
1、读取和写入方式略有不同:
(1) poi 读取:
- <span style="white-space:pre"> </span> FileInputStream input = new FileInputStream(new File(xls_read_Address)); //读取的文件路径
- XSSFWorkbook wb = new XSSFWorkbook(new BufferedInputStream(input));
poi 写入:先定位 哪一行,再在这个行的循环里面 写入每个 单元格的内容;
(2) jxl 读取:
- <span style="white-space:pre"> </span> Workbook book = Workbook.getWorkbook(new File(xls_read_Address),workbookSettings);
jxl 写入:任意定位 行列数,写入更灵活,当然,写入整个表的话,还是跟poi一样要遍历的。
2、数据类型判断方式略有不同:
(1)个人觉得,数据类型处理方面,poi 比不上 jxl 方便实用,poi在处理 数字 类型的值时 很容易出问题(不用文本方式),各位亲可以亲自试试。
(2)jxl 则处理的很好,像一般 操作 都只需要用到 文本方式就行。
----------------------------------------------------------------------------------
1、用 poi 读取Excel表格(传入Excel地址等):
(1)读取Excel ,将 Excel 中的所有 “工作表”,封装进 ArrayList<ArrayList> ls 中;
(2)读取工作表,遍历 ls, 将 每个 工作表 的所有数据,封装进 ArrayList<Sring[]> ls_a 中;
(3)读取每一行,遍历 ls_a,将 每一行 的所有 列 的内容,封装数组 Sring[] s 中;
(4)对 单元格 内容 进行 操作,比如 替换值、设置宽度 等。
(5)操作完后,赋值给对应的 s[i],也就是重写了s[i]的内容;接着封装进 ls_a ,最后把 ls_a 封装进 ls;
(6)关闭 流:
- input.close();
2、用 jxl 写入Excel 表格(传入 ArrayList<ArrayList>,新Excel地址等):
(1)用 ArrayList<ArrayList> ls 接收 上面 的传值,遍历 ls;
(2)用 ArrayList<Sring[]> ls_a 接收 遍历出来的 ls.get(i) ,并且 接着 遍历 ls_a ;
(3)用 String[] s 接收 遍历 出来的 ls_a ;
(4)用
- <span style="white-space:pre"> </span>XSSFCell cell = row.createCell(cols);
- cell.setCellType(XSSFCell.CELL_TYPE_STRING);//文本格式
- cell.setCellValue(s[cols]);//写入内容
将每个 s[cols] 写入 第 cols+1 列 。
(5)关闭流:
- <span style="white-space:pre"> </span>wb.write(output);
- output.close();
----------------------------------------------------------------------------------
方案 :每分钟约 处理 7000 行数据
运行环境:Tomcat 6.0.36 +JDK 1.6 + IE9
----------------------------------------------------------------------------------
1、建议建一个web工程而不是java工程;好处是:既可以用作web访问,又可以 以 java 工程 来测试;
2、src 下建一个包,两个 java文件,比如:Config.java ;
3、说明:Config.java ,所有操作在这里完成 ;
4、添加 jxl 的包,顺便如果用到数据库,就添加数据库包,比如本例中 oracle;
5、测试前要修改的信息有:
(1)包所在的路径、类名 等按提示修改即可;
(2) 数据库 信息 配置,这个要手动一个个修改,如果没有数据库的,那就用更简单的,将本例中的 调用数据库的 代码 直接去掉即可。
(3)各方法传入参数和传出参数 的修改:比如 Excel 文件路径 等
6、源码如下(源码中有调用到一个 DataConvert 类,这个类 是一个 基本数据类型 转换的封装类,你可以自己写一个方法替换就行):
(1)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.util.ArrayList;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.poi.xssf.usermodel.XSSFCell;
- import org.apache.poi.xssf.usermodel.XSSFRow;
- import org.apache.poi.xssf.usermodel.XSSFSheet;
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
- /**
- * <b> 数据匹配</b> <br>
- * <ul>
- * <li> 作者:C_Dream </li>
- * <li> 时间: 2012-11-08 19:22 </li>
- * <li> 版本:1.0 </li>
- * </ul>
- */
- public class Config extends HttpServlet{
- private static final long serialVersionUID = 1L; //此行可省略,只是为了标识
- 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 {
- 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");//自动编号
- try {
- DataConvert dc = new DataConvert();//数据转换工具
- DecimalFormat df = (DecimalFormat) NumberFormat.getPercentInstance();
- ArrayList<ArrayList> ls = new ArrayList<ArrayList>();
- FileInputStream input = new FileInputStream(new File(xls_read_Address)); //读取的文件路径
- XSSFWorkbook wb = new XSSFWorkbook(new BufferedInputStream(input));
- int sheet_numbers = wb.getNumberOfSheets();//获取表的总数
- 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:@10.57.123.214:1521:gz13200","gz13200","12345");
- stmt = con.createStatement();
- for(int i=0;i<sheet_numbers;i++){//遍历所有表
- ArrayList<String[]> ls_a = new ArrayList<String[]>(); //用来存储某个表 读取出来的数据
- XSSFSheet sheet = wb.getSheetAt(i); //获取 某个表
- sheetnames[i] = sheet.getSheetName();//获取表名,存入数组
- System.out.println("------>>>---正在读取Excel表数据,当前表:"+sheetnames[i]);
- for( int rows=0;rows<sheet.getLastRowNum();rows++){//有多少行
- XSSFRow row = sheet.getRow(rows);//取得某一行 对象
- String[] s =new String[5];//初始化数组长度
- for( int columns=0;columns<row.getLastCellNum();columns++){//读取所有列
- //s[columns] = row.getCell(columns).getStringCellValue(); //取得某单元格内容,字符串类型
- XSSFCell 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:
- System.out.print(" ---单元格格式不支持---");
- break;
- }
- }
- }
- if(count_rows.equals("是")&&rows>0){
- s[0]=dc.intToString(rows);//自动编号
- }
- /* ******** 访问数据库 ,并判断是否3G ******** */
- String sql="select * 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]=" ";
- }
- System.out.println(" ------>>>---已处理数据---号码:"+s[1]+" 是否3G:"+s[4]);
- ls_a.add(s);//添加每行数据到 ls_a
- }
- ls.add(ls_a); //添加 每个表 到 ls
- System.out.println(" ------>>>---开始写入Excel文件,请耐心等待---<<<------");
- input.close();
- write_Excel( xls_write_Address, ls, sheetnames ) ;
- }
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void write_Excel( String xls_write_Address,ArrayList<ArrayList> ls,String[] sheetnames ) throws IOException {
- FileOutputStream output = new FileOutputStream(new File(xls_write_Address)); //读取的文件路径
- XSSFWorkbook wb = new XSSFWorkbook();//(new BufferedInputStream(output));
- for(int sn=0;sn<ls.size();sn++){
- XSSFSheet 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++){
- XSSFRow row = sheet.createRow(i);
- String[] s = ls2.get(i);
- for(int cols=0;cols<s.length;cols++){
- XSSFCell cell = row.createCell(cols);
- cell.setCellType(XSSFCell.CELL_TYPE_STRING);//文本格式
- cell.setCellValue(s[cols]);//写入内容
- }
- }
- }
- wb.write(output);
- output.close();
- System.out.println("-------【完成写入】-------");
- }
- }
-----------------------------------------------------------
关于代码可读性与扩展性,以及运行效率问题的 小结:
1、本章方案:二次开发难度相对高,但是运行效率更高,因为只需连接一次数据库,就可以处理所有数据;
2、跟前章jxl类似的DAO方案(本章未列出):代码可读性相对高,更适合做二次开发,但是由于 在业务中调用DAO,因此 每次都连接数据库,因此消耗了性能;
-------------------------------------------------
关于为何 不用 SSH 等框架:
1、一个小小的业务的话,是没必要伤筋动骨的;
2、如果业务不多,那么,其实直接用 JDBC 访问数据库,效率比 Hibernate 更高;
3、不用 SSH,那么,对公司的员工的技术要求 门槛就低了,可以用 较低的成本,完成自己的业务。