前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >百万级 Excel导入数据库 效率太低? 基于 SAX 的事件模型 导入,将会解决 效率问题

百万级 Excel导入数据库 效率太低? 基于 SAX 的事件模型 导入,将会解决 效率问题

作者头像
猫头虎
发布2024-04-08 14:22:43
1250
发布2024-04-08 14:22:43
举报

百万级 Excel导入效率太低? 基于 SAX 的事件模型 导入,将会解决 效率问题

如果使用传统的基于 POI 的读写方式,处理大量数据时确实效率较低,可以考虑使用基于 SAX 的事件模型进行读写。

基于 SAX 的事件模型,是一种流式的读写方式,可以直接读取 Excel 文件中的 XML 格式数据,并将其转换为对象模型,因此具有较高的性能和较小的内存占用。

基于 SAX 的事件模型是一种流式的读写方式,它可以直接读取 Excel 文件中的 XML 格式数据,并将其转换为对象模型。在处理大量数据时,该方式具有较高的性能和较小的内存占用。

SAX 是 Simple API for XML(简单 XML 应用程序接口)的缩写,它是一种基于事件的 XML 解析技术,通过注册一些回调函数(事件处理程序),可以实现对 XML 文件的解析。SAX 解析器读取 XML 文档,并发送事件(例如元素开始、元素结束等)给注册的事件处理程序,通过事件处理程序对 XML 文档进行处理。

实现思路:

在基于 SAX 的事件模型中,我们可以通过 XSSFReader 类获取 Excel 文件的输入流,并使用 XMLReader 类来解析 Excel 文件中的 XML 数据。具体步骤如下:

  1. 准备写入的输出流,例如输出到文件或内存中。

​ 2.创建 SAX 事件处理程序,通过实现不同的回调函数来处理不同的事件,例如开始解析 Workbook、解析 Cell 的值、结束解析 Workbook 等。

  1. 获取 Excel 文件输入流,使用 OPCPackage 和 XSSFReader 类来读取 Excel 文件中的 XML 数据。
  2. 获取 Workbook 中每个 Sheet 的 XML 输入流,并使用 XMLReader 类来解析 Excel 文件中的 XML 数据。
  3. 在 SAX 事件处理程序中处理不同的事件,例如开始解析 Workbook、解析 Cell 的值、结束解析 Workbook 等。
  4. 写入缓存的数据,例如每隔一定行数进行一次缓存写入。

需要注意的是,由于使用了 SAX 事件模型,需要自己实现解析事件处理程序。在处理复杂的 Excel 文件时,可能需要编写更为复杂的事件处理程序。同时,使用 SAX 事件模型可以有效减少内存占用,但需要较多的 I/O 操作,因此在处理小规模数据时可能不如基于 POI 的读写方式效率高。

代码示例:

以下是一个基于 SAX 的事件模型示例代码:

代码语言:javascript
复制
// 准备写入的输出流
OutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile));
SXSSFWorkbook writer = new SXSSFWorkbook(new XSSFWorkbook(), 10000);
SXSSFSheet outSheet = writer.createSheet();

// 定义 SAX 事件处理程序
DefaultHandler handler = new DefaultHandler() {
    private boolean isRow = false;
    private int rowIndex = 0;
    private int colIndex = 0;
    private Row outRow = null;

    // 开始解析 Workbook
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if (qName.equals("row")) {
            isRow = true;
            rowIndex++;
            colIndex = 0;
            outRow = outSheet.createRow(rowIndex - 1);
        } else if (qName.equals("c")) {
            String colRef = attributes.getValue("r");
            colIndex = CellReference.convertColStringToIndex(colRef.replaceAll("\\d", ""));
        }
    }

    // 解析 Cell 的值
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (isRow) {
            String cellValue = new String(ch, start, length);
            Cell cell = outRow.createCell(colIndex, CellType.STRING);
            cell.setCellValue(cellValue);
        }
    }

    // 结束解析 Workbook
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (qName.equals("row")) {
            isRow = false;

            // 每隔 10000 行进行一次缓存写入
            if (rowIndex % 10000 == 0) {
                ((SXSSFSheet) outSheet).flushRows();
            }
        }
    }
};

// 获取 Excel 文件输入流
InputStream is = new BufferedInputStream(new FileInputStream(inputFile));
OPCPackage pkg = OPCPackage.open(is);
XSSFReader reader = new XSSFReader(pkg);

// 获取 Workbook 中每个 Sheet 的 XML 输入流,并解析处理
XMLReader parser = XMLReaderFactory.createXMLReader();
parser.setContentHandler(handler);
Iterator<InputStream> sheets = reader.getSheetsData();
while (sheets.hasNext()) {
    InputStream sheetStream = sheets.next();
    InputSource sheetSource = new InputSource(sheetStream);
    parser.parse(sheetSource);
    sheetStream.close();
}

// 写入缓存的数据
writer.write(os);
os.flush();
os.close();
writer.dispose();

上述示例代码通过解析 Excel 文件中的 XML 数据,实现了基于 SAX 的事件模型读写操作。这种方式适用于处理大量数据,具有较高的性能和较小的内存占用。

需要注意的是,由于使用了 SAX 事件模型,需要自己实现解析事件处理程序。在处理复杂的 Excel 文件时,可能需要编写更为复杂的事件处理程序。

注意:

基于 SAX 的事件模型适用于读取基于 XML 格式的 Excel 文件,因此只能读取 XLSX 格式的文件,而不能读取旧版的 XLS 格式。这是因为 XLSX 文件是基于 XML 格式的文件,而 XLS 文件则采用了一种二进制格式,无法通过基于 SAX 的事件模型进行解析。如果需要读取 XLS 文件,可以使用基于 POI 的读写方式,例如 HSSF(适用于读写 XLS 格式文件)和 XSSF(适用于读写 XLSX 格式文件)。

结语

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、评论、收藏➕关注,您的支持是我坚持写作最大的动力。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 百万级 Excel导入效率太低? 基于 SAX 的事件模型 导入,将会解决 效率问题
  • 实现思路:
  • 代码示例:
  • 注意:
  • 结语
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档