如何使用大型 Excel 文件的 XSSF 和 SAX(事件 API)获取命名范围、工作表名称和参考公式的列表

2024-04-12

我正在尝试读取大型 Excel 文件(大小~10MB,.xlsx)。

我正在使用下面的代码

Workbook xmlworkbook =WorkbookFactory.create(OPCPackage.openOrCreate(root_path_name_file));

但它显示堆内存问题。

我还在 StackOverflow 上看到了其他解决方案,其中一些解决方案是为了增加 JVM,但我不想增加 jvm。

问题1)我们不能使用SXSSF (Streaming Usermodel API)因为这仅用于编写或创建新的工作簿。

我的唯一目标是获取大型 Excel 文件的工作表 NamedRange 数量、工作表总数及其工作表名称。


如果要求仅获取命名范围和工作表名称,则只需/xl/workbook.xml来自*.xlsx ZIPPackage必须解析,因为这些信息都存储在那里。

这可以通过获得适当的PackagePart并解析XML由此。用于解析XML我最喜欢的是使用StAX.

获取所有工作表名称和定义的命名范围的示例代码:

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.XMLEvent;

import javax.xml.namespace.QName;

import java.io.File;

import java.util.regex.Pattern;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

class StaxReadOPCPackageParts {

 public static void main(String[] args) {
  try {

   File file = new File("file.xlsx");
   OPCPackage opcpackage = OPCPackage.open(file);

   //get the workbook package part
   PackagePart workbookpart = opcpackage.getPartsByName(Pattern.compile("/xl/workbook.xml")).get(0);

   //create reader for package part            
   XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(workbookpart.getInputStream());

   List<String> sheetNames = new ArrayList<>();
   Map<String, String> definedNames = new HashMap<>();

   boolean isInDefinedName = false;
   String sheetName = "";
   String definedNameName = "";
   StringBuffer definedNameFormula = new StringBuffer();

   while(reader.hasNext()){ //loop over all XML in workbook.xml
    XMLEvent event = (XMLEvent)reader.next();

    if(event.isStartElement()) {
     StartElement startElement = (StartElement)event;
     QName startElementName = startElement.getName();
     if(startElementName.getLocalPart().equalsIgnoreCase("sheet")) { //start element of sheet definition
      Attribute attribute = startElement.getAttributeByName(new QName("name"));
      sheetName = attribute.getValue();
      sheetNames.add(sheetName);
     } else if (startElementName.getLocalPart().equalsIgnoreCase("definedName")) { //start element of definedName
      Attribute attribute = startElement.getAttributeByName(new QName("name"));
      definedNameName = attribute.getValue();
      isInDefinedName = true;
     }
    } else if(event.isCharacters() && isInDefinedName) { //character content of definedName == the formula
     definedNameFormula.append(((Characters)event).getData());
    } else if(event.isEndElement()) {
     EndElement endElement = (EndElement)event;
     QName endElementName = endElement.getName();
     if(endElementName.getLocalPart().equalsIgnoreCase("definedName")) { //end element of definedName
      definedNames.put(definedNameName, definedNameFormula.toString());
      definedNameFormula = new StringBuffer();
      isInDefinedName = false;
     }
    }

   } 

   opcpackage.close();

   System.out.println("Sheet names:");
   for (String shName : sheetNames) {
    System.out.println("Sheet name: " + shName);
   }

   System.out.println("Named ranges:");
   for (String defName : definedNames.keySet()) {
    System.out.println("Name: " + defName + ", Formula: " + definedNames.get(defName));
   }

  } catch (Exception ex) {
     ex.printStackTrace();
  }
 }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用大型 Excel 文件的 XSSF 和 SAX(事件 API)获取命名范围、工作表名称和参考公式的列表 的相关文章

  • 在VBA中将字符串文本拆分为单独的行

    我的 excel 或 csv 文件 中有 2 个文本框 如下所示 文本框 1 包含 11111 22222 33333 文本框 2 包含 55555 11111 22222 33333 55555 我希望 之间的文本位于 3 个不同的行上
  • Windows Azure 远程站点“Microsoft.ACE.OLEDB.12.0”提供程序未在本地计算机上注册[重复]

    这个问题在这里已经有答案了 以下代码在我的本地开发计算机上可以正常运行 但是当我部署它时 我收到以下错误消息Azure 远程网站 我已经查看了SO答案和谷歌搜索结果 但我仍然不清楚我必须在本地计算机上安装什么 这样当我将代码推送到Azure
  • 拆分具有多行文本和单行文本的行

    我试图弄清楚如何拆分数据行 其中行中的 B C D 列包含多行 而其他列不包含多行 我已经弄清楚如何拆分多行单元格 如果我将这些列复制到新工作表中 手动插入行 然后运行下面的宏 仅适用于 A 列 但我在编码时迷失了休息 Here s wha
  • 需要在Excel中合并3列

    我有 3 列 A B C 我需要合并这 3 列 并且我已经应用了 forumala A1 B1 C1输出为 E 列 我需要输出为 D 列 下面的公式将达到您想要的结果 TEXTJOIN TRUE A1 C1 Textjoin 的工作方式类似
  • 强力查询历年产品利润对比

    我有一个数据集 其中包含公司 产品 利润和年份 公司每年都会销售少量产品并获得利润 公司没有必要在明年销售相同的产品 他们可能会省略以前的产品并添加新的少量产品 我只想对两年的产品进行逐个比较 如下所示 我的数据集是 Company Pro
  • 你将如何开始自动化我的工作? - 第2部分

    后续这个问题 https stackoverflow com questions 2796128 how would you start automating my job 在经历了第一波进货 9 小时的复制 粘贴 后 我现在相信我已经满足
  • Excel VBA - 如何逐行读取csv文件而不是整个文件

    这是我需要读取的 csv 文件内容 header header header header header header value value value value value value value value value 我在网上找到
  • java实现excel价格、收益率函数[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 VBA 中按键对字典进行排序

    我使用 VBA 创建了一个字典CreateObject Scripting Dictionary 将源单词映射到要在某些文本中替换的目标单词 这实际上是为了混淆 不幸的是 当我按照下面的代码进行实际替换时 它将按照源单词添加到字典中的顺序替
  • 设置 Apache POI 的路径

    我想创建 Excel 文件并使用 java 程序在该文件中写入数据 That is here http www techbrainwave com p 554我在 java 文件所在的位置提取了 Apache POI 并将该路径包含在路径变
  • 如何在未安装 Office 的情况下以编程方式创建、读取、写入 Excel?

    我对所有读取 写入 创建 Excel 文件的方法感到非常困惑 VSTO OLEDB 等 但它们都seem具有必须安装office的要求 这是我的情况 我需要开发一个应用程序 它将以 Excel 文件作为输入 进行一些计算并创建一个新的 Ex
  • 如何使用Matlab将数据保存到Excel表格中?

    我想将数据以表格形式保存在 Excel 工作表中 它应该看起来像 Name Age R no Gpa Adnan 24 18 3 55 Ahmad 22 12 3 44 Usman 23 22 3 00 每次当我执行我的文件时类数据 m 下
  • 如何使用 VBA 将 mm/dd/yyyy 更改为 dd/mm/yyyy

    我在使用 VBA 将 mm dd yyyy 转换为 dd mm yyyy 日期格式时遇到问题 我有一个这样的表 仅供参考 该表是从报告工具自动生成的 字符串操作 或任何 Excel 函数可以提供帮助吗 希望知道如何解决这个问题的人可以给我一
  • VBA XML V6.0 如何让它等待页面加载?

    我一直在努力寻找答案 但似乎找不到任何有用的东西 基本上 我是从一个网站上拉取的 当您在该页面上时 该网站会加载更多项目 我希望我的代码在加载完成后提取最终数据 但不知道如何让 XML httprequest 等待 Edited Sub p
  • 使用 Apache POI Excel 写入特定单元格位置

    如果我有一个未排序的参数 x y z 列表 是否有一种简单的方法将它们写入使用 POI 创建的 Excel 文档中的特定单元格 就好像前两个参数是 X 和Y 坐标 例如 我有如下行 10 4 100 是否可以在第 10 行第 4 列的单元格
  • 无法摆脱脚本中的硬编码延迟

    我用 vba 结合 selenium 编写了一个脚本来解析网页中可用的所有公司名称 该网页启用了延迟加载方法 因此每个滚动中只有 20 个链接可见 如果我滚动 2 次 则可见链接数为 40 个 依此类推 该网页中有 1000 个可用链接 我
  • 来自十六进制代码的 Apache POI XSSFColor

    我想将单元格的前景色设置为十六进制代码中的给定颜色 例如 当我尝试将其设置为红色时 style setFillForegroundColor new XSSFColor Color decode FF0000 getIndexed 无论我在
  • 当使用公式生成超链接时,VBA 打开 Excel 超链接不起作用

    使用公式生成的 Excel 超链接似乎存在错误 我使用的是 Excel 2010 我有一个电子表格 其中的单元格包含 URL 我的目标是执行以下两件事 将这些单元格变成超链接 创建一个键盘快捷键来打开这些超链接 这样我就不必使用鼠标了 为了
  • 如何将 MySQL 查询输出保存到 Excel 或 .txt 文件? [复制]

    这个问题在这里已经有答案了 如何将 MySQL 查询的输出保存到 MS Excel 工作表 即使只能将数据存储在 txt文件 就可以了 From 将 MySQL 查询结果保存到文本或 CSV 文件中 http www tech recipe
  • apache poi cellIterator 跳过空白单元格,但不在第一行

    我正在创建一个 java 程序来读取 Excel 工作表并创建一个逗号分隔的文件 当我运行带有空白列的示例 Excel 文件时 第一行工作正常 但其余行会跳过空白单元格 我已阅读有关将空白单元格插入行所需的代码更改 但我的问题是为什么第一行

随机推荐