java使用事件读取xlxs

xiaoxiao2021-02-28  65

import java.io.InputStream; import java.math.BigDecimal; import java.math.MathContext; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; 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.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; /**  *   * @author linht  * @date 创建时间:2018年2月18日   *@version 1.0  */ public class EventModel { protected static final Logger log =Logger.getLogger(EventModel.class); private StylesTable stylesTable; private List<String[]> datas = new ArrayList<>(); /** * 获取解析器 * @param sst * @return * @throws SAXException */ private XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException { XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); ContentHandler handler = new SheetHandler(sst); parser.setContentHandler(handler); return parser; } /** * 自定义解析处理器 See org.xml.sax.helpers.DefaultHandler javadocs */ private class SheetHandler extends DefaultHandler { private SharedStringsTable sst; private String lastContents; private boolean nextIsString; private List<String> rowlist = new ArrayList<String>(); private int curRow = 0; private int curCol = 0; // 定义前一个元素和当前元素的位置,用来计算其中空的单元格数量,如A6和A8等 private String preRef = null, ref = null; // 定义该文档一行最大的单元格数,用来补全一行最后可能缺失的单元格 private String maxRef = null; private CellDataType nextDataType = CellDataType.SSTINDEX; private final DataFormatter formatter = new DataFormatter(); private short formatIndex; private String formatString; // 用一个enum表示单元格可能的数据类型 private SheetHandler(SharedStringsTable sst) { this.sst = sst; } /** * 解析一个element的开始时触发事件 */ private boolean cc = false; public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { String r = attributes.getValue("r"); if (cc && name.equals("c")) { if (preRef == null) { preRef = attributes.getValue("r"); } else { if (!ref.equals(preRef)) { int len = countNullCell(r, preRef); for (int i = 0; i < len; i++) { rowlist.add(curCol, ""); curCol++; } } } cc = false; } // c => cell if (name.equals("c")) { cc = true; // 前一个单元格的位置 if (preRef == null) { preRef = r; } else { preRef = ref; } // 当前单元格的位置 ref = attributes.getValue("r"); this.setNextDataType(attributes); String cellType = attributes.getValue("t"); if (cellType != null && cellType.equals("s")) { nextIsString = true; } else { nextIsString = false; } } // Clear contents cache lastContents = ""; } /** * 根据element属性设置数据类型 * @param attributes */ public void setNextDataType(Attributes attributes) { nextDataType = CellDataType.NUMBER; formatIndex = -1; formatString = null; String cellType = attributes.getValue("t"); String cellStyleStr = attributes.getValue("s"); 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"; } if (formatString == null) { nextDataType = CellDataType.NULL; formatString = BuiltinFormats.getBuiltinFormat(formatIndex); } } } /** * 解析一个element元素结束时触发事件 */ public void endElement(String uri, String localName, String name) throws SAXException { if (nextIsString) { int idx = Integer.parseInt(lastContents); lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); nextIsString = false; } if (name.equals("v")) { cc = false; String value = this.getDataValue(lastContents.trim(), ""); // 补全单元格之间的空单元格 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 { // 如果标签名称为 row,这说明已到行尾,调用 optRows() 方法 if (name.equals("row")) { // 默认第一行为表头,以该行单元格数目为最大数目 if (curRow == 0) { maxRef = ref; } // 补全一行尾部可能缺失的单元格 if (maxRef != null) { int len = countNullCell(maxRef, ref); for (int i = 0; i <= len; i++) { rowlist.add(curCol, ""); curCol++; } } datas.add(rowlist.toArray(new String[0])); curRow++; // 一行的末尾重置一些数据 rowlist.clear(); curCol = 0; preRef = null; ref = null; cc = false; } } } /** * 根据数据类型获取数据 * @param value * @param thisStr * @return */ public String getDataValue(String value, String thisStr) { switch (nextDataType) { // 这几个的顺序不能随便交换,交换了很可能会导致数据错误 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: thisStr = value.toString(); break; case NUMBER: if (formatString != null) { java.text.DecimalFormat df = new java.text.DecimalFormat("#.00"); thisStr = formatter.formatRawCellContents(Double.parseDouble(df.format(Double.parseDouble(value))), formatIndex, formatString).trim(); } else { if (value.contains(".")&&isDouble(value)) { try { BigDecimal a=new BigDecimal(value, MathContext.DECIMAL64); thisStr=""+Double.parseDouble(a.toString()); } catch (Exception e) { thisStr=value; } }else thisStr = value; } thisStr = thisStr.replace("_", "").trim(); if(thisStr.contains("E")) { BigDecimal bd = new BigDecimal(thisStr);   thisStr=bd.toPlainString(); } break; case DATE: try { thisStr = formatter.formatRawCellContents(Double.parseDouble(value), formatIndex, formatString); } catch (NumberFormatException ex) { thisStr = value.toString(); } thisStr = thisStr.replace(" ", ""); break; default: thisStr = ""; break; } return thisStr; } /** * 获取element的文本数据 */ public void characters(char[] ch, int start, int length) throws SAXException { lastContents += new String(ch, start, length); } public boolean isDouble(String str) { String DOUBLE_NEGATIVE ="^(-?\\d+)(\\.\\d+)?$"; if(str!=null&&str.matches(DOUBLE_NEGATIVE)) return true; else  return false; } /** * 计算两个单元格之间的单元格数目(同一行) * @param ref * @param preRef * @return */ public int countNullCell(String ref, String preRef) { // excel2007最大行数是1048576,最大列数是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; } } public List<String[]> readFile(String fileName)throws Exception { try { processOneSheet(fileName,1); } catch (Exception e) { throw e; } return this.datas; } /** * 处理一个sheet * @param filename * @throws Exception */ private void processOneSheet(String filename,int n) throws Exception { OPCPackage pkg = OPCPackage.open(filename); XSSFReader r = new XSSFReader(pkg); stylesTable = r.getStylesTable(); SharedStringsTable sst = r.getSharedStringsTable(); XMLReader parser = fetchSheetParser(sst); InputStream sheet2 = r.getSheet("rId"+n); try { InputSource sheetSource = new InputSource(sheet2); parser.parse(sheetSource); } catch (Exception e) { throw e; }finally { sheet2.close(); } } /**读取多文件 * @param filename * @return * @throws Exception */ public Map<String, List<String[]>> process(String filename) throws Exception {   Map<String, List<String[]>> map=new HashMap<String, List<String[]>>();         int i=-1;         OPCPackage pkg = OPCPackage.open(filename);           log.info("读取"+filename);         XSSFReader r = new XSSFReader(pkg);           stylesTable = r.getStylesTable();         SharedStringsTable sst = r.getSharedStringsTable();           XMLReader parser = fetchSheetParser(sst);           Iterator<InputStream> sheets = r.getSheetsData();           log.info("转换完成"+filename);         InputStream sheet=null;         while (sheets.hasNext()) {           try {         i++;         sheet = sheets.next();                   InputSource sheetSource = new InputSource(sheet);                   parser.parse(sheetSource);           } catch (Exception e) {         throw e; }finally { if(sheet!=null) sheet.close();   List<String[]> list=new ArrayList<>(); log.info("读取完成sheet"+i+filename); list.addAll(datas); this.datas.clear(); map.put(ti+"", list); System.gc(); }         }         return map;     }   /*public Map<String, List<String[]>> process(String filename) throws Exception {   Map<String, List<String[]>> map=new HashMap<String, List<String[]>>();         String[] tableName=new String[] {"MR.RSRP","MR.AOA","MR.Tadv","MR.TadvRsrp","MR.TadvAoa"};         int i=-1;         while (i<5) {           try {         i++;         processOneSheet(filename,i+1);         } catch (Exception e) {         e.printStackTrace(); }finally { map.put(tableName[i], datas); this.datas.clear(); }         }         return map;     }  */    public static void main(String[] args) throws Exception { EventModel example = new EventModel();

String fileName = "C:\\Users\\linhr\\Desktop\\XXX.xlsx";

System.out.println("-- 程序开始 --"); long time_1 = System.currentTimeMillis(); Map<String, List<String[]>>  map = example.process(fileName); long time_2 = System.currentTimeMillis(); System.out.println("-- 程序结束 --"); System.out.println("-- 耗时 --" + (time_2 - time_1) + "ms"); for (String value :map.keySet()) { for (String[] s : map.get(value)) { System.out.println(Arrays.asList(s)); } } } } enum CellDataType { BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, DATE, NULL }
转载请注明原文地址: https://www.6miu.com/read-2622666.html

最新回复(0)