3

I implement an upload service for Microsoft Excel files and can not be sure what kind of file is uploaded. Sometimes users upload files with xls extension that contain xlsx content. To parse the files I use Apache Poi and currently I try at first to parse the uploaded file as HSSFWorkbook and if I catch an exception then I try to create a XSSFWorkbook.

Is there any smarter way to detect what version is needed?

/** should parse the uploaded file */
private void handleUpload(File file) {
  Workbook wb = tryToHandleHSSF(file);
  if (wb==null)
    wb = tryToHandleXSSF(file);
  if (wb!=null) {
    // ... do the parsing stuff
  }
}

/** helper for HSSF */
private Workbook tryToHandleHSSF(File file) {
  try {
    return new HSSFWorkbook(new FileInputStream(file));
  }
  catch(Exception e) {
    return null;
  }
}

/** helper for XSSF */
private Workbook tryToHandleXSSF(File file) {
  Workbook workbook;
  try {
    InputStream fin = new FileInputStream(file);
    BufferedInputStream in = new BufferedInputStream(fin);
    try {
        if (POIFSFileSystem.hasPOIFSHeader(in)) {
            // if the file is encrypted
            POIFSFileSystem fs = new POIFSFileSystem(in);
            EncryptionInfo info = new EncryptionInfo(fs);
            Decryptor d = Decryptor.getInstance(info);
            d.verifyPassword(Decryptor.DEFAULT_PASSWORD);
            workbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook(d.getDataStream(fs));
        }
        else
            return new org.apache.poi.xssf.usermodel.XSSFWorkbook(in);
    }
    finally {
        in.close();
    }
  }
  catch(Exception e) {
    return null;
  }
}
centic
  • 15,565
  • 9
  • 68
  • 125
OkieOth
  • 3,604
  • 1
  • 19
  • 29

1 Answers1

11

You could use the SS Usermodel which can handle both XSSF and HSSF Workbooks.

To load the workbook from the file in a type agnostic way, you may use the create method from WorkbookFactory.

import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.Workbook;

...
...

// SS Workbook object
Workbook workbook;

// Handles both XSSF and HSSF automatically
workbook = WorkbookFactory.create(new FileInputStream(file)); 

//Do your parsing using the workbook object
Mustafa
  • 2,447
  • 23
  • 31