国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

POI Sax 事件驅(qū)動解析Excel2007文件(較大數(shù)據(jù)量的讀存導(dǎo)出)

cod7ce / 409人閱讀

摘要:方式解析全稱,它是一個(gè)接口,也是一個(gè)軟件包。另外,推模型可用于廣播環(huán)境,能夠同時(shí)注冊多個(gè),并行接收事件,而不是在一個(gè)管道中一個(gè)接一個(gè)地進(jìn)行處理。這些語法分析器是最靈活的,因?yàn)樗鼈冞€支持。

xcel2007版本的代碼如下,本文主要是用于POI解析大文件Excel容易出現(xiàn)內(nèi)存溢出的現(xiàn)象而提出解決方案,故此解決了大數(shù)據(jù)量的Excel文件解析的難度,在此拿出來貢獻(xiàn)給大家,謝謝!

1.Office2007與Office Open XML

在Office 2007之前,Office一直都是以二進(jìn)制位的方式存儲,但這種格式不易被其它軟件拿來使用,在各界的壓力下,MicroSoft于2005年發(fā)布了基于XML的ooxml開放文檔標(biāo)準(zhǔn)。ooxml的xml schema強(qiáng)調(diào)減少load time,增快parsing speed,將child elements分開存儲,而不是multiple attributes一起存,這有點(diǎn)類似于HTML的結(jié)構(gòu)。ooxml 使用XML和ZIP技術(shù)結(jié)合進(jìn)行文件存儲,因?yàn)閄ML是一個(gè)基于文本的格式,而且ZIP容器支持內(nèi)容的壓縮,所以其一大優(yōu)勢就是可以大大減小文件的尺寸。其它特點(diǎn)這里不再敘述。

2.SAX方式解析XML

SAX全稱Simple API for XML,它是一個(gè)接口,也是一個(gè)軟件包。它是一種XML解析的替代方法,不同于DOM解析XML文檔時(shí)把所有內(nèi)容一次性加載到內(nèi)存中的方式,它逐行掃描文檔,一邊掃描,一邊解析。所以那些只需要單遍讀取內(nèi)容的應(yīng)用程序就可以從SAX解析中受益,這對大型文檔的解析是個(gè)巨大優(yōu)勢。另外,SAX “推" 模型可用于廣播環(huán)境,能夠同時(shí)注冊多個(gè)ContentHandler,并行接收事件,而不是在一個(gè)管道中一個(gè)接一個(gè)地進(jìn)行處理。一些支持 SAX 的語法分析器包括 Xerces,Apache parser(以前的 IBM 語法分析器)、MSXML(Microsoft 語法分析器)和 XDK(Oracle 語法分析器)。這些語法分析器是最靈活的,因?yàn)樗鼈冞€支持 DOM。

3.POI以SAX解析excel2007文件

所需jar包:
poi-3.10-FINAL-20140208.jar,
poi-ooxml-3.10-FINAL-20140208.jar,
poi-ooxml-schemas-3.10-FINAL-20140208.jar
xercesImpl.jar
xml-apis-2.0.2.jar
xmlbeans-2.6.0.jar
sax2.jar

package com.boguan.bte.util.excel;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
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;

import com.boguan.bte.service.common.IExcelRowReader;
import com.boguan.bte.service.common.impl.ExcelRowReader;

/**
 * 名稱: ExcelXlsxReader.java
* 描述:
* 類型: JAVA
* 最近修改時(shí)間:2016年7月5日 上午10:00:52
* * @since 2016年7月5日 * @author “” */ public class ExcelXlsxReader extends DefaultHandler { private IExcelRowReader rowReader; public void setRowReader(IExcelRowReader rowReader) { this.rowReader = rowReader; } /** * 共享字符串表 */ private SharedStringsTable sst; /** * 上一次的內(nèi)容 */ private String lastContents; /** * 字符串標(biāo)識 */ private boolean nextIsString; /** * 工作表索引 */ private int sheetIndex = -1; /** * 行集合 */ private List rowlist = new ArrayList(); /** * 當(dāng)前行 */ private int curRow = 0; /** * 當(dāng)前列 */ private int curCol = 0; /** * T元素標(biāo)識 */ private boolean isTElement; /** * 異常信息,如果為空則表示沒有異常 */ private String exceptionMessage; /** * 單元格數(shù)據(jù)類型,默認(rèn)為字符串類型 */ private CellDataType nextDataType = CellDataType.SSTINDEX; private final DataFormatter formatter = new DataFormatter(); private short formatIndex; private String formatString; // 定義前一個(gè)元素和當(dāng)前元素的位置,用來計(jì)算其中空的單元格數(shù)量,如A6和A8等 private String preRef = null, ref = null; // 定義該文檔一行最大的單元格數(shù),用來補(bǔ)全一行最后可能缺失的單元格 private String maxRef = null; /** * 單元格 */ private StylesTable stylesTable; /** * 遍歷工作簿中所有的電子表格 * * @param filename * @throws IOException * @throws OpenXML4JException * @throws SAXException * @throws Exception */ public void process(String filename) throws IOException, OpenXML4JException, SAXException { OPCPackage pkg = OPCPackage.open(filename); XSSFReader xssfReader = new XSSFReader(pkg); stylesTable = xssfReader.getStylesTable(); SharedStringsTable sst = xssfReader.getSharedStringsTable(); XMLReader parser = this.fetchSheetParser(sst); Iterator sheets = xssfReader.getSheetsData(); while (sheets.hasNext()) { curRow = 0; sheetIndex++; InputStream sheet = sheets.next(); InputSource sheetSource = new InputSource(sheet); parser.parse(sheetSource); sheet.close(); } } public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException { XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); this.sst = sst; parser.setContentHandler(this); return parser; } public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { // c => 單元格 if ("c".equals(name)) { // 前一個(gè)單元格的位置 if (preRef == null) { preRef = attributes.getValue("r"); } else { preRef = ref; } // 當(dāng)前單元格的位置 ref = attributes.getValue("r"); // 設(shè)定單元格類型 this.setNextDataType(attributes); // Figure out if the value is an index in the SST String cellType = attributes.getValue("t"); if (cellType != null && cellType.equals("s")) { nextIsString = true; } else { nextIsString = false; } } // 當(dāng)元素為t時(shí) if ("t".equals(name)) { isTElement = true; } else { isTElement = false; } // 置空 lastContents = ""; } /** * 單元格中的數(shù)據(jù)可能的數(shù)據(jù)類型 */ enum CellDataType { BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, DATE, NULL } /** * 處理數(shù)據(jù)類型 * * @param attributes */ public void setNextDataType(Attributes attributes) { nextDataType = CellDataType.NUMBER; formatIndex = -1; formatString = null; String cellType = attributes.getValue("t"); String cellStyleStr = attributes.getValue("s"); String columData = attributes.getValue("r"); if ("b".equals(cellType)) { nextDataType = CellDataType.BOOL; } else if ("e".equals(cellType)) { nextDataType = CellDataType.ERROR; } else if ("inlineStr".equals(cellType)) { nextDataType = CellDataType.INLINESTR; } else if ("s".equals(cellType)) { nextDataType = CellDataType.SSTINDEX; } else if ("str".equals(cellType)) { nextDataType = CellDataType.FORMULA; } if (cellStyleStr != null) { int styleIndex = Integer.parseInt(cellStyleStr); XSSFCellStyle style = stylesTable.getStyleAt(styleIndex); formatIndex = style.getDataFormat(); formatString = style.getDataFormatString(); if ("m/d/yy" == formatString) { nextDataType = CellDataType.DATE; formatString = "yyyy-MM-dd hh:mm:ss.SSS"; } if (formatString == null) { nextDataType = CellDataType.NULL; formatString = BuiltinFormats.getBuiltinFormat(formatIndex); } } } /** * 對解析出來的數(shù)據(jù)進(jìn)行類型處理 * * @param value * 單元格的值(這時(shí)候是一串?dāng)?shù)字) * @param thisStr * 一個(gè)空字符串 * @return */ @SuppressWarnings("deprecation") public String getDataValue(String value, String thisStr) { switch (nextDataType) { // 這幾個(gè)的順序不能隨便交換,交換了很可能會導(dǎo)致數(shù)據(jù)錯誤 case BOOL: char first = value.charAt(0); thisStr = first == "0" ? "FALSE" : "TRUE"; break; case ERROR: thisStr = ""ERROR:" + value.toString() + """; break; case FORMULA: thisStr = """ + value.toString() + """; break; case INLINESTR: XSSFRichTextString rtsi = new XSSFRichTextString(value.toString()); thisStr = rtsi.toString(); rtsi = null; break; case SSTINDEX: String sstIndex = value.toString(); try { int idx = Integer.parseInt(sstIndex); XSSFRichTextString rtss = new XSSFRichTextString(sst.getEntryAt(idx)); thisStr = rtss.toString(); rtss = null; } catch (NumberFormatException ex) { thisStr = value.toString(); } break; case NUMBER: if (formatString != null) { thisStr = formatter.formatRawCellContents(Double.parseDouble(value), formatIndex, formatString).trim(); } else { thisStr = value; } thisStr = thisStr.replace("_", "").trim(); break; case DATE: thisStr = formatter.formatRawCellContents(Double.parseDouble(value), formatIndex, formatString); // 對日期字符串作特殊處理 thisStr = thisStr.replace(" ", "T"); break; default: thisStr = " "; break; } return thisStr; } @Override public void endElement(String uri, String localName, String name) throws SAXException { // 根據(jù)SST的索引值的到單元格的真正要存儲的字符串 // 這時(shí)characters()方法可能會被調(diào)用多次 if (nextIsString && && StringUtils.isNotEmpty(lastContents) && StringUtils.isNumeric(lastContents)) { int idx = Integer.parseInt(lastContents); lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); } // t元素也包含字符串 if (isTElement) { // 將單元格內(nèi)容加入rowlist中,在這之前先去掉字符串前后的空白符 String value = lastContents.trim(); rowlist.add(curCol, value); curCol++; isTElement = false; } else if ("v".equals(name)) { // v => 單元格的值,如果單元格是字符串則v標(biāo)簽的值為該字符串在SST中的索引 String value = this.getDataValue(lastContents.trim(), ""); // 補(bǔ)全單元格之間的空單元格 if (!ref.equals(preRef)) { int len = countNullCell(ref, preRef); for (int i = 0; i < len; i++) { rowlist.add(curCol, ""); curCol++; } } rowlist.add(curCol, value); curCol++; } else { // 如果標(biāo)簽名稱為 row ,這說明已到行尾,調(diào)用 optRows() 方法 if (name.equals("row")) { // 默認(rèn)第一行為表頭,以該行單元格數(shù)目為最大數(shù)目 if (curRow == 0) { maxRef = ref; } // 補(bǔ)全一行尾部可能缺失的單元格 if (maxRef != null) { int len = countNullCell(maxRef, ref); for (int i = 0; i <= len; i++) { rowlist.add(curCol, ""); curCol++; } } rowReader.getRows(sheetIndex, curRow, rowlist); rowlist.clear(); curRow++; curCol = 0; preRef = null; ref = null; } } } /** * 計(jì)算兩個(gè)單元格之間的單元格數(shù)目(同一行) * * @param ref * @param preRef * @return */ public int countNullCell(String ref, String preRef) { // excel2007最大行數(shù)是1048576,最大列數(shù)是16384,最后一列列名是XFD String xfd = ref.replaceAll("d+", ""); String xfd_1 = preRef.replaceAll("d+", ""); xfd = fillChar(xfd, 3, "@", true); xfd_1 = fillChar(xfd_1, 3, "@", true); char[] letter = xfd.toCharArray(); char[] letter_1 = xfd_1.toCharArray(); int res = (letter[0] - letter_1[0]) * 26 * 26 + (letter[1] - letter_1[1]) * 26 + (letter[2] - letter_1[2]); return res - 1; } /** * 字符串的填充 * * @param str * @param len * @param let * @param isPre * @return */ String fillChar(String str, int len, char let, boolean isPre) { int len_1 = str.length(); if (len_1 < len) { if (isPre) { for (int i = 0; i < (len - len_1); i++) { str = let + str; } } else { for (int i = 0; i < (len - len_1); i++) { str = str + let; } } } return str; } @Override public void characters(char[] ch, int start, int length) throws SAXException { // 得到單元格內(nèi)容的值 lastContents += new String(ch, start, length); } /** * @return the exceptionMessage */ public String getExceptionMessage() { return exceptionMessage; } public static void main(String[] args) { IExcelRowReader rowReader = new ExcelRowReader(); try { // ExcelReaderUtil.readExcel(rowReader, // "E://2016-07-04-011940a.xls"); System.out.println("**********************************************"); ExcelReaderUtil.readExcel(rowReader, "E://test.xlsx"); } catch (Exception e) { e.printStackTrace(); } } }

轉(zhuǎn)自:http://www.cnblogs.com/wshsdl...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/70258.html

相關(guān)文章

  • Excel大批量數(shù)據(jù)的導(dǎo)入和導(dǎo)出,如何做優(yōu)化?

    摘要:并且在對的抽象中,每一行,每一個(gè)單元格都是一個(gè)對象。對支持使用官方例子需要繼承,覆蓋方法,每讀取到一個(gè)單元格的數(shù)據(jù)則會回調(diào)次方法。概要Java對Excel的操作一般都是用POI,但是數(shù)據(jù)量大的話可能會導(dǎo)致頻繁的FGC或OOM,這篇文章跟大家說下如果避免踩POI的坑,以及分別對于xls和xlsx文件怎么優(yōu)化大批量數(shù)據(jù)的導(dǎo)入和導(dǎo)出。一次線上問題這是一次線上的問題,因?yàn)橐粋€(gè)大數(shù)據(jù)量的Excel導(dǎo)出...

    Tecode 評論0 收藏0
  • java 導(dǎo)出 excel 最佳實(shí)踐,java 大文件 excel 避免OOM(內(nèi)存溢出) exce

    摘要:消費(fèi)之后,多線程處理文件導(dǎo)出,生成文件后上傳到等文件服務(wù)器。前端直接查詢并且展現(xiàn)對應(yīng)的任務(wù)執(zhí)行列表,去等文件服務(wù)器下載文件即可。這客戶體驗(yàn)不友好,而且網(wǎng)絡(luò)傳輸,系統(tǒng)占用多種問題。拓展閱讀導(dǎo)出最佳實(shí)踐框架 產(chǎn)品需求 產(chǎn)品經(jīng)理需要導(dǎo)出一個(gè)頁面的所有的信息到 EXCEL 文件。 需求分析 對于 excel 導(dǎo)出,是一個(gè)很常見的需求。 最常見的解決方案就是使用 poi 直接同步導(dǎo)出一個(gè) exc...

    K_B_Z 評論0 收藏0
  • 使用ApachePOI生成XLSX格式Excel文檔大數(shù)據(jù)導(dǎo)出

    摘要:最近在做使用進(jìn)行大數(shù)據(jù)量導(dǎo)出,現(xiàn)在把其整理成工具類供大家參考。版本增加了前綴為相關(guān)的類,主要用于大數(shù)據(jù)量的寫入與讀取。 最近在做使用POI進(jìn)行大數(shù)據(jù)量導(dǎo)出,現(xiàn)在把其整理成工具類供大家參考。Apache POI 3.8版本增加了前綴為SXSSF相關(guān)的類,主要用于大數(shù)據(jù)量的寫入與讀取。關(guān)于ApachePOI導(dǎo)出Excel基本的使用我這里就不詳解了,具體參考: Apache POI官方網(wǎng)站...

    Shihira 評論0 收藏0
  • POI如何高效導(dǎo)出百萬級Excel數(shù)據(jù)

    摘要:閱讀原文如何高效導(dǎo)出百萬級數(shù)據(jù)在一個(gè)具有統(tǒng)計(jì)功能的系統(tǒng)中,導(dǎo)出功能幾乎是一定的,如何導(dǎo)出導(dǎo)出的數(shù)據(jù)有多少如何高效的導(dǎo)出簡介什么是就不用介紹了,這里主要說明不同版本下每個(gè)下的行列限制。 閱讀原文:POI如何高效導(dǎo)出百萬級Excel數(shù)據(jù)? 在一個(gè)具有統(tǒng)計(jì)功能的系統(tǒng)中,導(dǎo)出excel功能幾乎是一定的,如何導(dǎo)出excel?導(dǎo)出的數(shù)據(jù)有多少?如何高效的導(dǎo)出? Excel簡介什么是excel就不用...

    lemanli 評論0 收藏0
  • Java對象和Excel轉(zhuǎn)換工具XXL-EXCEL

    摘要:一行代碼完成對象和之間的轉(zhuǎn)換。說明屬性列名稱四版本更新日志版本,新特性導(dǎo)出支持對象裝換為,并且支持字節(jié)數(shù)組等多種導(dǎo)出方式導(dǎo)入支持轉(zhuǎn)換為對象,并且支持文件路徑等多種導(dǎo)入方式版本,新特性字段支持類型。 《Java對象和Excel轉(zhuǎn)換工具XXL-EXCEL》 showImg(https://segmentfault.com/img/remote/1460000012470335);showI...

    mj 評論0 收藏0

發(fā)表評論

0條評論

cod7ce

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<