0

I've got an XPage that creates an Excel file using server-side javascript (thank to Russ Maher). I know how to save it to the C: drive if I'm running the XPage locally in a browser, but don't know how to save it to the user's machine when it's running on the server without first saving it to the server. The following code is used to save it from the server's perspective.

var fileOut = new java.io.FileOutputStream(directory+fileName);
xl.write(fileOut);
fileOut.close();

Any ideas how I can direct that to the user's drive?

David Navarre
  • 1,022
  • 10
  • 27

2 Answers2

1

Instead of writing the Excel workbook to a FileOutputStream, you should write it to a ByteArrayOutputStream:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
xl.write(outputStream);

You probably need to use an XAgent to create the output and then link to the XAgent from your XPage. Maybe this blog entry by Declan Lynch combined with this answer on how to do it in a servlet can guide you in the right direction.

Community
  • 1
  • 1
Per Henrik Lausten
  • 21,331
  • 3
  • 29
  • 76
  • Per is right. Look at the XAgent snippet in XSnippets on OpenNTF. It provides the outputstream. So instead of creating your own stream pass it as a parameter to your method. The content-disposition header can then determine the file name. Keep in mind the user needs to confirm the save. Also have a look at Apache POI for more advanced Excel output capabilities – stwissel Aug 02 '12 at 00:20
  • Thanks, Per, will check it out. @stwissel I am using Apache POI, but am a real amateur at it, having just taken Russ Maher's implementation and expanded on it a little. – David Navarre Aug 02 '12 at 13:43
0

Paul Calhoun sent me some sample code that I massaged to get it to produce the spreadsheet that I wanted. I don't know what it was that he'd done that I hadn't, but, for now, I think this is the heart of the solution, just harnessing an OutputStream instead of either a FileOutputStream or ByteArrayOutputStream.

// The Faces Context global object provides access to the servlet environment via the external content
var extCont = facesContext.getExternalContext(); 
// The servlet's response object provides control to the response object
var pageResponse = extCont.getResponse();
//Get the output stream to stream binary data
var pageOutput = pageResponse.getOutputStream();

// Set the content type and headers
pageResponse.setContentType("application/x-ms-excel");
pageResponse.setHeader("Cache-Control", "no-cache");
pageResponse.setHeader("Content-Disposition","inline; filename=" + fileName);
//Write the output, flush the buffer and close the stream
wb.write(pageOutput);
pageOutput.flush();
pageOutput.close();

//  Terminate the request processing lifecycle.
facesContext.responseComplete();

I will gladly provide help if someone else encounters this issue and, hopefully, by the time someone asks, I will understand more of what was different that worked....

David Navarre
  • 1,022
  • 10
  • 27