首页 文章

使用Apache POI获取大型Excel文件的Excel工作表名称

提问于
浏览
1

我有以下代码用于获取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

是否有用于在没有大内存印记的 .xlsx 文件中获取工作表名称的API?

1 回答

  • 4

    用他的评论来展示@Gagravarr可能意味着什么:

    XSSFReader包含XSSFReader.getSheetsData方法"Returns an Iterator which will let you get at all the different Sheets in turn. Each sheet's InputStream is only opened when fetched from the Iterator. It's up to you to close the InputStreams when done with each one." . 但通常这不是全部真相 . 实际上它返回一个XSSFReader.SheetIterator,它有一个方法XSSFReader.SheetIterator.getSheetName来获取工作表名称 .

    例:

    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 . 相反,你必须始终看看source code .

相关问题