Search code examples
javacsvzip

Creating a zip on the fly with csv files inside


I'm trying to create a zip file on the fly containing a bunch of csv files to return from a servlet and its very confusing. A little guidance would be great. Here are chunks of code I have that somehow need to work together:

// output stream coming from httpResponse, thats all fine
ZipOutputStream zip = new ZipOutputStream(outputStream);


// using the openCSV library to create the csv file
CSVWriter writer = new CSVWriter(Writer?); 
// what writer do I use? I want to write to memory, not a file

writer.writeNext(entries); 
writer.close();

// at this point should I have the csv file in memory somewhere? 
//and then try to copy it into the zip file?

int length;
byte[] buffer = new byte[1024 * 32];    
zip.putNextEntry(new ZipEntry(getClass() + ".csv"));

// the 'in' doesn't exist yet - where am I getting the input stream from?
while((length = in.read(buffer)) != -1)
    zip.write(buffer, 0, length);

zip.closeEntry();
zip.flush();

Solution

  • You can stream the ZIP file containing your CSVs as follows :

    try {
        OutputStream servletOutputStream = httpServletResponse.getOutputStream(); // retrieve OutputStream from HttpServletResponse
        ZipOutputStream zos = new ZipOutputStream(servletOutputStream); // create a ZipOutputStream from servletOutputStream
    
        List<String[]> csvFileContents  = getContentToZIP(); // get the list of csv contents. I am assuming the CSV content is generated programmatically
        int count = 0;
        for (String[] entries : csvFileContents) {
            String filename = "file-" + ++count  + ".csv";
            ZipEntry entry = new ZipEntry(filename); // create a zip entry and add it to ZipOutputStream
            zos.putNextEntry(entry);
    
            CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos));  // There is no need for staging the CSV on filesystem or reading bytes into memory. Directly write bytes to the output stream.
            writer.writeNext(entries);  // write the contents
            writer.flush(); // flush the writer. Very important!
            zos.closeEntry(); // close the entry. Note : we are not closing the zos just yet as we need to add more files to our ZIP
        }
    
        zos.close(); // finally closing the ZipOutputStream to mark completion of ZIP file
    } catch (Exception e) {
        log.error(e); // handle error
    }