gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 02:27:06 25 4
gpt4 key购买 nike

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

我正在使用下面的代码

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

但它显示堆内存问题。

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

问题 1)我们无法使用 SXSSF(流用户模型 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();
}
}
}

关于excel - 如何使用大型 Excel 文件的 XSSF 和 SAX(事件 API)获取命名范围、工作表名称和引用公式的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46363139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com