JAVA Apache POI 之sax 解析10万级大数量数据

第一步让我们来看看我们的大量数据的excel 文件

好的下面第二步看一下代码:

package com.chinait.utils;  
  
/**
 * 写这个东西主要是最近做了一个联通的数据迁移工作,他们就是这样导出的数据,所以我们写了这个代码。
 * 还有一个就是网上n 多都是半成品,代码不能直接运行,我这个代码能够直接运行。
 * java poi 之sax 解析10万级大数量数据,其实百万,千万都是可以的,
 * 但是想到这么大的数据一般不会使用excel 进行导入数据的行为,所以我采用了这个方法只是针对于10万级数据,
 * 宁外,虚拟机的堆内存需要设置大一些,不然会报内存溢出。
 * 支持多个sheet 数据一起导入
 * 支持按照数据量范围取值
 */
  
import java.io.InputStream;  
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;  
  
import org.apache.commons.lang.StringUtils;  
import org.apache.poi.openxml4j.opc.OPCPackage;  
import org.apache.poi.xssf.eventusermodel.XSSFReader;  
import org.apache.poi.xssf.model.SharedStringsTable;  
import org.apache.poi.xssf.usermodel.XSSFRichTextString;  
import org.xml.sax.Attributes;  
import org.xml.sax.ContentHandler;  
import org.xml.sax.InputSource;  
import org.xml.sax.SAXException;  
import org.xml.sax.XMLReader;  
import org.xml.sax.helpers.DefaultHandler;  
import org.xml.sax.helpers.XMLReaderFactory;  
  
public class MyExcel2007ForPaging_high {  
        private static List<Map<String,String>> dataListT;
        private final int startRow;  
        private final int endRow;  
        private int currentRow = 0;  
        private final String filename;  
        private static Map<String,String> map;
        static char[] strChar ;  
        /**
         * 构造方法
         */
        public MyExcel2007ForPaging_high(String filename,int startRow,int endRow) throws Exception{
        	dataListT = new ArrayList<>();
            if(StringUtils.isEmpty(filename)) throw new Exception("文件名不能空");  
            this.filename = filename;  
            this.startRow = startRow;  
            this.endRow = endRow+1;  
            processSheet();  
        }  
        /** 
         * 指定获取第一个sheet 
         * @param filename 
         * @throws Exception 
         */  
        private void processSheet() throws Exception {  
            OPCPackage pkg = OPCPackage.open(filename);  
            XSSFReader r = new XSSFReader( pkg );  
            SharedStringsTable sst = r.getSharedStringsTable();  
            XMLReader parser = fetchSheetParser(sst);   
            Iterator<InputStream> it = r.getSheetsData();
            while(it.hasNext()){
            	 map = null;
            	 InputStream sheet1 = it.next();  
                 InputSource sheetSource = new InputSource(sheet1);  
                 parser.parse(sheetSource);  
                 sheet1.close();  
            }
        }  
        /**
         * 加载sax 解析器
         * @param sst
         * @return
         * @throws SAXException
         */
        private XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {  
            XMLReader parser =  
                XMLReaderFactory.createXMLReader(  
                        "org.apache.xerces.parsers.SAXParser"  
                );  
            ContentHandler handler = new PagingHandler(sst);  
            parser.setContentHandler(handler);  
            return parser;  
        }  
  
        /**  
         * See org.xml.sax.helpers.DefaultHandler javadocs  
         */  
        private  class PagingHandler extends DefaultHandler {  
            private SharedStringsTable sst;  
            private String lastContents;  
            private boolean nextIsString;  
            private String index = null;  
            private PagingHandler(SharedStringsTable sst) {  
                this.sst = sst;  
            }
            /**
             * 开始元素 (获取key 值)
             */
            @Override  
            public void startElement(String uri, String localName, String name,  
                    Attributes attributes) throws SAXException {  
                if(name.equals("c")) {
                    index = attributes.getValue("r");
                    //判断是否是新的一行
                    if(Pattern.compile("^A[0-9]+$").matcher(index).find()){  
                        if(map!=null&&isAccess()&&!map.isEmpty()){  
                        	dataListT.add(map);
                        }
                        map = new LinkedHashMap<>();
                        currentRow++; 
                    }  
                    if(isAccess()){  
                        String cellType = attributes.getValue("t");  
                        if(cellType != null && cellType.equals("s")) {  
                            nextIsString = true;  
                        } else {  
                            nextIsString = false;  
                        }  
                    }  
                }  
                lastContents = "";  
            }  
            /**
             * 获取value 
             */
            @Override  
            public void endElement(String uri, String localName, String name)  
                    throws SAXException {  
                if(isAccess()){  
                    if(nextIsString) {  
                        int idx = Integer.parseInt(lastContents);  
                        lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();  
                        nextIsString = false;  
                    }  
                    if(name.equals("v")) {  
                    	map.put(index, lastContents);
                    }  
                }  
                  
            }  
            @Override  
            public void characters(char[] ch, int start, int length)  
                    throws SAXException {  
                if(isAccess()){  
                    lastContents += new String(ch, start, length);  
                }  
            }  
            @Override  
            public void endDocument ()throws SAXException{  
                if(map!=null&&isAccess()&&!map.isEmpty()){
                	dataListT.add(map);
                }  
            }  
          
        }  
        private boolean isAccess(){  
            if(currentRow>=startRow¤tRow<=endRow){  
                return true;  
            }  
            return false;  
        }
        /**
         * 获取数据 并且填补字段值为空的数据
         * @return
         * @throws Exception
         */
        public List<Map<String,String>> getMyDataList() throws Exception{
        	List<Map<String,String>> list = dataListT.subList(startRow, dataListT.size());
        	if(!list.isEmpty()){
        		Map<String,String> map = dataListT.get(0);
        		List<String> com = data("A",map.size()-1);
        		for(int i=0;i<list.size();i++){
        			Map<String,String> returnMap = list.get(i);
        			for(String str:com){
        				boolean flag = true;
        				for(Entry<String,String> entry:returnMap.entrySet()){
        					if(entry.getKey().contains(str)){
        						//有
        						flag = false;
        						break;
        					}
        				}
        				if(flag){
	        				//没有
        					returnMap.put(str+(i+2), null);
        				}
        			}
        		}
        	}
            return list;  
        }  
       
        public static void main(String[] args) throws Exception {
        	MyExcel2007ForPaging_high reader = new MyExcel2007ForPaging_high("D://20000.xlsx",1,30000);  
            reader.getMyDataList();
        }
        /**
         * 封装数据
         * @param str
         * @param counts
         * @return
         */
        public static List<String> data(String str,int counts){
        	List<String> list = new ArrayList<>();
        	list.add(str);
            for(int i=0;i<counts;i++){  
                strChar = str.toCharArray();  
                jinwei(0);  
                str = new String(strChar);  
                list.add(str);
            }
            return list;
        }
        //数字进位
        public static void jinwei(int index){
        	char a = 'A';
        	int aint =(int)('A');
        	if((strChar.length-1)-index>=0){
        		int sc = (int)strChar[(strChar.length-1)-index];
        		if(sc- 25 >= aint){
        			jinwei(index+1);
        			strChar[(strChar.length-1)-index] = a;
        		}else{
        			strChar[strChar.length-1-index] = (char)(sc+1);
        		}
        	}else{
        		strChar[(strChar.length-1)-index+1] = a;
        		StringBuilder str = new StringBuilder();
        		str.append('A');
        		str.append(strChar);
        		strChar = str.toString().toCharArray();
        	}
        }  
} 
这是输出结果:

 写这个东西主要是最近做了一个联通的数据迁移工作,他们就是这样导出的数据,所以我们写了这个代码。

还有一个就是网上n 多都是半成品,代码不能直接运行,我这个代码能够直接运行。
java poi 之sax 解析10万级大数量数据,其实百万,千万都是可以的。
但是想到这么大的数据一般不会使用excel 进行导入数据的行为,所以我采用了这个方法只是针对于10万级数据。
宁外,虚拟机的堆内存需要设置大一些,不然会报内存溢出。
支持多个sheet 数据一起导入。
支持按照数据量范围取值。

支持原创,支持代码能运行的原创,谢谢!~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值