原标题:Resolve OutOfMemoryError With Excel Export in the Apache POI Stream API
原始链接: https://dzone.com/articles/resolve-outofmemoryerror-with-excelexport-export-e
Whenever we try to export a huge excel spreadsheet (for example: around 200,000-300,000 records), most of the time we end up with an OutOfMemoryError:JavaHeapSpace. We also consume more time and processing power to export that much of data. The main reason for this kind of problem is that the prior version of Apache POI (prior to 3.8) does not provide a proper solution for this kind of situation, and I also have other issues with the API design in those versions. I've sometimes faced situations where we couldn't support more than 65000 rows of data during excel exports with prior versions of POI. But with version 3.8 and higher, there are solutions for all these problems.
To resolve the memory issues and performance issues of Excel exports, they have utilized a stream API to design to support large data exports. With the stream API we can flush only few rows of data into memory and the reamining rows can be flushed to the hard memory (permanent memory). In this example, you can easily see how it supports larger datasets. I wrote this utility for supporting almost 200,000 records with one of my applications. I hope it will help many who are in search of this kind of solution. I built this solution with Spring MVC.
To solve this problem I have applied the template design pattern to create a utility for excel exporting of any data. This is a generic implementation that you can use wherever you want with a respective implementation. Below we have the first abstract class which is generic class. It needs to be extended to implement the export functionality for our corresponding module.
By extending the class above, we can implement our own excel utility to export the data. In this extended class we have to override the 'fillData()' method to provide the data for export. For example, I have taken one such class below for a demo:
Now the utility is ready. The next step is to call this utility from some Action or Controller code for exporting the data. In this case, I am providing the Spring controller Method code. For the sake of understanding I am just providing only the required code snippet from the controller. For the data being exported I am using ServletContext to get the already available search data to avoid multiple hits to the business methods. For this reason I am using SeverletContext to input the data from teh search method and getting the same data from the Export method of the same controller. Here is the code from the controller:
That's all. The functionality is ready now. The next step is to call this controller method from the UI action.
Kindly post your comments if you like it. And also provide your suggestions if you think you have a better approach than this. I really appreciate such suggestions.
Thank you.