JAVA Apache POI 之sax 解析10万级大数量数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 数据一起导入。
支持按照数据量范围取值。
支持原创,支持代码能运行的原创,谢谢!~
原文地址:https://blog.csdn.net/sai739295732/article/details/68489403
以上是关于JAVA Apache POI 之sax 解析10万级大数量数据的主要内容,如果未能解决你的问题,请参考以下文章
使用POI解析Excel时,出现org.xml.sax.SAXParseException: duplicate attribute 'o:relid'的解决办法
POI以SAX方式解析Excel2007大文件(包含空单元格的处理) Java生成CSV文件实例详解