我使用以下代码来获取excel文件的工作表名称(.xlsx)

    XSSFWorkbook workBookXlsx = new XSSFWorkbook(new FileInputStream(pathToFile));
    ArrayList<String> sheetNames = new ArrayList<>();

    int numberOfSheets = workBookXlsx.getNumberOfSheets();
    for (int i = 0; i < numberOfSheets; i++) {
        sheetNames.add(workBookXlsx.getSheetAt(i).getSheetName());
    }

    workBookXlsx = null;


上面的代码存在的问题是,为9MB大小的文件创建XSSFWorkbook会占用大量内存(〜700MB)和较长时间(5-6s)。即使将workBookXlsx设置为null也不会释放javaw占用的内存(我知道gc可能会也可能不会被调用,并且JVM不会因为我将变量设置为null而释放内存)

我确实浏览了WorkbookXSSFWorkbook的文档,据我了解,没有任何方法可以帮助我获得内存烙印少的工作表名称。

我发现的一种解决方案是手动解压缩.xlsx文件并读取.\xl\woorkbook.xml的内容以获取工作表名称和r:id

是否有一个API可在没有大内存印记的情况下在.xlsx文件中获取工作表名称?

最佳答案

为了显示@Gagravarr的评论可能意味着什么:

XSSFReader包含方法XSSFReader.getSheetsData,该方法“返回一个迭代器,该迭代器将使您依次获得所有不同的Sheets。仅在从Iterator提取时才打开每个表单的InputStream。由您决定完成时关闭InputStreams每个。”。但是通常这不是全部。实际上,它返回一个XSSFReader.SheetIterator,该XSSFReader.SheetIterator.getSheetName具有用于获取工作表名称的方法source code

例:

import java.io.InputStream;
import java.io.FileInputStream;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;

import java.util.Iterator;

public class ExcelXSSFGetSheetNamesXSSFReader {

 public static void main(String[] args) throws Exception {

  OPCPackage pkg = OPCPackage.open(new FileInputStream("Example.xlsx"));
  XSSFReader r = new XSSFReader( pkg );
  Iterator<InputStream> sheets = r.getSheetsData();

  if (sheets instanceof XSSFReader.SheetIterator) {
   XSSFReader.SheetIterator sheetiterator = (XSSFReader.SheetIterator)sheets;

   while (sheetiterator.hasNext()) {
    InputStream dummy = sheetiterator.next();

    System.out.println(sheetiterator.getSheetName());

    dummy.close();
   }
  }

  pkg.close();
 }
}


结论:当前,您只能通过信任API文档才能使用apache poi。相反,您必须始终查看。

07-27 23:17