From 7e26f01ad7d75ff258c6a22a56733eedb342d3b0 Mon Sep 17 00:00:00 2001 From: wuchunlei Date: Mon, 15 Dec 2025 13:36:54 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E6=9E=90excel=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 17 ++ .../java/com/zmzm/finance/util/ExcelUtil.java | 185 ++++++++++++++++++ .../com/zmzm/finance/util/SheetHandler.java | 68 +++++++ 3 files changed, 270 insertions(+) create mode 100644 src/main/java/com/zmzm/finance/util/ExcelUtil.java create mode 100644 src/main/java/com/zmzm/finance/util/SheetHandler.java diff --git a/pom.xml b/pom.xml index 8d3fb61..ea1e0da 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,23 @@ + + + + org.apache.poi + poi + 3.17 + + + org.apache.poi + poi-ooxml + 3.17 + + + org.apache.poi + poi-scratchpad + 3.17 + com.alibaba diff --git a/src/main/java/com/zmzm/finance/util/ExcelUtil.java b/src/main/java/com/zmzm/finance/util/ExcelUtil.java new file mode 100644 index 0000000..17ac1d0 --- /dev/null +++ b/src/main/java/com/zmzm/finance/util/ExcelUtil.java @@ -0,0 +1,185 @@ +package com.zmzm.finance.util; + +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xssf.eventusermodel.XSSFReader; +import org.apache.poi.xssf.model.SharedStringsTable; +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.XMLReaderFactory; +import java.io.InputStream; +import java.util.*; + +/** + * 数据量比较大(8万条以上)的excel文件解析,将excel文件解析为 行列坐标-值的形式存入map中,此方式速度快,内存耗损小 但只能读取excel文件 + * 提供处理单个sheet方法 processOneSheet(String filename) 以及处理多个sheet方法 processAllSheets(String filename) + * 只需传入文件路径+文件名即可 调用处理方法结束后,只需接收ExcelUtil.getRowContents()返回值即可获得解析后的数据 + */ +public class ExcelUtil { + private static LinkedHashMap rowContents = new LinkedHashMap(); + private static SheetHandler sheetHandler; + + public LinkedHashMap getRowContents() { + return rowContents; + } + + public static void setRowContents(LinkedHashMap rc) { + rowContents = rc; + } + + public SheetHandler getSheetHandler() { + return sheetHandler; + } + + public static void setSheetHandler(SheetHandler sh) { + sheetHandler = sh; + } + + public static List> processSheetByRId(InputStream in, Integer count) throws Exception { + OPCPackage pkg = null; + InputStream sheet = null; + List> results = new ArrayList>(); + try { + pkg = OPCPackage.open(in); + XSSFReader r = new XSSFReader(pkg); + SharedStringsTable sst = r.getSharedStringsTable(); + + for (int i = 0; i < count; i++) { + sheet = r.getSheet("rId" + (i + 1)); + InputSource sheetSource = new InputSource(sheet); + XMLReader parser = fetchSheetParser(sst); + parser.parse(sheetSource); + results.add(sheetHandler.getRowContents()); + } + return results; + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + if (pkg != null) { + pkg.close(); + } + if (sheet != null) { + sheet.close(); + } + } + } + + // 处理一个sheet + public static void processOneSheet(String filename) throws Exception { + InputStream sheet2 = null; + OPCPackage pkg = null; + try { + pkg = OPCPackage.open(filename); + XSSFReader r = new XSSFReader(pkg); + SharedStringsTable sst = r.getSharedStringsTable(); + XMLReader parser = fetchSheetParser(sst); + sheet2 = r.getSheet("rId1"); + InputSource sheetSource = new InputSource(sheet2); + parser.parse(sheetSource); + setRowContents(sheetHandler.getRowContents()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + if (pkg != null) { + pkg.close(); + } + if (sheet2 != null) { + sheet2.close(); + } + } + } + + // 处理一个sheet + public static void processOneSheet(InputStream is) throws Exception { + InputStream sheet2 = null; + OPCPackage pkg = null; + try { + pkg = OPCPackage.open(is); + XSSFReader r = new XSSFReader(pkg); + SharedStringsTable sst = r.getSharedStringsTable(); + XMLReader parser = fetchSheetParser(sst); + sheet2 = r.getSheet("rId1"); + InputSource sheetSource = new InputSource(sheet2); + parser.parse(sheetSource); + setRowContents(sheetHandler.getRowContents()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + if (pkg != null) { + pkg.close(); + } + if (sheet2 != null) { + sheet2.close(); + } + } + } + + // 处理多个sheet + public static void processAllSheets(String filename) throws Exception { + OPCPackage pkg = null; + InputStream sheet = null; + try { + pkg = OPCPackage.open(filename); + XSSFReader r = new XSSFReader(pkg); + SharedStringsTable sst = r.getSharedStringsTable(); + XMLReader parser = fetchSheetParser(sst); + Iterator sheets = r.getSheetsData(); + while (sheets.hasNext()) { + System.out.println("Processing new sheet:\n"); + sheet = sheets.next(); + InputSource sheetSource = new InputSource(sheet); + parser.parse(sheetSource); + } + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + if (pkg != null) { + pkg.close(); + } + if (sheet != null) { + sheet.close(); + } + } + } + + public static XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException { + XMLReader parser = XMLReaderFactory.createXMLReader("com.sun.org.apache.xerces.internal.parsers.SAXParser"); + setSheetHandler(new SheetHandler(sst)); + ContentHandler handler = (ContentHandler) sheetHandler; + parser.setContentHandler(handler); + return parser; + } + + /** + * See org.xml.sax.helpers.DefaultHandler + */ + // 测试 + public void test() throws Exception { + Long time = System.currentTimeMillis(); + ExcelUtil example = new ExcelUtil(); + example.processOneSheet("C:/Users/Desktop/2018041310024112.xlsx"); + Long endtime = System.currentTimeMillis(); + LinkedHashMap map = example.getRowContents(); + Iterator> it = map.entrySet().iterator(); + int count = 0; + String prePos = ""; + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + String pos = entry.getKey(); + if (!pos.substring(1).equals(prePos)) { + prePos = pos.substring(1); + count++; + } + System.out.println(pos + ";" + entry.getValue()); + } + System.out.println("解析数据" + count + "条;耗时" + (endtime - time) / 1000 + "秒"); + } +} + + + diff --git a/src/main/java/com/zmzm/finance/util/SheetHandler.java b/src/main/java/com/zmzm/finance/util/SheetHandler.java new file mode 100644 index 0000000..ad6c11c --- /dev/null +++ b/src/main/java/com/zmzm/finance/util/SheetHandler.java @@ -0,0 +1,68 @@ +package com.zmzm.finance.util; + +import org.apache.poi.xssf.model.SharedStringsTable; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; +import java.util.LinkedHashMap; + +/** + * @description: 重写startElement() endElement() characters() 用于把Excel数据封装到 LinkedHashMap 中 + * @date: 2021/12/16 15:10 + */ +public class SheetHandler extends DefaultHandler { + private SharedStringsTable sst; + private String lastContents; + private boolean nextIsString; + private String cellPosition; + private LinkedHashMap rowContents = new LinkedHashMap(); + + public LinkedHashMap getRowContents() { + return rowContents; + } + + public void setRowContents(LinkedHashMap rowContents) { + this.rowContents = rowContents; + } + + public SheetHandler(SharedStringsTable sst) { + this.sst = sst; + } + + public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { + if (name.equals("c")) { + cellPosition = attributes.getValue("r"); + String cellType = attributes.getValue("t"); + if (cellType != null && cellType.equals("s")) { + nextIsString = true; + } else { + nextIsString = false; + } + } + // 清楚缓存内容 + lastContents = ""; + } + + 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")) { + // 数据读取结束后,将单元格坐标,内容存入map中 + if (!(cellPosition.length() == 2) || (cellPosition.length() == 2 && !"1".equals(cellPosition.substring(1)))) { //不保存第一行数据 + rowContents.put(cellPosition, lastContents); + } + } + } + + public void characters(char[] ch, int start, int length) throws SAXException { + lastContents += new String(ch, start, length); + } +} + + +