<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java解析excel文件大數據量時,報OOM異常問題。

      在解析EXCEL,JAVA 通常使用poi包下的 XSSFWorkbook 對象,但是,遇到海量數據(比如十幾萬條 或者 JVM堆設置了內存比較小時),就會拋出OOM異常,下面就放出解決方法。

      直接上代碼:

      package com.xxx.xxx.xxx.common.util;
      
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.ArrayList;
      import java.util.List;
      import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
      import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
      import org.apache.poi.openxml4j.opc.OPCPackage;
      import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
      import org.apache.poi.xssf.eventusermodel.XSSFReader;
      import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
      import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
      import org.apache.poi.xssf.model.StylesTable;
      import org.apache.poi.xssf.usermodel.XSSFComment;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.stereotype.Component;
      import org.xml.sax.InputSource;
      import org.xml.sax.SAXException;
      import org.xml.sax.XMLReader;
      import org.xml.sax.helpers.XMLReaderFactory;
      
      /**
       * @author Jimmy Shan
       * @date 2021-04-09
       * @desc 解析大數據量excel文件,避免OOM發生
       */
      @Component
      public class ExcelParserBigData {
          private static final Logger logger = LoggerFactory.getLogger(ExcelParserBigData.class);
          private ISheetContentHandler contentHandler = new DefaultSheetHandler(); //表格默認處理器
          private List<String[]> datas = new ArrayList<String[]>(); //讀取數據
      
          /**
           * @desc 轉換表格,默認為轉換第一個表格
           */
          public ExcelParserBigData parse(InputStream stream)
                  throws InvalidFormatException, IOException, ParseException {
              return parse(stream, 1);
          }
      
          /**
           * @desc 解析方法
           */
          public synchronized ExcelParserBigData parse(InputStream stream, int sheetId)
                  throws InvalidFormatException, IOException, ParseException {
              // 每次轉換前都清空數據
              datas.clear();
              // 打開表格文件輸入流
              OPCPackage pkg = OPCPackage.open(stream);
              try {
                  // 創建表閱讀器
                  XSSFReader reader;
                  try {
                      reader = new XSSFReader(pkg);
                  } catch (OpenXML4JException e) {
                      logger.error("讀取表格出錯");
                      throw new ParseException(e.fillInStackTrace());
                  }
      
                  // 轉換指定單元表
                  InputStream shellStream = reader.getSheet("rId" + sheetId);
                  try {
                      InputSource sheetSource = new InputSource(shellStream);
                      StylesTable styles = reader.getStylesTable();
                      ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(pkg);
                      getContentHandler().init(datas);// 設置讀取出的數據
                      // 獲取轉換器
                      XMLReader parser = getSheetParser(styles, strings);
                      parser.parse(sheetSource);
                  } catch (SAXException e) {
                      logger.error("讀取表格出錯");
                      throw new ParseException(e.fillInStackTrace());
                  } finally {
                      shellStream.close();
                  }
              } finally {
                  pkg.close();
              }
      
              return this;
          }
      
          /**
           * @desc 獲取表格讀取數據,獲取數據前,需要先轉換數據,此方法不會獲取第一行數據,表格讀取數據
           */
          public List<String[]> getDatas() {
              return getDatas(true);
          }
      
          /**
           * @desc 獲取表格讀取數據,獲取數據前,需要先轉換數據
           */
          public List<String[]> getDatas(boolean dropFirstRow) {
              if (dropFirstRow && datas.size() > 0) {
                  datas.remove(0);// 刪除表頭
              }
      
              return datas;
          }
      
          /**
           * @desc 獲取讀取表格的轉換器
           */
          protected XMLReader getSheetParser(StylesTable styles, ReadOnlySharedStringsTable strings) throws SAXException {
              XMLReader parser = XMLReaderFactory.createXMLReader();
              parser.setContentHandler(new XSSFSheetXMLHandler(styles, strings, getContentHandler(), false));
      
              return parser;
          }
      
          public ISheetContentHandler getContentHandler() {
              return contentHandler;
          }
      
          public void setContentHandler(ISheetContentHandler contentHandler) {
              this.contentHandler = contentHandler;
          }
      
          /**
           * @desc 表格轉換錯誤
           */
          public class ParseException extends Exception {
              private static final long serialVersionUID = -2451526411018517607L;
      
              public ParseException(Throwable t) {
                  super("表格轉換錯誤", t);
              }
          }
      
          public interface ISheetContentHandler extends SheetContentsHandler {
              /**
               * @desc 設置轉換后的數據集,用于存放轉換結果
               */
              void init(List<String[]> datas);
          }
      
          /**
           * @desc 默認表格解析handder
           */
          class DefaultSheetHandler implements ISheetContentHandler {
              /**
               * @desc 讀取數據
               */
              private List<String[]> datas;
              private int columsLength;
              private String[] readRow;
              private ArrayList<String> fristRow = new ArrayList<String>();
      
              @Override
              public void init(List<String[]> datas) {
                  this.datas = datas;
                  //this.columsLength = columsLength;
              }
      
              @Override
              public void startRow(int rowNum) {
                  if (rowNum != 0) {
                      readRow = new String[columsLength];
                  }
              }
      
              @Override
              public void endRow(int rowNum) {
                  //將Excel第一行表頭的列數當做數組的長度,要保證后續的行的列數不能超過這個長度,這是個約定。
                  if (rowNum == 0) {
                      columsLength = fristRow.size();
                      readRow = fristRow.toArray(new String[fristRow.size()]);
                  }else {
                      readRow = fristRow.toArray(new String[columsLength]);
                  }
                  datas.add(readRow.clone());
                  readRow = null;
                  fristRow.clear();
              }
      
              @Override
              public void cell(String cellReference, String formattedValue, XSSFComment comment) {
                  int index = getCellIndex(cellReference);//轉換A1,B1,C1等表格位置為真實索引位置
                  try {
                      fristRow.set(index, formattedValue);
                  } catch (IndexOutOfBoundsException e) {
                      int size = fristRow.size();
                      for (int i = index - size+1;i>0;i--){
                          fristRow.add(null);
                      }
                      fristRow.set(index,formattedValue);
                  }
              }
      
              @Override
              public void headerFooter(String text, boolean isHeader, String tagName) {
              }
      
              /**
               * @desc 轉換表格引用為列編號
               */
              public int getCellIndex(String cellReference) {
                  String ref = cellReference.replaceAll("\\d+", "");
                  int num = 0;
                  int result = 0;
                  for (int i = 0; i < ref.length(); i++) {
                      char ch = cellReference.charAt(ref.length() - i - 1);
                      num = (int) (ch - 'A' + 1);
                      num *= Math.pow(26, i);
                      result += num;
                  }
                  return result - 1;
              }
          }
      }
      

       

      調用方:

      package com.xxx.xxx.xxx.service.impl;
      
      import com.xxx.xxx.xxx.common.util.ExcelParserBigData;
      import com.xxx.xxx.xxx.service.DemoBaseService;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      import java.io.FileInputStream;
      import java.util.List;
      
      /**
       * @author Jimmy Shan
       * @date 2021-04-07
       * @desc 示例 服務實現
       */
      @Service("demoBaseService")
      public class DemoBaseServiceImpl implements DemoBaseService {
          private static final Logger LOGGER = LoggerFactory.getLogger(DemoBaseServiceImpl.class);
          @Autowired
          private ExcelParserBigData excelParserBigData;
      
          /**
           * @desc 解析大數據量excel文件
           */
          @Override
          public void parseBigXlsx(String upPathName) {
              long start = System.currentTimeMillis();
              FileInputStream inf = null;
              try {
                  inf = new FileInputStream(upPathName);
                  ExcelParserBigData parseBigData = excelParserBigData.parse(inf);
                  List<String[]> dataList = parseBigData.getDatas(); //這里的List泛型是String數組,解析后的數據是以 數組形式存放的。
                  for (int i = 0; i < dataList.size(); i++) {
                      String[] str = dataList.get(i);
                      LOGGER.info("第 {} 行", (i +1));
                      LOGGER.info("oppoId = {}, oppoName = {}", str[0], str[1]);
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  try {
                      if(inf != null) {
                          inf.close();
                      }
                      LOGGER.info("解析總耗時:{} 毫秒", (System.currentTimeMillis() - start));
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }
      }
      

       

      接口定義:

      package com.xxx.xxx.xxx.service;
      
      /**
       * @author Jimmy Shan
       * @date 2021-04-07
       * @desc 示例 服務
       */
      public interface DemoBaseService {
          /**
           * @desc 解析大數據量excel文件
           */
          void parseBigXlsx(String upPathName);
      }
      

       

      OK,記錄到此。

       

      posted @ 2021-04-09 20:32  JimmyShan  閱讀(2268)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 国产精品综合在线免费看| 亚洲一区中文字幕第十页| 欧美精欧美乱码一二三四区| 日本免费人成视频在线观看| 人妻系列中文字幕精品| 新安县| 亚洲码与欧洲码区别入口| 久久精品国产蜜臀av| 国产麻花豆剧传媒精品mv在线| 免费看黄色亚洲一区久久| av色国产色拍| 天天爽夜夜爽人人爽一区二区| 欧美xxxxhd高清| 精品国产一区二区三区性色| 国产精品久久一区二区三区| 午夜综合网| 国产成人不卡一区二区| 甘孜县| 日韩精品 在线 国产 丝袜| 久久被窝亚洲精品爽爽爽| 亚洲熟妇自偷自拍另欧美| 国产精品国产精品偷麻豆| 人妻精品动漫h无码| 亚洲天堂一区二区三区四区| 无套内谢少妇一二三四| 国内不卡一区二区三区| 精品精品久久宅男的天堂| 色五月丁香六月欧美综合| 国产一区国产二区在线视频 | 免费国产高清在线精品一区| 国产女人18毛片水真多1| 中文字幕av中文字无码亚| 99久久激情国产精品| 精品人妻中文字幕在线| 丰满岳乱妇久久久| 97人妻免费碰视频碰免| 亚洲av熟女国产一二三| 中文字幕国产精品av| 樟树市| 国产AV国片精品有毛| 狠狠色婷婷久久综合频道日韩|