Writing Multiple CSV Files From Excel using Java a

2019-08-27 03:27发布

问题:

I'm trying to create a program that writes all the data from excel to multiple csv files.

Currently, my program creates n number of files, and only the last row of excel is being written on the last csv file.

Programming Background Observation:

It seems like the file is writing. But for each written row, it somehow creates the same file 250 times. It erases the row that was written last.

I may have some problems using the OutputStream or BufferedWriter. I just can't figure out what it is.

writeRow() method:

public static void writeRow(BufferedWriter bw, Cell[] row) throws IOException { 
    if (row.length > 0) {
        bw.write(row[0].getContents());
        for (int j = 1; j < row.length; j++) {
            bw.write(',');
            bw.write(row[j].getContents());
        }
    }
}

setFile() method:

public static BufferedWriter setFile (int i) throws IOException {
    i=i/250;
    File f = new File(dir + "file-" + (i+1) + ".csv");
    // If i has changed, create a new file. Else, append to current file.
    String encoding = "UTF8";
    OutputStream os = null;
    OutputStreamWriter osw = null;
    BufferedWriter bw = null;
    Boolean append = null;
    try {
        // If i has changed, create a new file, else append.
        if (i%250==0) {
            append = new Boolean("TRUE");
            os = new FileOutputStream(f,append);
        } else {
            append = new Boolean("FALSE");
            os = new FileOutputStream(f, append);
        }
        osw = new OutputStreamWriter(os, encoding);
        bw = new BufferedWriter(osw);

    } finally {
        os.close();
        osw.close();
    }
    return bw;
}

Here are the exceptions.

Exception in thread "main" java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.BufferedWriter.flush(Unknown Source)
at Main.main(Main.java:46)

Below are some of the links to the code.

What am I doing wrong?

Here is the svn trunk:

https://franz-opensource.googlecode.com/svn/trunk/ExcelToCsv -

  • Click here for the Java Main code like the one above.
  • Click here to download the sample excel file
  • Click here for the jexcelapi download

回答1:

Important Advice: Instead of writing on the same buffer, stop the rows, after every nth records. Then, read the worksheet again. Then, output buffer on another file. You can not be able to change the file while writing on the same buffer.

Here is the whole solution piece by piece:

Static variables:

public static int maxRecords = 250;
public static String directory = "C:\\Users\\User02\\workspace\\ExcelToCsv\\src\\";
public static String inputFile = directory + "inventory.xls";

Main:

public static void main(String[] args) throws BiffException, IOException {
Sheet s = getSheet();
    int countRows = s.getRows(); // counts the number of rows in the sheet.
    int numberOfFiles = (countRows/maxRecords)+1;

    for(int file=0; file<numberOfFiles; file++) {
        System.out.println("Create file number " + (file+1));
        int fileNumber = file+1;
        System.out.println("Start number: " + ((file*maxRecords)+1));
        int startNumber = (file*maxRecords);
        populateFile(fileNumber,startNumber);
        System.out.println("");
    }
}

Populate List:

public static void populateFile(int fileNumber, int startNumber) 
    throws IOException, BiffException {
        BufferedWriter bw = setFile(fileNumber);
        Sheet s = getSheet();
        Cell[] row = null;
        writeRow(bw,s.getRow(0));
        bw.newLine(); 
        int limit = getLimit(s,startNumber);
        System.out.println("End Number:" + limit);
        System.out.println();
        for (int i = startNumber; i < limit ; i++) {
            row = s.getRow(i); 
            //System.out.println(i);
            writeRow(bw,row);
            bw.newLine();
        }
        bw.flush();
        bw.close();
    }

Get the Sheet:

public static Sheet getSheet() throws BiffException, IOException {
    WorkbookSettings ws = new WorkbookSettings();
    ws.setLocale(new Locale("en", "EN"));
    Workbook w = Workbook.getWorkbook(new File(inputFile),ws);
    Sheet s = w.getSheet(0);
    return s;
}

Setting the File to write to:

public static BufferedWriter setFile(int fileNumber) throws IOException {
    String csvFilename = directory + "file-"+ fileNumber +".csv";
    FileWriter csvFile = new FileWriter(csvFilename);
    BufferedWriter bw = new BufferedWriter(csvFile);
    return bw;
}

Getting the Limit:

public static int getLimit(Sheet s, int startNumber) {
    int limit;
    int countRows = s.getRows();
    if (startNumber+maxRecords<=countRows) {
        limit = startNumber + maxRecords;
    } else {
        limit = startNumber + (countRows-startNumber);
    }
    return limit;
}

Write the Rows to file:

public static void writeRow(BufferedWriter bw, Cell[] row) throws IOException { 
    if (row.length > 0) {
        bw.write(row[0].getContents());
        for (int j = 1; j < row.length; j++) {
            bw.write(',');
            bw.write(row[j].getContents());
        }
    }
}