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


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

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

    1. package com.chinait.utils;
    2. /**
    3. * 写这个东西主要是最近做了一个联通的数据迁移工作,他们就是这样导出的数据,所以我们写了这个代码。
    4. * 还有一个就是网上n 多都是半成品,代码不能直接运行,我这个代码能够直接运行。
    5. * java poi 之sax 解析10万级大数量数据,其实百万,千万都是可以的,
    6. * 但是想到这么大的数据一般不会使用excel 进行导入数据的行为,所以我采用了这个方法只是针对于10万级数据,
    7. * 宁外,虚拟机的堆内存需要设置大一些,不然会报内存溢出。
    8. * 支持多个sheet 数据一起导入
    9. * 支持按照数据量范围取值
    10. */
    11. import java.io.InputStream;
    12. import java.util.ArrayList;
    13. import java.util.Iterator;
    14. import java.util.LinkedHashMap;
    15. import java.util.List;
    16. import java.util.Map;
    17. import java.util.Map.Entry;
    18. import java.util.regex.Pattern;
    19. import org.apache.commons.lang.StringUtils;
    20. import org.apache.poi.openxml4j.opc.OPCPackage;
    21. import org.apache.poi.xssf.eventusermodel.XSSFReader;
    22. import org.apache.poi.xssf.model.SharedStringsTable;
    23. import org.apache.poi.xssf.usermodel.XSSFRichTextString;
    24. import org.xml.sax.Attributes;
    25. import org.xml.sax.ContentHandler;
    26. import org.xml.sax.InputSource;
    27. import org.xml.sax.SAXException;
    28. import org.xml.sax.XMLReader;
    29. import org.xml.sax.helpers.DefaultHandler;
    30. import org.xml.sax.helpers.XMLReaderFactory;
    31. public class MyExcel2007ForPaging_high {
    32. private static List<Map<String,String>> dataListT;
    33. private final int startRow;
    34. private final int endRow;
    35. private int currentRow = 0;
    36. private final String filename;
    37. private static Map<String,String> map;
    38. static char[] strChar ;
    39. /**
    40. * 构造方法
    41. */
    42. public MyExcel2007ForPaging_high(String filename,int startRow,int endRow) throws Exception{
    43. dataListT = new ArrayList<>();
    44. if(StringUtils.isEmpty(filename)) throw new Exception("文件名不能空");
    45. this.filename = filename;
    46. this.startRow = startRow;
    47. this.endRow = endRow+1;
    48. processSheet();
    49. }
    50. /**
    51. * 指定获取第一个sheet
    52. * @param filename
    53. * @throws Exception
    54. */
    55. private void processSheet() throws Exception {
    56. OPCPackage pkg = OPCPackage.open(filename);
    57. XSSFReader r = new XSSFReader( pkg );
    58. SharedStringsTable sst = r.getSharedStringsTable();
    59. XMLReader parser = fetchSheetParser(sst);
    60. Iterator<InputStream> it = r.getSheetsData();
    61. while(it.hasNext()){
    62. map = null;
    63. InputStream sheet1 = it.next();
    64. InputSource sheetSource = new InputSource(sheet1);
    65. parser.parse(sheetSource);
    66. sheet1.close();
    67. }
    68. }
    69. /**
    70. * 加载sax 解析器
    71. * @param sst
    72. * @return
    73. * @throws SAXException
    74. */
    75. private XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
    76. XMLReader parser =
    77. XMLReaderFactory.createXMLReader(
    78. "org.apache.xerces.parsers.SAXParser"
    79. );
    80. ContentHandler handler = new PagingHandler(sst);
    81. parser.setContentHandler(handler);
    82. return parser;
    83. }
    84. /**
    85. * See org.xml.sax.helpers.DefaultHandler javadocs
    86. */
    87. private class PagingHandler extends DefaultHandler {
    88. private SharedStringsTable sst;
    89. private String lastContents;
    90. private boolean nextIsString;
    91. private String index = null;
    92. private PagingHandler(SharedStringsTable sst) {
    93. this.sst = sst;
    94. }
    95. /**
    96. * 开始元素 (获取key 值)
    97. */
    98. @Override
    99. public void startElement(String uri, String localName, String name,
    100. Attributes attributes) throws SAXException {
    101. if(name.equals("c")) {
    102. index = attributes.getValue("r");
    103. //判断是否是新的一行
    104. if(Pattern.compile("^A[0-9]+$").matcher(index).find()){
    105. if(map!=null&&isAccess()&&!map.isEmpty()){
    106. dataListT.add(map);
    107. }
    108. map = new LinkedHashMap<>();
    109. currentRow++;
    110. }
    111. if(isAccess()){
    112. String cellType = attributes.getValue("t");
    113. if(cellType != null && cellType.equals("s")) {
    114. nextIsString = true;
    115. } else {
    116. nextIsString = false;
    117. }
    118. }
    119. }
    120. lastContents = "";
    121. }
    122. /**
    123. * 获取value
    124. */
    125. @Override
    126. public void endElement(String uri, String localName, String name)
    127. throws SAXException {
    128. if(isAccess()){
    129. if(nextIsString) {
    130. int idx = Integer.parseInt(lastContents);
    131. lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
    132. nextIsString = false;
    133. }
    134. if(name.equals("v")) {
    135. map.put(index, lastContents);
    136. }
    137. }
    138. }
    139. @Override
    140. public void characters(char[] ch, int start, int length)
    141. throws SAXException {
    142. if(isAccess()){
    143. lastContents += new String(ch, start, length);
    144. }
    145. }
    146. @Override
    147. public void endDocument ()throws SAXException{
    148. if(map!=null&&isAccess()&&!map.isEmpty()){
    149. dataListT.add(map);
    150. }
    151. }
    152. }
    153. private boolean isAccess(){
    154. if(currentRow>=startRow¤tRow<=endRow){
    155. return true;
    156. }
    157. return false;
    158. }
    159. /**
    160. * 获取数据 并且填补字段值为空的数据
    161. * @return
    162. * @throws Exception
    163. */
    164. public List<Map<String,String>> getMyDataList() throws Exception{
    165. List<Map<String,String>> list = dataListT.subList(startRow, dataListT.size());
    166. if(!list.isEmpty()){
    167. Map<String,String> map = dataListT.get(0);
    168. List<String> com = data("A",map.size()-1);
    169. for(int i=0;i<list.size();i++){
    170. Map<String,String> returnMap = list.get(i);
    171. for(String str:com){
    172. boolean flag = true;
    173. for(Entry<String,String> entry:returnMap.entrySet()){
    174. if(entry.getKey().contains(str)){
    175. //有
    176. flag = false;
    177. break;
    178. }
    179. }
    180. if(flag){
    181. //没有
    182. returnMap.put(str+(i+2), null);
    183. }
    184. }
    185. }
    186. }
    187. return list;
    188. }
    189. public static void main(String[] args) throws Exception {
    190. MyExcel2007ForPaging_high reader = new MyExcel2007ForPaging_high("D://20000.xlsx",1,30000);
    191. reader.getMyDataList();
    192. }
    193. /**
    194. * 封装数据
    195. * @param str
    196. * @param counts
    197. * @return
    198. */
    199. public static List<String> data(String str,int counts){
    200. List<String> list = new ArrayList<>();
    201. list.add(str);
    202. for(int i=0;i<counts;i++){
    203. strChar = str.toCharArray();
    204. jinwei(0);
    205. str = new String(strChar);
    206. list.add(str);
    207. }
    208. return list;
    209. }
    210. //数字进位
    211. public static void jinwei(int index){
    212. char a = 'A';
    213. int aint =(int)('A');
    214. if((strChar.length-1)-index>=0){
    215. int sc = (int)strChar[(strChar.length-1)-index];
    216. if(sc- 25 >= aint){
    217. jinwei(index+1);
    218. strChar[(strChar.length-1)-index] = a;
    219. }else{
    220. strChar[strChar.length-1-index] = (char)(sc+1);
    221. }
    222. }else{
    223. strChar[(strChar.length-1)-index+1] = a;
    224. StringBuilder str = new StringBuilder();
    225. str.append('A');
    226. str.append(strChar);
    227. strChar = str.toString().toCharArray();
    228. }
    229. }
    230. }
    这是输出结果:

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

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

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

    原文地址:https://blog.csdn.net/sai739295732/article/details/68489403
  • 相关阅读:
    Runner站立会议07
    Runner站立会议06
    “记计帐”需求分析
    Runner站立会议03
    Runner站立会议02
    2016年秋季个人阅读计划
    梦断代码阅读笔记03
    进度条15
    梦断代码阅读笔记02
    软件工程概论课程总结
  • 原文地址:https://www.cnblogs.com/jpfss/p/10931938.html
Copyright © 2020-2023  润新知