今天在处理Excel文件时候,发现对于以xls和xlsx为后缀的文件,用以下的代码处理时候抛 The supplied data appears to be in the OLE2 Format.异常,百思不得其姐!!! 明明都判断类型对应的文件类型也没毛病啊!!

        try {
          if ((filename.endsWith(".xls"))) {
              workbook = new HSSFWorkbook(inputStream);
          } else if (filename.endsWith(".xlsx")) {
              workbook = new XSSFWorkbook(inputStream);
          }

于是,我就想如何能得到workbook对象呢,是不是对象工厂构造然后返回对应的类型对象呢,百度之后发现有个WorkbookFactory对象构造workbook,查看源码,看到如下方法

   public static Workbook create(InputStream inp) throws IOException, InvalidFormatException, EncryptedDocumentException {
        return create((InputStream)inp, (String)null);
    }
  public static Workbook create(InputStream inp, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {
        InputStream is = FileMagic.prepareToCheckMagic(inp);
        FileMagic fm = FileMagic.valueOf(is);
        switch(fm) {
        case OLE2:
            NPOIFSFileSystem fs = new NPOIFSFileSystem(is);
            return create(fs, password);
        case OOXML:
            return new XSSFWorkbook(OPCPackage.open(is));
        default:
            throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
        }
    }
  

上面的create方法对应下面方法,不得不说这重载的方法真的很巧妙。

    private static Workbook create(NPOIFSFileSystem fs, String password) throws IOException, InvalidFormatException {
        DirectoryNode root = fs.getRoot();
        if (root.hasEntry("EncryptedPackage")) {
            InputStream stream = DocumentFactoryHelper.getDecryptedStream(fs, password);
            OPCPackage pkg = OPCPackage.open(stream);
            return create(pkg);
        } else {
            boolean passwordSet = false;
            if (password != null) {
                Biff8EncryptionKey.setCurrentUserPassword(password);
                passwordSet = true;
            }

            HSSFWorkbook var4;
            try {
                var4 = new HSSFWorkbook(root, true);
            } finally {
                if (passwordSet) {
                    Biff8EncryptionKey.setCurrentUserPassword((String)null);
                }

            }
            return var4;
        }
    }

唉,这不就是我想要的判断吗!!!成功解决OLE2和OOXML Format问题!!!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐