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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 百万级 Excel导入数据库 效率太低? 基于 SAX 的事件模型 导入,将会解决 效率问题

百万级 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 的事件模型示例代码:

// 准备写入的输出流
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 格式文件)。

结语

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

目录
相关文章
|
12天前
|
Python
使用OpenPyXL库实现Excel单元格其他对齐方式设置
本文介绍了如何使用Python的`openpyxl`库设置Excel单元格中的文本对齐方式,包括文本旋转、换行、自动调整大小和缩进等,通过具体示例代码展示了每种对齐方式的应用方法,适合需要频繁操作Excel文件的用户学习参考。
139 85
使用OpenPyXL库实现Excel单元格其他对齐方式设置
|
2月前
|
SQL 关系型数据库 MySQL
数据库导入SQL文件:全面解析与操作指南
在数据库管理中,将SQL文件导入数据库是一个常见且重要的操作。无论是迁移数据、恢复备份,还是测试和开发环境搭建,掌握如何正确导入SQL文件都至关重要。本文将详细介绍数据库导入SQL文件的全过程,包括准备工作、操作步骤以及常见问题解决方案,旨在为数据库管理员和开发者提供全面的操作指南。一、准备工作在导
452 0
|
17天前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
26天前
|
前端开发
实现Excel文件和其他文件导出为压缩包,并导入
实现Excel文件和其他文件导出为压缩包,并导入
27 1
|
28天前
|
数据格式 UED
记录一次NPOI库导出Excel遇到的小问题解决方案
【11月更文挑战第16天】本文记录了使用 NPOI 库导出 Excel 过程中遇到的三个主要问题及其解决方案:单元格数据格式错误、日期格式不正确以及合并单元格边框缺失。通过自定义单元格样式、设置数据格式和手动添加边框,有效解决了这些问题,提升了导出文件的质量和用户体验。
160 3
|
1月前
|
Java BI API
Java Excel报表生成:JXLS库的高效应用
在Java应用开发中,经常需要将数据导出到Excel文件中,以便于数据的分析和共享。JXLS库是一个强大的工具,它基于Apache POI,提供了一种简单而高效的方式来生成Excel报表。本文将详细介绍JXLS库的使用方法和技巧,帮助你快速掌握Java中的Excel导出功能。
69 6
|
1月前
|
Java API Apache
|
3月前
|
SQL C# 数据库
EPPlus库的安装和使用 C# 中 Excel的导入和导出
本文介绍了如何使用EPPlus库在C#中实现Excel的导入和导出功能。首先,通过NuGet包管理器安装EPPlus库,然后提供了将DataGridView数据导出到Excel的步骤和代码示例,包括将DataGridView转换为DataTable和使用EPPlus将DataTable导出为Excel文件。接着,介绍了如何将Excel数据导入到数据库中,包括读取Excel文件、解析数据、执行SQL插入操作。
EPPlus库的安装和使用 C# 中 Excel的导入和导出
|
2月前
|
SQL 存储 关系型数据库
SQL文件导入MySQL数据库的详细指南
数据库中的数据转移是一项常规任务,无论是在数据迁移过程中,还是在数据备份、还原场景中,导入导出SQL文件显得尤为重要。特别是在使用MySQL数据库时,如何将SQL文件导入数据库是一项基本技能。本文将详细介绍如何将SQL文件导入MySQL数据库,并提供一个清晰、完整的步骤指南。这篇文章的内容字数大约在
342 1
|
3月前
|
SQL 关系型数据库 MySQL
Python小技巧——将CSV文件导入到MySQL数据库
Python小技巧——将CSV文件导入到MySQL数据库
125 0
下一篇
DataWorks