POI、SAX读取Excel大文件

       poi 读取文件分为两种模式:用户模型、事件用户模型,第一种方案是以DOM方式读取Excel,好处是读取操作方便,不足的是一次性将文件加载到内存; 第二种方案是SAX读取Excel,好处是内存占用小,因为每次只读取陪份数据,缺点是读取方件较不方便。

        涉及的功能类: excel错误信息记录类、读取excel基类、读取excel公用类、示例类

测试结果(读取、存库):

16万  8个字段  80s 全英文
10万  15个字段 120s 大部份中文
jvm要设置成-Xms512m -Xmx1024m 否则会很影响性能

 

excel错误信息记录类

  1. /*********************************************************************** 
  2. Copyright (c) 2007, AgileSC,Inc.China 
  3. All rights reserved. 
  4. ************************************************************************/  
  5. package com.asc.console.dao.impl;  
  6.   
  7. import java.util.ArrayList;  
  8. import java.util.HashMap;  
  9. import java.util.LinkedList;  
  10. import java.util.List;  
  11. import java.util.Map;  
  12.   
  13.   
  14. /** 
  15.  * 验证上传文件  . 
  16.  * @author yangzelai 
  17.  * @version 版本信息 创建时间 Jan 15, 2011 2:36:37 PM 
  18.  */  
  19. public class ValidateFileUpload<T> {  
  20.       
  21.     public static String VALIDATE_NULL = "不能为空";  
  22.     public static String VALIDATE_REPEATED = "忽略文件中重复的";  
  23.     public static String VALIDATE_INVALID = "不合法";  
  24.     public static String VALIDATE_EXIST = "已存在";  
  25.     public static String VALIDATE_NOT_EXIST = "不存在";  
  26.       
  27.     //验证消息集合  
  28.     private List<ValidateInfo> validateInfo = new ArrayList<ValidateInfo>();  
  29.     //验证的字段  
  30.     public  Map<String,Object> map = new HashMap<String,Object>();  
  31.     //上传的内容  
  32.     List<T> uploadList = new LinkedList<T>();  
  33.     //总记录数  
  34.     public int total;  
  35.       
  36.       
  37.     /*******************************/  
  38.       
  39.     public void addResult(String msg,Integer rowNumber,String value){  
  40.         ValidateInfo  result = null;  
  41.         // 限制错误信息数量  
  42.         if(uploadList.size() < 1000){  
  43.             result = new ValidateInfo(msg,rowNumber,value);  
  44.         }else if(uploadList.size() == 1000){   
  45.             result = new ValidateInfo("错误信息已达到上限1000条,请检查数据格式!",rowNumber,value);  
  46.         }else{  
  47.             return;  
  48.         }  
  49.         this.validateInfo.add(result);  
  50.     }  
  51.       
  52.     public  void addResult(String msg,Integer rowNumber,String value,Integer valid){  
  53.         ValidateInfo  result = new ValidateInfo(msg,rowNumber,value,valid);  
  54.         this.validateInfo.add(result);  
  55.     }  
  56.   
  57.     public List<ValidateInfo> getValidateInfo() {  
  58.         return this.validateInfo;  
  59.     }  
  60.   
  61.     public void setValidateInfo(List<ValidateInfo> validateInfo) {  
  62.         this.validateInfo = validateInfo;  
  63.     }  
  64.   
  65.     public Map<String, Object> getMap() {  
  66.         return this.map;  
  67.     }  
  68.   
  69.     public void setMap(Map<String, Object> map) {  
  70.         this.map = map;  
  71.     }  
  72.   
  73.     public List<T> getUploadList() {  
  74.         return this.uploadList;  
  75.     }  
  76.   
  77.     public void setUploadList(List<T> uploadList) {  
  78.         this.uploadList = uploadList;  
  79.     }  
  80.   
  81.     /** 
  82.      * @param validateInfo 
  83.      * @param map 
  84.      */  
  85.     public ValidateFileUpload(List<ValidateInfo> validateInfo,  
  86.             Map<String, Object> map) {  
  87.         super();  
  88.         this.validateInfo = validateInfo;  
  89.         this.map = map;  
  90.     }  
  91.   
  92.     /** 
  93.      *  
  94.      */  
  95.     public ValidateFileUpload() {  
  96.         super();  
  97.     }  
  98.   
  99.     public int getTotal() {  
  100.         return this.total;  
  101.     }  
  102.   
  103.     public void setTotal(int total) {  
  104.         this.total = total;  
  105.     }  
  106.       
  107.     public void setTotal(){  
  108.         this.total++;  
  109.     }  
  110.       
  111. }  
  112.   
  113.   
  114. /*********************************************************************** 
  115. Copyright (c) 2007, AgileSC,Inc.China 
  116. All rights reserved. 
  117. ************************************************************************/  
  118. package com.asc.console.dao.impl;  
  119.   
  120. /** 
  121.  * 封装验证的结果  . 
  122.  * @author yangzelai 
  123.  * @version 版本信息 创建时间 Jan 15, 2011 2:34:59 PM 
  124.  */  
  125. public class ValidateInfo {  
  126.     private String validateMsg;        // 验证的类型  
  127.     private Integer rowNumber;        // 验证的记录在Excel中的行号  
  128.     private String value;            // 错误的值  
  129.     private Integer valid;            // 0 错误 1 正确  
  130.       
  131.     /** 
  132.      *  
  133.      */  
  134.     public ValidateInfo() {  
  135.         super();  
  136.     }  
  137.       
  138.     public String getValidateMsg() {  
  139.         return this.validateMsg;  
  140.     }  
  141.     public void setValidateMsg(String validateMsg) {  
  142.         this.validateMsg = validateMsg;  
  143.     }  
  144.     public Integer getRowNumber() {  
  145.         return this.rowNumber;  
  146.     }  
  147.     public void setRowNumber(Integer rowNumber) {  
  148.         this.rowNumber = rowNumber;  
  149.     }  
  150.     public String getValue() {  
  151.         return this.value;  
  152.     }  
  153.     public void setValue(String value) {  
  154.         this.value = value;  
  155.     }  
  156.     public Integer getValid() {  
  157.         return this.valid;  
  158.     }  
  159.     public void setValid(Integer valid) {  
  160.         this.valid = valid;  
  161.     }  
  162.     /** 
  163.      * @param validateMsg 
  164.      * @param rowNumber 
  165.      * @param value 
  166.      * @param valid 
  167.      */  
  168.     public ValidateInfo(String validateMsg, Integer rowNumber, String value,  
  169.             Integer valid) {  
  170.         super();  
  171.         this.validateMsg = validateMsg;  
  172.         this.rowNumber = rowNumber;  
  173.         this.value = value;  
  174.         this.valid = valid;  
  175.     }  
  176.       
  177.     public ValidateInfo(String validateMsg, Integer rowNumber, String value) {  
  178.         super();  
  179.         this.validateMsg = validateMsg;  
  180.         this.rowNumber = rowNumber;  
  181.         this.value = value;  
  182.         this.setValid(0);  
  183.     }  
  184.       
  185.       
  186.       
  187.       
  188. }  

读取excel基类

  1. package com.asc.console.fileupload;  
  2.   
  3. import java.io.InputStream;  
  4. import java.sql.SQLException;  
  5. import java.util.ArrayList;  
  6. import java.util.Iterator;  
  7. import java.util.List;  
  8.   
  9. import org.apache.poi.xssf.eventusermodel.XSSFReader;  
  10. import org.apache.poi.xssf.model.SharedStringsTable;  
  11. import org.apache.poi.xssf.usermodel.XSSFRichTextString;  
  12. import org.apache.poi.openxml4j.opc.OPCPackage;  
  13. import org.xml.sax.Attributes;  
  14. import org.xml.sax.InputSource;  
  15. import org.xml.sax.SAXException;  
  16. import org.xml.sax.XMLReader;  
  17. import org.xml.sax.helpers.DefaultHandler;  
  18. import org.xml.sax.helpers.XMLReaderFactory;  
  19.   
  20. /** 
  21.  * 1.标题必须在第一行,且符合规范 
  22.  * 2.自动忽略空行 
  23.  * 3.自动忽略标题外的多余列  
  24.  * @author yangzelai 
  25.  * 
  26.  */  
  27. public abstract class XxlsAbstract extends DefaultHandler {  
  28.     private SharedStringsTable sst;  
  29.     private String lastContents;  
  30.     private boolean nextIsString;  
  31.   
  32.     private int sheetIndex = -1;  
  33.     private List<String> rowlist;  
  34.     private int curRow = 1;  
  35.     private int curCol = 1;  
  36.     private String defaultStr = "";  
  37.     private boolean listIsNull = true;  
  38.     protected int total = 0;  
  39.     private boolean allNull = true;  
  40.   
  41.     //excel记录行操作方法,以sheet索引,行索引和行元素列表为参数,对sheet的一行元素进行操作,元素为String类型  
  42.     public abstract void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException;  
  43.       
  44.     //只遍历一个sheet,其中sheetId为要遍历的sheet索引,从1开始,1-3  
  45.     public void processOneSheet(String filename,int sheetId) throws Exception {  
  46.         OPCPackage pkg = OPCPackage.open(filename);  
  47.         XSSFReader r = new XSSFReader(pkg);  
  48.         SharedStringsTable sst = r.getSharedStringsTable();  
  49.           
  50.         XMLReader parser = fetchSheetParser(sst);  
  51.   
  52.         // rId2 found by processing the Workbook  
  53.         // 根据 rId# 或 rSheet# 查找sheet  
  54.         InputStream sheet2 = r.getSheet("rId"+sheetId);  
  55.         sheetIndex++;  
  56.         InputSource sheetSource = new InputSource(sheet2);  
  57.         parser.parse(sheetSource);  
  58.         sheet2.close();  
  59.     }  
  60.       
  61.     public void processOneSheet(InputStream in,int sheetId) throws Exception {  
  62.         OPCPackage pkg = OPCPackage.open(in);  
  63.         XSSFReader r = new XSSFReader(pkg);  
  64.         SharedStringsTable sst = r.getSharedStringsTable();  
  65.           
  66.         XMLReader parser = fetchSheetParser(sst);  
  67.   
  68.         // rId2 found by processing the Workbook  
  69.         // 根据 rId# 或 rSheet# 查找sheet  
  70.         InputStream sheet2 = r.getSheet("rId"+sheetId);  
  71.         sheetIndex++;  
  72.         InputSource sheetSource = new InputSource(sheet2);  
  73.         parser.parse(sheetSource);  
  74.         sheet2.close();  
  75.     }  
  76.   
  77.     /** 
  78.      * 遍历 excel 文件 
  79.      */  
  80.     public void process(String filename) throws Exception {  
  81.         OPCPackage pkg = OPCPackage.open(filename);  
  82.         XSSFReader r = new XSSFReader(pkg);  
  83.         SharedStringsTable sst = r.getSharedStringsTable();  
  84.   
  85.         XMLReader parser = fetchSheetParser(sst);  
  86.   
  87.         Iterator<InputStream> sheets = r.getSheetsData();  
  88.         while (sheets.hasNext()) {  
  89.             curRow = 0;  
  90.             sheetIndex++;  
  91.             InputStream sheet = sheets.next();  
  92.             InputSource sheetSource = new InputSource(sheet);  
  93.             parser.parse(sheetSource);  
  94.             sheet.close();  
  95.         }  
  96.     }  
  97.   
  98.     public XMLReader fetchSheetParser(SharedStringsTable sst)  
  99.             throws SAXException {  
  100.         XMLReader parser = XMLReaderFactory  
  101.                 .createXMLReader("org.apache.xerces.parsers.SAXParser");  
  102.         this.sst = sst;  
  103.         parser.setContentHandler(this);  
  104.         return parser;  
  105.     }  
  106.   
  107.     public void startElement(String uri, String localName, String name,  
  108.             Attributes attributes) throws SAXException {  
  109.         // c => 单元格  
  110.         if (name.equals("c")) {  
  111.             // 如果下一个元素是 SST 的索引,则将nextIsString标记为true  
  112.             String cellType = attributes.getValue("t");  
  113.             if (cellType != null && cellType.equals("s")) {  
  114.                 nextIsString = true;  
  115.             } else {  
  116.                 nextIsString = false;  
  117.             }  
  118.             curCol = getNumberFromLetter(attributes.getValue("r"));  
  119.         } else if (name.equals("row")) {  
  120.             // 设置行号  
  121.             curRow = Integer.parseInt(attributes.getValue("r"));  
  122.             if(listIsNull){  
  123.                 initRowList(attributes);  
  124.             }  
  125.         } else if (name.equals("dimension")){  
  126.             //获得总计录数  
  127.             String d = attributes.getValue("ref");  
  128.             total = getNumber(d.substring(d.indexOf(":")+1,d.length()));  
  129.         }  
  130.         // 置空  
  131.         lastContents = "";  
  132.     }  
  133.   
  134.     @Override  
  135.     public void endElement(String uri, String localName, String name)  
  136.             throws SAXException {  
  137.         // 根据SST的索引值的到单元格的真正要存储的字符串  
  138.         // 这时characters()方法可能会被调用多次  
  139.         if (nextIsString) {  
  140.             try {  
  141.                 int idx = Integer.parseInt(lastContents);  
  142.                 lastContents = new XSSFRichTextString(sst.getEntryAt(idx))  
  143.                         .toString();  
  144.             } catch (Exception e) {  
  145.   
  146.             }  
  147.         }  
  148.           
  149.         // v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引  
  150.         // 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符  
  151.         if (name.equals("v")) {  
  152.             String value = lastContents.trim();  
  153.             if(allNull && !value.equals("")){  
  154.                 allNull = false;  
  155.             }  
  156.             if(curCol <= rowlist.size()){  
  157.                 rowlist.set(curCol - 1, value);  
  158.             }  
  159.         }else {  
  160.             if (name.equals("row") && !allNull) {  
  161.                 try {  
  162.                     optRows(sheetIndex, curRow, rowlist);  
  163.                     allNull = true;  
  164.                 } catch (IllegalArgumentException ie){  
  165.                     throw ie;  
  166.                 }catch (SQLException e) {  
  167.                     throw new SAXException(e);  
  168.                 }  
  169.                 resetRowList();  
  170.             }  
  171.         }  
  172.     }  
  173.   
  174.     private void initRowList(Attributes attributes) {  
  175.         // 以第一行为行数据标准  
  176.         if (curRow == 1) {  
  177.             int size = getColumns(attributes.getValue("spans"));  
  178.             rowlist = new ArrayList<String>(size);  
  179.             for (int i = 0; i < size; i++) {  
  180.                 rowlist.add(defaultStr);  
  181.             }  
  182.         }  
  183.         listIsNull = false;  
  184.     }  
  185.   
  186.     private static int getColumns(String spans) {  
  187.         String number = spans.substring(spans.lastIndexOf(':') + 1,  
  188.                 spans.length());  
  189.         return Integer.parseInt(number);  
  190.     }  
  191.   
  192.     private static int getNumberFromLetter(String column) {  
  193.         String c = column.toUpperCase().replaceAll("[0-9]""");  
  194.         int number = (int) c.charAt(0) - 64;  
  195.         return number;  
  196.     }  
  197.       
  198.     private static int getNumber(String column) {  
  199.         String c = column.toUpperCase().replaceAll("[A-Z]""");  
  200.         return Integer.parseInt(c);  
  201.     }  
  202.   
  203.     public void resetRowList() {  
  204.         for (int i = 0; i < rowlist.size(); i++) {  
  205.             rowlist.set(i, defaultStr);  
  206.         }  
  207.     }  
  208.       
  209.     public void characters(char[] ch, int start, int length)  
  210.             throws SAXException {  
  211.         //得到单元格内容的值  
  212.         lastContents += new String(ch, start, length);  
  213.     }  
  214.   
  215.     public void setAllNull(boolean allNull) {  
  216.         this.allNull = allNull;  
  217.     }  
  218.   
  219.     public boolean isAllNull() {  
  220.         return allNull;  
  221.     }  
  222. }  

读取excel公用类
  1. /*********************************************************************** 
  2. Copyright (c) 2007, AgileSC,Inc.China 
  3. All rights reserved. 
  4. ************************************************************************/  
  5. package com.asc.console.fileupload;  
  6.   
  7. import java.io.FileInputStream;  
  8. import java.sql.Connection;  
  9. import java.sql.PreparedStatement;  
  10. import java.sql.SQLException;  
  11. import java.util.Date;  
  12. import java.util.HashMap;  
  13. import java.util.List;  
  14. import java.util.Map;  
  15.   
  16. import javax.servlet.http.HttpServletRequest;  
  17. import javax.sql.DataSource;  
  18.   
  19. import org.apache.poi.hssf.usermodel.HSSFDateUtil;  
  20. import org.springframework.jdbc.core.JdbcTemplate;  
  21.   
  22. import com.asc.console.dao.impl.ValidateFileUpload;  
  23.   
  24. /** 
  25.  * 类描述  . 
  26.  * @author yangzelai 
  27.  * @version 版本信息 创建时间 Jan 17, 2011 6:01:05 PM 
  28.  */  
  29. public abstract class FileUploadModel<T> extends XxlsAbstract {  
  30.     // jdbc connection  
  31.     public Connection conn;  
  32.     // jdbc datasource  
  33.     public DataSource dataSource;  
  34.     // jdbc statement  
  35.     public PreparedStatement ps;  
  36.     // jdbc template;  
  37.     public JdbcTemplate jdbcTemplate;  
  38.     // 上传文件标题 与 列号 map  
  39.     public Map<Integer,String> titleRowMap = new HashMap<Integer, String>();  
  40.     // 验证类  
  41.     public ValidateFileUpload<T> validate;  
  42.     // 记录bean  
  43.     public T bean;  
  44.     // 批量提交大小 默认1万  
  45.     public int commitNumber = 10000*1;  
  46.     // 是否已提交  
  47.     public boolean isCommit = false;  
  48.     // 临时表名  
  49.     public String tempTable;  
  50.     // 数据库中的表 名  
  51.     public String tableName;  
  52.     // HttpServletRequest  
  53.     public HttpServletRequest request;  
  54.     // 读取单元格的值  
  55.     public abstract void optRows(int sheetIndex, int rowNumber, List<String> rowList) throws SQLException;  
  56.     // 设置bean的属性值  true:功能  false:失败   
  57.     public abstract boolean setColumnValue(String colName, String colValue, int rowNumber, T bean);  
  58.     // 初始化  
  59.     public abstract void init();  
  60.     // 结束  
  61.     public abstract void end();  
  62.     // 处理文件  
  63.     public void process(FileInputStream in) throws Exception{  
  64.         try {  
  65.             init();  
  66.             processOneSheet(in, 1);  
  67.             if(!isCommit){  
  68.                 ps.executeBatch();  
  69.                 getConn().commit();  
  70.                 ps.clearBatch();  
  71.             }  
  72.             end();  
  73.             clearCurrentProcess();  
  74.         } catch (Exception e) {  
  75.             throw e;  
  76.         }finally{  
  77.             try {  
  78.                 //删除临时表  
  79.                 dropTable();  
  80.                 //关闭连接  
  81.                 close();  
  82.             } catch (Exception e) {  
  83.                 e.printStackTrace();  
  84.             }  
  85.         }  
  86.     }  
  87.       
  88.     //创建表  
  89.     public void createTable(){  
  90.         @SuppressWarnings("unchecked")  
  91.         List<Map<String, Object>>  list= getJdbcTemplate().queryForList("select tname from tab where tname = '"+tempTable+"'");  
  92.         if(null != list && list.size() > 0){  
  93.             getJdbcTemplate().execute("drop table "+tempTable+" cascade constraints");  
  94.         }  
  95.         getJdbcTemplate().execute("create table "+tempTable+" as select * from "+tableName+" where rownum < -1");  
  96.         getJdbcTemplate().execute("alter table "+tempTable+" add (excel_row_number NUMBER)");  
  97.     }  
  98.       
  99.     //将临时表数据保存到正式表中  
  100.     @Deprecated  
  101.     public void insertDataFromTempTable(){  
  102.         getJdbcTemplate().execute("insert into "+tableName+" select * from "+tempTable);  
  103.     }  
  104.       
  105.     //删除表  
  106.     public void dropTable(){  
  107.         @SuppressWarnings("unchecked")  
  108.         List<Map<String, Object>>  list= getJdbcTemplate().queryForList("select tname from tab where tname = '"+tempTable+"'");  
  109.         if(null != list && list.size() > 0){  
  110.             getJdbcTemplate().execute("drop table "+tempTable+" cascade constraints");  
  111.         }  
  112.     }  
  113.       
  114.     //格式化日期  
  115.     public Date formatDate(String colValue, String colName, int rowNumber, ValidateFileUpload<T> validate){  
  116.         Date date = null;  
  117.         try {  
  118.             date = HSSFDateUtil.getJavaDate(Double.parseDouble(colValue));  
  119.         } catch (Exception e) {  
  120.             validate.addResult(colName+ValidateFileUpload.VALIDATE_INVALID+",正确的格式:2011-10-10", rowNumber, colValue);  
  121.         }  
  122.         return date;  
  123.     }  
  124.       
  125.       
  126.     @Deprecated  
  127.     public String getInsertSQL(String sql){  
  128.         //不能加this 否则指向本类  
  129.         return "insert into "+tempTable+sql;  
  130.     }  
  131.       
  132.     //设置实时处理变量  
  133.     protected void setCurrentProcess(int totalRecord,int rowNumber){  
  134.         getRequest().getSession().setAttribute("UPLOAD_TOTAL", totalRecord);  
  135.         getRequest().getSession().setAttribute("UPLOAD_CURRENT_PROGRESS", rowNumber);  
  136.     }  
  137.       
  138.     protected void clearCurrentProcess(){  
  139.         getRequest().getSession().removeAttribute("UPLOAD_TOTAL");  
  140.         getRequest().getSession().removeAttribute("UPLOAD_CURRENT_PROGRESS");  
  141.     }  
  142.       
  143.     //关闭资源  
  144.     public void close() throws Exception{  
  145.         if(null != this.ps){  
  146.             ps.close();  
  147.             ps = null;  
  148.         }  
  149.           
  150.         if(null != this.getConn()){  
  151.             getConn().close();  
  152.             setConn(null);  
  153.         }  
  154.     }  
  155.       
  156.     public boolean isEmpty(String param){  
  157.         if(null == param){  
  158.             return true;  
  159.         }  
  160.         param  = param.trim();  
  161.         if(param.length()==0){  
  162.             return true;  
  163.         }  
  164.         return false;  
  165.     }  
  166.   
  167.     public Connection getConn() {  
  168.           
  169.         try {  
  170.             if(null == conn){  
  171.                 this.conn = getDataSource().getConnection();  
  172.             }  
  173.         } catch (Exception e) {  
  174.             System.out.println("获得JDBC connection异常 ");  
  175.             e.printStackTrace();  
  176.         }  
  177.         return conn;  
  178.           
  179.     }  
  180.   
  181.     public void setConn(Connection conn) {  
  182.         this.conn = conn;  
  183.     }  
  184.   
  185.     public PreparedStatement getPs() {  
  186.         return this.ps;  
  187.     }  
  188.   
  189.     public void setPs(PreparedStatement ps) {  
  190.         this.ps = ps;  
  191.     }  
  192.   
  193.     public Map<Integer, String> getTitleRowMap() {  
  194.         return this.titleRowMap;  
  195.     }  
  196.   
  197.     public void setTitleRowMap(Map<Integer, String> titleRowMap) {  
  198.         this.titleRowMap = titleRowMap;  
  199.     }  
  200.   
  201.     public ValidateFileUpload<T> getValidate() {  
  202.         return this.validate;  
  203.     }  
  204.   
  205.     public void setValidate(ValidateFileUpload<T> validate) {  
  206.         this.validate = validate;  
  207.     }  
  208.   
  209.     public T getBean() {  
  210.         return this.bean;  
  211.     }  
  212.   
  213.     public void setBean(T bean) {  
  214.         this.bean = bean;  
  215.     }  
  216.     public DataSource getDataSource() {  
  217.         return this.dataSource;  
  218.     }  
  219.     public void setDataSource(DataSource dataSource) {  
  220.         this.dataSource = dataSource;  
  221.         getJdbcTemplate().setDataSource(dataSource);  
  222.     }  
  223.     public int getCommitNumber() {  
  224.         return this.commitNumber;  
  225.     }  
  226.     public void setCommitNumber(int commitNumber) {  
  227.         this.commitNumber = commitNumber;  
  228.     }  
  229.     public boolean isCommit() {  
  230.         return this.isCommit;  
  231.     }  
  232.     public void setCommit(boolean isCommit) {  
  233.         this.isCommit = isCommit;  
  234.     }  
  235.     public String getTempTable() {  
  236.         return this.tempTable;  
  237.     }  
  238.     public void setTempTable(String tempTable) {  
  239.         this.tempTable = tempTable;  
  240.     }  
  241.     public JdbcTemplate getJdbcTemplate() {  
  242.         if(null == jdbcTemplate){  
  243.             jdbcTemplate = new JdbcTemplate();  
  244.         }  
  245.         return jdbcTemplate;  
  246.     }  
  247.     public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
  248.         this.jdbcTemplate = jdbcTemplate;  
  249.     }  
  250.     public String getTableName() {  
  251.         return tableName;  
  252.     }  
  253.     public void setTableName(String tableName) {  
  254.         this.tableName = tableName;  
  255.     }  
  256.     public FileUploadModel() {  
  257.         super();  
  258.     }  
  259.     public HttpServletRequest getRequest() {  
  260.         return request;  
  261.     }  
  262.     public void setReqeust(HttpServletRequest request) {  
  263.         this.request = request;  
  264.     }  
  265.       
  266.     @SuppressWarnings("unused")  
  267.     public void setNull(Object... list){  
  268.         for (Object obj : list) {  
  269.             obj =  null;  
  270.         }  
  271.     }  
  272.       
  273.     /** 
  274.      * 添加验证 
  275.      * @param list list<map> 
  276.      * @param msg 消息 
  277.      * @param rowNumber 行号 
  278.      * @param value 错误的值  
  279.      */  
  280.     protected void addValidateResult(List<Map<String, Object>> list, String msg, String rowNumber,String value ){  
  281.         if (null != list && list.size() > 0) {  
  282.             for (Map<String, Object> record : list) {  
  283.                 try {  
  284.                     validate.addResult(msg, ((Number)record.get(rowNumber)).intValue(), (String)record.get(value));  
  285.                 } catch (Exception e) {  
  286.                     validate.addResult(msg, ((Number)record.get(rowNumber)).intValue(), ((Number)record.get(value)).intValue()+"");  
  287.                 }  
  288.                   
  289.             }  
  290.         }  
  291.     }  
  292. }  

上传示列:

  1. /*********************************************************************** 
  2. Copyright (c) 2007, AgileSC,Inc.China 
  3. All rights reserved. 
  4. ************************************************************************/  
  5. package com.asc.console.fileupload;  
  6.   
  7. import java.sql.SQLException;  
  8. import java.util.Date;  
  9. import java.util.List;  
  10. import java.util.Map;  
  11.   
  12. import com.asc.console.dao.impl.ValidateFileUpload;  
  13. import com.asc.maindatainfo.orginfo.bean.TskfOrg;  
  14.   
  15. /** 
  16.  * 上传企业文件时,不做数据验证 . 
  17.  * @author yangzelai 
  18.  * @version 版本信息 创建时间 Jan 23, 2011 9:38:20 AM 
  19.  */  
  20. public class TskfOrgModel extends FileUploadModel<TskfOrg> {  
  21.     //列  
  22.     public static String COLUMNS = "ID,ORG_NAME,ORG_CODE,REGION_NAME,REGION_CODE" +  
  23.     ",PROVINCE_NAME,PROVINCE_CODE,CITY_NAME,CITY_CODE" +  
  24.     ",ADDRESS,ORG_TYPE,ORG_LEVEL,ORG_PROPERTY,ORG_CHANNEL,CREATE_DATE,UPDATE_MONTH";  
  25.       
  26.     public static boolean isLock = false;  
  27.       
  28.     /* (non-Javadoc) 
  29.      * @see com.asc.console.fileupload.FileUploadModel#optRows(int, int, java.util.List) 
  30.      */  
  31.       
  32.     public static boolean isLock() {  
  33.         return isLock;  
  34.     }  
  35.   
  36.     public static void setLock(boolean isLock) {  
  37.         TskfOrgModel.isLock = isLock;  
  38.     }  
  39.   
  40.     public void optRows(int sheetIndex, int rowNumber, List<String> rowList)  
  41.             throws SQLException {  
  42.         if(rowNumber == 1){  
  43.             int index = 0;  
  44.             for (String title : rowList) {  
  45.                 if(!(TskfOrg.TITLE_COLUMN.contains(title) && TskfOrg.TITLE_COLUMN.indexOf(title) == index)){  
  46.                     throw new IllegalArgumentException("标题不符合规范:"+title);  
  47.                 }  
  48.                 titleRowMap.put(index, title);  
  49.                 index++;  
  50.             }  
  51.             //创建临时表  
  52.             createTable();  
  53.             //设置事务  
  54.             getConn().setAutoCommit(false);  
  55.             ps = getConn().prepareStatement("INSERT INTO "+tempTable+" ("+COLUMNS+",EXCEL_ROW_NUMBER) VALUES (HIBERNATE_SEQUENCE.NEXTVAL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");  
  56.         }else{  
  57.             //读取行数据   
  58.             this.bean  = new TskfOrg();  
  59.             boolean toSave = false;  
  60.             for(int i=0; i<rowList.size(); i++){  
  61.                 String colName = titleRowMap.get(i);  
  62.                 String colValue = rowList.get(i);  
  63.                 toSave = setColumnValue(colName, colValue, rowNumber, bean);  
  64.                 //如果有一个字段值无效,这条数据不保存  
  65.                 if(!toSave){  
  66.                     break;  
  67.                 }  
  68.             }  
  69.             //添加到ps中  
  70.             if(toSave){  
  71.                 ps.setString(1, bean.getOrgName());  
  72.                 ps.setString(2, bean.getOrgCode());  
  73.                 ps.setString(3, bean.getRegionName());  
  74.                 ps.setString(4, bean.getRegionCode());  
  75.                 ps.setString(5, bean.getProvinceName());  
  76.                 ps.setString(6, bean.getProvinceCode());  
  77.                 ps.setString(7, bean.getCityName());  
  78.                 ps.setString(8, bean.getCityCode());  
  79.                 ps.setString(9, bean.getAddress());  
  80.                 ps.setString(10, bean.getOrgType());  
  81.                 ps.setString(11, bean.getOrgLevel());  
  82.                 ps.setString(12, bean.getOrgProperty());  
  83.                 ps.setString(13, bean.getOrgChannel());  
  84.                   
  85.                 if(null != bean.getCreateDate()){  
  86.                     ps.setDate(14new java.sql.Date(bean.getCreateDate().getTime()));  
  87.                 }else{  
  88.                     ps.setDate(14null);  
  89.                 }  
  90.                 ps.setString(15, bean.getUpdateMonth());  
  91.                 ps.setInt(16, rowNumber);  
  92.                 ps.addBatch();  
  93.                 isCommit = false;  
  94.                 this.validate.setTotal();  
  95.             }  
  96.             //提交  
  97.             if(rowNumber%commitNumber == 0){  
  98.                 ps.executeBatch();  
  99.                 getConn().commit();  
  100.                 ps.clearBatch();  
  101.                 isCommit = true;  
  102.                 setCurrentProcess(this.total, rowNumber);  
  103.             }  
  104.         }  
  105.     }  
  106.   
  107.     /* (non-Javadoc) 
  108.      * @see com.asc.console.fileupload.FileUploadModel#setColumnValue(java.lang.String, java.lang.String, int, java.lang.Object) 
  109.      */  
  110.       
  111.     public boolean setColumnValue(String colName, String colValue,  
  112.             int rowNumber, TskfOrg bean) {  
  113.         /************ 字段验证 start *************/  
  114.         if(TskfOrg.ROW_ORG_NAME.equals(colName)){  
  115.             bean.setOrgName(colValue);  
  116.         }else if(TskfOrg.ROW_ORG_CODE.equals(colName)){  
  117.             //去空、去重  
  118.             if(isEmpty(colValue)){  
  119.                 validate.addResult(colName+ValidateFileUpload.VALIDATE_NULL, rowNumber, colValue);  
  120.                 return false;  
  121.             }else{  
  122.                 bean.setOrgCode(colValue);  
  123.             }  
  124.         }else if(TskfOrg.ROW_REGION_NAME.equals(colName)){  
  125.             bean.setRegionName(colValue);  
  126.         }else if(TskfOrg.ROW_REGION_CODE.equals(colName)){  
  127.             bean.setRegionCode(colValue);  
  128.         }else if(TskfOrg.ROW_PROVINCE_NAME.equals(colName)){  
  129.             bean.setProvinceName(colValue);  
  130.         }else if(TskfOrg.ROW_PROVINCE_CODE.equals(colName)){  
  131.             bean.setProvinceCode(colValue);  
  132.         }else if(TskfOrg.ROW_CITY_NAME.equals(colName)){  
  133.             bean.setCityName(colValue);  
  134.         }else if(TskfOrg.ROW_CITY_CODE.equals(colName)){  
  135.             bean.setCityCode(colValue);  
  136.         }else if(TskfOrg.ROW_ADDRESS.equals(colName)){  
  137.             bean.setAddress(colValue);  
  138.         }else if(TskfOrg.ROW_ORG_TYPE.equals(colName)){  
  139.             //去空、验证  
  140.             if(isEmpty(colValue)){  
  141.                 validate.addResult(colName+ValidateFileUpload.VALIDATE_NULL, rowNumber, colValue);  
  142.                 return false;  
  143.             }else if(!TskfOrg.ORG_TYPE.contains(colValue)){  
  144.                 validate.addResult(colName+ValidateFileUpload.VALIDATE_INVALID, rowNumber, colValue);  
  145.                 return false;  
  146.             }else{  
  147.                 bean.setOrgType(colValue);  
  148.             }  
  149.         }else if(TskfOrg.ROW_ORG_LEVEL.equals(colName)){  
  150.             bean.setOrgLevel(colValue);  
  151.         }else if(TskfOrg.ROW_ORG_PROPERTY.equals(colName)){  
  152.             bean.setOrgProperty(colValue);  
  153.         }else if(TskfOrg.ROW_ORG_CHANNEL.equals(colName)){  
  154.             bean.setOrgChannel(colValue);  
  155.         }else if(TskfOrg.ROW_CREATE_DATE.equals(colName)){  
  156.             if(!isEmpty(colValue)){  
  157.                 Date date = formatDate(colValue, colName, rowNumber, validate);  
  158.                 if(null != date){  
  159.                     bean.setCreateDate(date);  
  160.                 }else{  
  161.                     return false;  
  162.                 }  
  163.             }  
  164.               
  165.         }else if(TskfOrg.ROW_UPDATE_MONTH.equals(colName)){  
  166.             bean.setUpdateMonth(colValue);  
  167.         }else{  
  168.             validate.addResult(ValidateFileUpload.VALIDATE_INVALID+colName, rowNumber, colValue);  
  169.             return false;  
  170.         }  
  171.         /************ 字段验证 end *************/  
  172.         return true;  
  173.     }  
  174.   
  175.     /* (non-Javadoc) 
  176.      * @see com.asc.console.fileupload.FileUploadModel#init() 
  177.      */  
  178.     public void init() {  
  179.         validate =  new ValidateFileUpload<TskfOrg>();  
  180.         //validate.getMap().put("ORG_CODE",new HashMap<String,TskfOrg>());  
  181.     }  
  182.   
  183.       
  184.     @SuppressWarnings("unchecked")  
  185.     public void end() {  
  186.         /************ 校验数据 start **********/  
  187.         //自身去重  
  188.         StringBuffer tempDirtySQL = new StringBuffer();  
  189.         tempDirtySQL.append(" WHERE ORG_CODE IN (");  
  190.         tempDirtySQL.append("   SELECT ORG_CODE FROM ").append(tempTable);  
  191.         tempDirtySQL.append("   GROUP BY ORG_CODE");  
  192.         tempDirtySQL.append("   HAVING COUNT(1) > 1");  
  193.         tempDirtySQL.append(") AND ID NOT IN (");  
  194.         tempDirtySQL.append("   SELECT MIN(ID) FROM ").append(tempTable);  
  195.         tempDirtySQL.append("   GROUP BY ORG_CODE");  
  196.         tempDirtySQL.append("   HAVING COUNT(1) > 1");  
  197.         tempDirtySQL.append(")");  
  198.         List<Map<String, Object>>  tempDirtyList= getJdbcTemplate().queryForList("SELECT ORG_CODE, EXCEL_ROW_NUMBER FROM "+ tempTable + tempDirtySQL+" AND ROWNUM <= 100");  
  199.         addValidateResult(tempDirtyList,ValidateFileUpload.VALIDATE_REPEATED+TskfOrg.ROW_ORG_CODE  
  200.                 + "(仅显示100条)","EXCEL_ROW_NUMBER","ORG_CODE");  
  201.         if (null != tempDirtyList && tempDirtyList.size() > 0) {  
  202.             getJdbcTemplate().update("DELETE "+ tempTable + tempDirtySQL);  
  203.         }  
  204.           
  205.         //对比去重  
  206.         StringBuffer compareDirtySQL = new StringBuffer();  
  207.         compareDirtySQL.append(" LEFT JOIN ").append(tableName).append(" T ON (").append(tempTable).append(".ORG_CODE = T.ORG_CODE)");  
  208.         compareDirtySQL.append(" WHERE T.ORG_CODE IS NOT NULL");  
  209.         compareDirtySQL.append(" AND ROWNUM <= 100");  
  210.         List<Map<String, Object>>  compareDirtyList = getJdbcTemplate().queryForList("SELECT "+tempTable+".ORG_CODE, "+tempTable+".EXCEL_ROW_NUMBER FROM "+ tempTable + compareDirtySQL);  
  211.         addValidateResult(compareDirtyList, TskfOrg.ROW_ORG_CODE  
  212.                 + ValidateFileUpload.VALIDATE_EXIST  
  213.                 + "(仅显示100条)""EXCEL_ROW_NUMBER""ORG_CODE");  
  214.         /************ 校验数据 end **********/  
  215.           
  216.         StringBuffer insertSQL = new StringBuffer();  
  217.         insertSQL.append("INSERT INTO ").append(tableName);  
  218.         insertSQL.append(" (").append(COLUMNS).append(")");  
  219.         insertSQL.append(" SELECT ").append(TskfOrgModel.COLUMNS.replaceFirst("ID", tempTable+".ID").replaceAll(","","+tempTable+"."));  
  220.         insertSQL.append(" FROM ").append(tempTable);  
  221.         insertSQL.append(" LEFT JOIN ").append(tableName).append(" T ON (").append(tempTable).append(".ORG_CODE = T.ORG_CODE)");  
  222.         insertSQL.append(" WHERE T.ORG_CODE IS NULL");  
  223.         int total = getJdbcTemplate().update(insertSQL.toString());  
  224.         validate.setTotal(total);  
  225.           
  226.         setNull(tempDirtySQL,tempDirtyList,compareDirtySQL,compareDirtyList,insertSQL);  
  227.         TskfOrgModel.setLock(false);  
  228.     }  
  229.       
  230. }  

测试方法
  1. TskfOrgModel mode = new TskfOrgModel();  
  2. mode.setDataSource(getDataSource());  
  3. mode.setTableName("TSKF_ORG");  
  4. mode.setTempTable("TEMP_TSKF_ORG");  
  5. mode.setReqeust(request);  
  6. mode.process(fileStream);//开始处理  
  7.   
  8. ValidateFileUpload<TskfOrg> validate = mode.getValidate();  
  9. validate.addResult("保存成功", validate.getTotal(), ""1);  
  10. response.getWriter().write("{success: true,msg:'上传成功',data:"+JsonUtil.toJson(validate.getValidateInfo(),"-class")+"}");  

附SAX读Excel生成的xml格式:

  1. <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">  
  2.     <dimension ref="A1:C2"/>  
  3.     <sheetViews>  
  4.         <sheetView tabSelected="1" workbookViewId="0">  
  5.         <selection activeCell="A2" sqref="A2"/></sheetView>  
  6.     </sheetViews>  
  7.     <sheetFormatPr defaultRowHeight="13.5"/>  
  8.         <cols>  
  9.             <col min="1" max="1" width="15.375" customWidth="1"/>  
  10.             <col min="2" max="2" width="19.25" customWidth="1"/>  
  11.             <col min="3" max="3" width="13.75" customWidth="1"/>  
  12.         </cols>  
  13.     <sheetData>  
  14.         <row r="1" spans="1:3">  
  15.             <c r="A1" s="1" t="s">  
  16.                 <v>0</v>  
  17.             </c>  
  18.             <c r="B1" s="1"/>  
  19.             <c r="C1" s="1">  
  20.                 <v>111.1</v>  
  21.             </c>  
  22.         </row>  
  23.         <row r="2" spans="1:3">  
  24.             <c r="C2">  
  25.                 <v>222.2</v>  
  26.             </c>  
  27.         </row>  
  28.     </sheetData>  
  29.     <phoneticPr fontId="1" type="noConversion"/>  
  30.     <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>  
  31.     <pageSetup paperSize="9" orientation="portrait" horizontalDpi="200" verticalDpi="200" r:id="rId1"/>  
  32. </worksheet>  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值