0

I'm relatively new to Java (learning on my own for about 6 months) and I have never written a program as large as the one I'm working on now. I have to take tax data and filter it and then calculate fees for an entire county given an Excel spreadsheet and then output a new Excel Workbook with the data sorted on different sheets using Apache POI v4.1.2. I've been working on this program for a month and I finally got it to where it works beautifully for an excerpt of 100 out of the 135k records. When I went to run it on the full file I got a NullPointer error. I believe this is because my laptop ran out of memory and that it happened because I only write the file at the end of the program so it has to store all the data and calculations and everything else until the very end.

Sorry for the long intro but my question is: How do I write the file, close it, and reopen it periodically to give my poor potato laptop a break before taking it's next "byte" of data (sorry for the pun. I couldn't resist)? I know I should post code and an error log but my code is pretty long with a class and a bunch of methods in it and I don't think you guys want to read my entire 700+ line code. If there is something in particular I can share then let me know. Be gentle though. I've always been able to find my answers with a search and so I haven't really needed to ask questions before. Of course if there is there is a better way of preserving memory as a program runs then I'm open to that suggestion as well.

package swfeecalc;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JOptionPane;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 *
 * @author B
 */


public class SWFeeCalc {

    /**
     * @param args the command line arguments 
     */
    public static void main(String[] args) throws IOException {

        //Excel Workbook
        XSSFWorkbook wb = null;

        //Excel Sheets
        XSSFSheet orgSht = null; //original raw data minus unused columns
        XSSFSheet sortSht = null; //sorted raw data sheet
        XSSFSheet dupSht = null; //duplicates that were thrown out
        XSSFSheet exSht = null; //records thrown out because of exemptions
        XSSFSheet finSht = null; //final product
        XSSFSheet errSht = null; //unhandled errors (may not end up getting used)

        CellCopyPolicy policy = new CellCopyPolicy();
        try{

            //output fileDir
            String date = new SimpleDateFormat("MM-dd-yyyy").format(new Date());        
            String rawDataInputFolder = "C:\\StormWaterFeeReports\\Reports\\" +date +"\\";       
            File excelFolder = new File(rawDataInputFolder);
            boolean dirCreated = excelFolder.mkdirs();
            System.out.println("Directory created = " +dirCreated);

            //output sheet name
            String timeStamp = new SimpleDateFormat("HH.mm.ss").format(new Date());
            String rawDataInput = ("FeeData " +timeStamp +".xlsx");
            File excelFile = new File(rawDataInputFolder +rawDataInput);

            //create output sheets
            wb = new XSSFWorkbook();
            finSht = wb.createSheet ("Final Product");
            sortSht = wb.createSheet("Sorted Raw Data");
            orgSht = wb.createSheet("Raw Data");
            dupSht = wb.createSheet("Duplicates");
            exSht = wb.createSheet ("Exemptions");           
            errSht = wb.createSheet ("Unhandled Errors");
            FileOutputStream out = new FileOutputStream(excelFile);
            int rowNum = 0; //row number
            int cellNum = 0; //cell number


            //Create output sheets title row

            XSSFRow row = orgSht.createRow(rowNum);
            XSSFCell cell = row.createCell(cellNum);

            //prompt user to put file in folder
            JOptionPane.showMessageDialog(null, "Folder created... \n"
                    + "Please enter an Excel spreadsheet titled 'RawData' (rename if necessary) in to the folder at the following location: \n\n" 
                    +rawDataInputFolder +"\n\n"
                    + "This file will be used to calculate the Storm Water fee and should be the raw tax data provided by the Assessors office.\n "
                    + "Please rename the file as mentioned above if needed. \n"
                    + "Click OK when finished.");

            //input file path     
            String excelInputName = rawDataInputFolder +"RawData.xlsx";   //create string to hold file directory for new workbook     
            FileInputStream inputStream = new FileInputStream(new File(excelInputName));    //finds inputStream from the file directory in excelInputName


            //create input workbook
            XSSFWorkbook iwb = new XSSFWorkbook(inputStream);

            //input sheet
            XSSFSheet inSht = iwb.getSheetAt(0);           

            int rowEnd = inSht.getLastRowNum(); //variable to hold end of row
            double inCellValNum;
            String inCellValStr;
            CellType type = cell.getCellType();

                for (int i = 0; i <= rowEnd; i++){  //loop that populates the orgSht
                    XSSFRow inRow = inSht.getRow(i);    
                    row = orgSht.createRow(i);
                    cellNum = 0;


                    for (int j = 0; j < inRow.getLastCellNum(); j++){


                        if(j ==0 || j ==3 || j ==4 || j ==5 || j ==6 || j ==9 || j ==11){
                    }
                        else{
                            XSSFCell inCell = inRow.getCell(j);
                            type = inCell.getCellType();    //checks cell type of current input cell

                            if (type == CellType.NUMERIC){
                                cell = row.createCell(cellNum); //make a new cell to store value
                                inCellValNum = inCell.getNumericCellValue();    //save value from input cell
                                cell.setCellValue(inCellValNum);    //set the newly created cells value to the stored value
                            }
                            if (type == CellType.STRING){
                                cell = row.createCell(cellNum);
                                inCellValStr = inCell.getStringCellValue();
                                cell.setCellValue(inCellValStr);
                            }
                            cellNum++;
                        }
                    }  
                }

The error

Directory created = true
Exception in thread "main" java.lang.NullPointerException
    at swfeecalc.SWFeeCalc.main(SWFeeCalc.java:121)
C:\Users\BD\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 8 seconds)
T.D.
  • 1
  • 1
  • 4
    NullPointerException has nothing to do with memory, you would get OutOfMemoryException if that would be the case. – Amongalen Mar 12 '20 at 14:34
  • 1
    I think posting the stacktrace and relevant code wouldn't hurt. – Amongalen Mar 12 '20 at 14:38
  • I thought so too but why would it work on a smaller excerpt of 100 records but not on the larger file? I've actually gone through and looked for empty cells and I've also tried 500 records and that works. – T.D. Mar 12 '20 at 14:39
  • 1
    Post the stack trace and code where it is breaking. – Rahul Agrawal Mar 12 '20 at 14:40
  • First, a nullpointerexception means you are trying to call a method on an object that is NULL. Second, you can write to the document after every 100 records if you like and clean up your data memory. You don't specifically have to write at the end. – Wesley De Keirsmaeker Mar 12 '20 at 14:43
  • I posted the very first part of the code. There is much more but I can't get through that without an error now when I use the full sheet with all the data – T.D. Mar 12 '20 at 14:48
  • Which one is the 121st line? – Amongalen Mar 12 '20 at 14:50
  • type = inCell.getCellType(); //checks cell type of current input cell – T.D. Mar 12 '20 at 14:53
  • 1
    Well, it seems that `inCell` is null for whatever reason. – Amongalen Mar 12 '20 at 14:55
  • You could put a conditional breakpoint and check with a debugger `i` and `j` values for which it is null and go from there. – Amongalen Mar 12 '20 at 14:56
  • Also check your logic for which you are skipping your columns for values like 0,3,4,5,6,9,11 applies to this j for which it is failing – Rahul Agrawal Mar 12 '20 at 14:57
  • `getCell()` or `getRow()` returns `null` when no content has been written to that particular row/cell, which is most probably your case. In simple words, the cell is empty and has never been used. – Pavel Smirnov Mar 12 '20 at 14:58
  • Thank you folks. I haven't fixed the code yet but I have some tools to use to fix it now. I honestly didn't realize that it told me exactly what line it encountered the error on... lessons learned. Thanks again. – T.D. Mar 12 '20 at 15:01

0 Answers0