`
skzr.org
  • 浏览: 366131 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

超大excel读取 43万记录 26M文件

 
阅读更多

maven:

 

<dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.8</version>
</dependency>
<dependency>
        <groupId>xerces</groupId>
        <artifactId>xercesImpl</artifactId>
        <version>2.10.0</version>
</dependency>
 

代码:读取26M excel 2007 xlsx,43万记录,耗时25s (jvm: -Xmx1024M)

 

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
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;

public class XSSFProcess {
        public static void main1(String[] args) throws Exception {
                System.out.println();
                long end, start = System.currentTimeMillis();
//              Path file = Paths.get("/home/skzrorg/tmp/2007.xlsx");
                Path file = Paths.get("/home/skzrorg/tmp/xlsx/IPTABLE.xlsx");
                SheetDatasHandler handler = UtilPoi.read(file);
                end = System.currentTimeMillis();
                System.out.println("耗时:" + (end - start) / 1000f + "s");
                List<List<Object>> sheet = handler.getSheetData(0);
                System.out.println("sheet 大小:" + sheet.size());
                System.out.println("sheet[0]" + sheet.get(0));
                int i = new Random().nextInt(sheet.size());
                System.out.println("sheet[" + i + "]" + sheet.get(i));
                System.out.println("sheet[" + (sheet.size() - 1) + "]" + sheet.get(sheet.size() - 1));
        }
        
        private static int rowCount;
        public static void main(String[] args) throws Exception {
                System.out.println();
                long end, start = System.currentTimeMillis();
                Path file = Paths.get("/home/skzrorg/tmp/xlsx/IPTABLE.xlsx");
                UtilPoi.read(file, new RowMapper() {
                        @Override
                        void mapRow(int sheetIndex, int rowIndex, List<Object> row) {
                                rowCount++;
                        }
                });
                end = System.currentTimeMillis();
                System.out.println("耗时:" + (end - start) / 1000f + "s");
                System.out.println("sheet 大小:" + rowCount);
        }
}

class UtilPoi {
        public static SheetDatasHandler read(Path file) throws Exception {
                SheetDatasHandler handler = new SheetDatasHandler((int) (Files.size(file) / 50));
                read(file, handler);
                return handler;
        }
        public static void read(Path file, RowMapper mapper) throws Exception {
                final long size = Files.size(file);
                try (InputStream in = new BufferedInputStream(new FileInputStream(file.toFile()), size > Integer.MAX_VALUE ? 1024 * 1024 * 10 : (int) size)) {
                        read(in, mapper);
                }
        }
        public static void read(InputStream in, RowMapper mapper) throws Exception {
                XSSFReader reader = new XSSFReader(OPCPackage.open(in));
                XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
                
                mapper.setSharedStringsTable(reader.getSharedStringsTable());
                parser.setContentHandler(mapper);
                
                for (Iterator<InputStream> iter = reader.getSheetsData(); iter.hasNext();) {
                        try (InputStream sheetIn = iter.next()) {
                                parser.parse(new InputSource(sheetIn));
                        }
                }
        }
}

class SheetDatasHandler extends RowMapper {
        private int bufRowSize, curSheetIndex = -1;
        private List<List<List<Object>>> sheetDatas = new ArrayList<>();
        private List<List<Object>> sheetData;
        
        public List<List<List<Object>>> getSheetDatas() {
                return sheetDatas;
        }
        public List<List<Object>> getSheetData(int sheetIndex) {
                return sheetDatas.get(sheetIndex);
        }
        
        SheetDatasHandler(int bufRowSize) {
                this.bufRowSize = bufRowSize;
        }
        
        @Override
        void mapRow(int sheetIndex, int rowIndex, List<Object> row) {
                if (curSheetIndex != sheetIndex) {
                        sheetData = new ArrayList<>(sheetIndex == 0 ? bufRowSize : sheetData.size() / 2);
                        sheetDatas.add(sheetData);
                        curSheetIndex = sheetIndex;
                }
                
                sheetData.add(row);
        }
}

abstract class RowMapper extends DefaultHandler {
        private SharedStringsTable sst;
        private Map<Integer, String> strMap;
        private int sheetIndex = -1, rowIndex = -1;
        private List<Object> row;
        private String cellS;
        private String cellType;
        private boolean valueFlag;
        private StringBuilder value;
        
        public void setSharedStringsTable(SharedStringsTable sst) {
                this.sst = sst;
                strMap = new HashMap<>(sst.getCount());
        }
        
        private void clearSheet() {
                sst = null;
                strMap = null;
                row = null;
                cellS = null;
                cellType = null;
                value = null;
                rowIndex = 0;
        }
        
        private Object convertCellValue() {
                String tmp = value.toString();
                Object result = tmp;
                
                if ("s".equals(cellType)) {     //字符串
                        Integer key = Integer.parseInt(tmp);
                        result = strMap.get(key);
                        if (result == null) strMap.put(key, (String) (result = new XSSFRichTextString(sst.getEntryAt(key)).toString()));
                } else if ("n".equals(cellType)) {
                        if ("2".equals(cellS)) {        //日期
                                result = HSSFDateUtil.getJavaDate(Double.valueOf(tmp));
                        }
                }
                return result;
        }
        
        @Override
        public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
                if ("sheetData".equals(name)) {
                        sheetIndex++;
                } else if ("row".equals(name)) {
                        rowIndex++;
                        row = new ArrayList<>();
                } else if ("c".equals(name)) {
                        cellS = attributes.getValue("s");
                        cellType = attributes.getValue("t");
                } else if ("v".equals(name)) {
                        valueFlag = true;
                        value = new StringBuilder();
                }
        }
        
        @Override
        public void endElement(String uri, String localName, String name) throws SAXException {
                if ("sheetData".equals(name)) {
                        clearSheet();
                } else if ("row".equals(name)) {
                        mapRow(sheetIndex, rowIndex, row);
                } else if ("v".equals(name)) {
                        row.add(convertCellValue());
                        valueFlag = false;
                }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
                if (valueFlag) value.append(ch, start, length);
        }
        
        abstract void mapRow(int sheetIndex, int rowIndex, List<Object> row);
}
 

 

如果采用dom解析,需要配置2G内存

分享到:
评论
1 楼 chenghong726 2015-12-18  
你好,我用你这个方法,上传文件72M一直卡在 mapper.setSharedStringsTable(reader.getSharedStringsTable());我把        SheetDatasHandler handler = new SheetDatasHandler((int) (Files.size(file) / 200));除以200还是一样,这是为什么

相关推荐

    java读取excel之xlsl超大文件

    标题"java读取excel之xlsl超大文件"所涉及的核心知识点是优化大量数据的读取策略。在Java中,可以使用Apache POI的SXSSF API(Streaming Usermodel API)来实现这种优化。与常规的XSSF API不同,SXSSF允许我们以流的...

    Java处理100万行超大Excel文件秒级响应

    ### Java处理100万行超大Excel文件秒级响应 #### 一、问题背景与需求分析 在项目开发过程中,经常会遇到需要处理大量Excel数据的情况。这些数据可能包括成千上万条记录,每条记录又包含多个字段。传统的处理方式...

    C#读取加密Excel文件

    C# 读取加密的Excel 文件; 有源码,VS2010开发。 采用的是微软的Microsoft.Office.Interop.Excel, V14.0,来读取加密后的Excle文件。 不是采用第三方控件NPOI读取加密的Excel文件。 开始研究NPOI读取加密的Excel文件...

    html静态读取excel文件

    以`SheetJS`为例,可以使用以下代码读取Excel文件: ```javascript var reader = new FileReader(); reader.onload = function(e) { var data = e.target.result; var workbook = XLSX.read(data, {type: 'binary...

    QT 快速读取Excel文件

    在处理Excel文件时,QT虽然没有内置的专门模块,但可以通过一些第三方库如QAxContainer或QSpreadsheet来实现快速读取Excel文件的功能。 QAxContainer是QT提供的一个ActiveX控件容器,允许在QT应用中使用Windows的...

    excel读取生成xml文件

    本文将详细介绍如何通过Excel读取数据并生成XML文件,以实现数据的标准化存储和传输。 首先,我们需要了解Excel如何读取数据。Excel提供了丰富的函数和公式,可以方便地对单元格中的数据进行操作。例如,VLOOKUP...

    java读取excel文件

    Java 读取 Excel 文件 Java 读取 Excel 文件是指使用 Java 语言从 Excel 文件中读取数据,并对其进行处理的过程。下面将详细介绍 Java 读取 Excel 文件的过程和相关知识点。 Java 读取 Excel 文件的步骤 1. 导入...

    C++读取excel数据

    读取环境为Win10+VS2015,个人参考资料封装的excel读取模块用来读取Excel2007中的数据,文件为压缩文件,亲测可用。

    读取Excel文件中多个sheet

    java读取Excel文件中多个sheet,生成xml格式的文件

    delphi7如何读取excel文件

    "Delphi7 读取 Excel 文件" Delphi7 是一个功能强大的开发环境,它提供了多种方式来读取 Excel 文件。在本文中,我们将介绍使用 OLE 和 Excel Application 读取 Excel 文件的方法。 使用 OLE 读取 Excel 文件 ...

    Unity读取Excel文件

    在Unity游戏开发中,有时我们需要从Excel文件中读取数据,比如角色属性、地图配置或者游戏物品信息等。为了实现这一功能,我们可以借助外部库来处理Excel文件。本篇文章将详细讲解如何在Unity中读取Excel文件,以及...

    mvc 上传excel文件并读取excle内容

    asp.net mvc 上传excel文件并读取excle内容转成DataTable(Spire.Office.3.6.0) 一个需求:将一个Excel文件中的数据导入到数据库中去。 思路:上传一个excel文件,读取该excel文件中数据,转成DataTable(或List),...

    python读取excel文件例子

    Python提供了多个库来方便地读取和写入Excel文件,其中最常用的是`pandas`库和`openpyxl`库。本例子将重点介绍如何使用Python通过`pandas`库来读取Excel文件。 首先,`pandas`是一个强大的数据处理库,它提供了...

    读取Excel文件xls、xlsx、csv格式文件,读取txt文件

    //C# 读取Excel文件、C#读取xls文件、C#读取xlsx文件、C#读取csv文件 //C# 将xls文件转换为DataTable、C#将xlsx文件转换为DataTable //C#将csv文件转换为DataTable //C#将txt文件转换为DataTable(列与列之间空格隔...

    AutoLISP例程:读取excel文件.doc

    AutoLISP 读取 Excel 文件 AutoLISP 是一种功能强大的编程语言,广泛应用于计算机辅助设计(CAD)领域。它可以与 Autodesk 的 AutoCAD 等软件集成,用于自动化设计和绘图过程。AutoLISP 也可以用于读取和处理 Excel...

    C# winform 读取Excel文件 表名及内容

    在C#编程环境中,开发Windows桌面应用程序时,我们经常需要处理Excel文件,例如读取、写入或修改数据。在本场景中,我们将探讨如何在Winform应用中读取Excel文件,包括表名和内容。这里使用的开发工具是Visual ...

    Android Excel文件写入和读取

    本文将详细介绍如何在Android中实现Excel文件的读取与写入。 首先,Android系统本身并不直接支持Excel文件的操作,因此我们需要引入第三方库来实现这一功能。常用的库有Apache POI,这是一个用于处理Microsoft ...

    labview读取excel文件数据

    labview读取固定的excel文件

    三个Excel读取必备Dll文件:Excel.dll 和ICSharpCode.SharpZipLib库文件

    这里提到的“三个Excel读取必备Dll文件”指的是`Excel.dll`和`ICSharpCode.SharpZipLib.dll`,它们可以帮助我们实现这一目标。 首先,`Excel.dll`通常是一个用于读写Excel文件的库,它可能封装了对Microsoft Office...

    c#无需安装office就可原格式读取excel文件

    在C#编程环境中,开发人员经常需要处理Excel文件,例如读取、写入或修改数据。在传统的做法中,这通常需要在系统上安装Microsoft Office套件,利用COM互操作来调用Excel应用程序。然而,这种方法不仅依赖于Office的...

Global site tag (gtag.js) - Google Analytics