Exporting largish csv files

UI Components for JSF
Post Reply
mattharr
Posts: 20
Joined: 01 Feb 2011, 04:49

22 Mar 2011, 20:57

Hi,

I'm using PrimeFaces 2.2.1, and we're exporting a fairly large set of data via the Exporter. I found we hit a bit of a problem when the file got a bit bigger (the example that triggered it here was 26kb). It seemed that the PrintWriter was flushing its full buffer out to the browser, and then the browser tried to render the half completed response - causing some very odd behavior.

Had a little look at the CSVExporter, and made a change to get it to write out to a ByteArrayOutputStream, so we can get the length, and set that for the browser:

Code: Select all

@Override
	public void export(FacesContext facesContext, DataTable table, String filename, boolean pageOnly, int[] excludeColumns,
			String encodingType, MethodExpression preProcessor, MethodExpression postProcessor) throws IOException {

		ByteArrayOutputStream output = new ByteArrayOutputStream();
		OutputStreamWriter osw = new OutputStreamWriter(output, encodingType);
		PrintWriter writer = new PrintWriter(osw);
		List<UIColumn> columns = getColumnsToExport(table, excludeColumns);

		addColumnHeaders(writer, columns);

		int first = pageOnly ? table.getFirst() : 0;
		int size = pageOnly ? (first + table.getRows()) : table.getRowCount();

		for (int i = first; i < size; i++) {
			table.setRowIndex(i);
			addColumnValues(writer, columns);
			writer.write("\n");
		}

		table.setRowIndex(-1);

		HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();

		response.setContentType("text/csv");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
		response.setHeader("Pragma", "public");
		response.setHeader("Content-disposition", "attachment;filename=" + filename + ".csv");

		byte[] toSend = output.toByteArray();
		response.setContentLength(toSend.length);

		OutputStream os = response.getOutputStream();
		os.write(toSend);

		writer.flush();
		writer.close();

		response.getOutputStream().flush();
	}
I know this might give us an issue with very large files, but is this likely to hit any other problems?

Maybe/hopefully this will be of use.

Cheers,

Matt

mattharr
Posts: 20
Joined: 01 Feb 2011, 04:49

03 May 2011, 05:12

Just if this is any use to anyone. The code previously had a bit of an issue in that it wouldn't always send all the file. I believe this was because the writers weren't being flushed before figuring out how much there was to send, so an amended method is:

Code: Select all

@Override
	public void export(FacesContext facesContext, DataTable table, String filename, boolean pageOnly, int[] excludeColumns,
			String encodingType, MethodExpression preProcessor, MethodExpression postProcessor) throws IOException {

		ByteArrayOutputStream output = new ByteArrayOutputStream();
		OutputStreamWriter osw = new OutputStreamWriter(output, encodingType);
		PrintWriter writer = new PrintWriter(osw);
		List<UIColumn> columns = getColumnsToExport(table, excludeColumns);

		addColumnHeaders(writer, columns);

		int first = pageOnly ? table.getFirst() : 0;
		int size = pageOnly ? (first + table.getRows()) : table.getRowCount();

		for (int i = first; i < size; i++) {
			table.setRowIndex(i);
			addColumnValues(writer, columns);
			writer.write("\n");
		}

		table.setRowIndex(-1);

		HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();

		response.setContentType("text/csv");
		response.setHeader("Expires", "0");
		response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
		response.setHeader("Pragma", "public");
		response.setHeader("Content-disposition", "attachment;filename=" + filename + ".csv");

		writer.flush();
		osw.flush();

		byte[] toSend = output.toByteArray();
		response.setContentLength(toSend.length);

		OutputStream os = response.getOutputStream();
		os.write(toSend);

		writer.close();

		response.getOutputStream().flush();
	}
Cheers,

Matt

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: jlafosse and 15 guests