Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance comparison between JXL and POI FOR excel file generations

Here is the code that generates .xls file using JXL:

public void generateXls(String fileName, int sheets, int cols, int rows) {

    if (cols > 256) {
        throw new IllegalArgumentException("Error: number of cols per sheet must be < 256");
    }

    if (rows > 65536) {
        throw new IllegalArgumentException("Error: number of rows per sheet  must be < 65536");
    }

    String fullName = fileName + ".xls";
    WritableWorkbook workbook = null;
    try {
        workbook = Workbook.createWorkbook(new File(fullName));
    } catch (IOException e) {
        e.printStackTrace();
    }
    Random random = new Random();
    for (int s = 0; s < sheets; s++ ) {
        WritableSheet sheet = workbook.createSheet("Sheet" + s, 0);
        for (int i = 0; i < cols ; i++) {
            for (int j = 0;  j < rows; j++) {
                Number number = new Number(i, j, random.nextDouble()*1000);
                try {
                    sheet.addCell(number);
                } catch (RowsExceededException e) {
                    throw new RuntimeException("Error: too many rows in a sheet");
                } catch (WriteException e) {
                    throw new RuntimeException("Error occured while adding cell to sheet", e);
                }
            }
        }
    }

    try {
        workbook.write(); 
        workbook.close();
    } catch (WriteException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

Here is the code that generates .xls and .xlsx files using POI:

public void generateXlsx(String fileName, int sheets, int cols, int rows) {

    if (cols > 16383) {
        throw new IllegalArgumentException("Error: number of cols per sheet must be < 16383");
    }
    XSSFWorkbook workbook = new XSSFWorkbook();

    Random random = new Random();
    for (int s = 0; s < sheets; s++ ) {
        XSSFSheet sheet = workbook.createSheet();
        for (int i = 0; i < rows ; i++) {
            XSSFRow row =  sheet.createRow(i);
            for (int j = 0;  j < cols; j++) {
                XSSFCell cell = row.createCell(j);
                cell.setCellValue(random.nextDouble()*1000);
            }
        }
    }

    FileOutputStream fileOut = null;
    try {
        fileOut = new FileOutputStream(fileName);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        workbook.write(fileOut);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        fileOut.flush();
        fileOut.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

public void generateXls(String fileName, int sheets, int cols, int rows) {

    if (cols > 256) {
        throw new IllegalArgumentException("Error: number of cols per sheet must be < 256");
    }

    HSSFWorkbook workbook = new HSSFWorkbook();

    Random random = new Random();
    for (int s = 0; s < sheets; s++ ) {
        HSSFSheet sheet = workbook.createSheet();
        for (int i = 0; i < rows ; i++) {
            HSSFRow row =  sheet.createRow(i);
            for (int j = 0;  j < cols; j++) {
                HSSFCell cell = row.createCell(j);
                cell.setCellValue(random.nextDouble()*1000);
            }
        }
    }

    FileOutputStream fileOut = null;
    try {
        fileOut = new FileOutputStream(fileName);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        workbook.write(fileOut);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        fileOut.flush();
        fileOut.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

I wrote a performance test:

public static void main(String[] args) {

    int sheets =1;
    int cols = 255;
    int rows = 20000;
    long a1 = System.currentTimeMillis();
    ExcelFileGenerator generator  = new ExcelFileGenerator();
    generator.generateXls("xlsJXL.xls", sheets, cols, rows);
    long xls = System.currentTimeMillis()-a1;
    System.out.println("xlsJXL: " + xls);
    ExcelFileGeneratorPOI generatorPOI = new ExcelFileGeneratorPOI();
    long a2 = System.currentTimeMillis();
    generatorPOI.generateXls("xlsPOI.xls", sheets, cols, rows);
    long xlsPoi = System.currentTimeMillis()-a2;
    System.out.println("xlsPOI: " + xlsPoi);
    long a3 = System.currentTimeMillis();
    generatorPOI.generateXlsx("xlsxPOI.xlsx", sheets, cols, rows);
    long xlsx = System.currentTimeMillis()-a3;
    System.out.println("xlsxPOI: " + xlsx);
}

The results are: sheets =1 cols = 255 rows = 10 xlsJXL: 133 xlsPOI: 162 xlsxPOI: 645

sheets =1 cols = 10 rows = 255 xlsJXL: 130 xlsPOI: 140 xlsxPOI: 650

sheets =10 cols = 255 rows = 255 xlsJXL: 611 xlsPOI: 784 xlsxPOI: 16228

sheets =2 cols = 100 rows = 10000

xlsJXL: 2755 xlsPOI: 3270 xlsxPOI: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

any reason by creating .xlsx with POI is much slower than creating .xls?

like image 918
AAaa Avatar asked Jan 22 '12 18:01

AAaa


1 Answers

xls is a binary based format, xlsx is an XML based format and requires more work to read/write.

xlsx might also require an in memory document model to parse/build the XML which could be more complex.

Finally, xls could be optimised better because it has been supported longer.

like image 62
Peter Lawrey Avatar answered Sep 21 '22 09:09

Peter Lawrey