0

I'm using Wicket (not sure if it matters) but I'm using Workbook to create an excel file for a user to download. But I'm not sure how exactly to do this. What I would like to happen is the user clicks the button, a log is created and a prompt is given to the user to open (and save to temp files) or to save to their computer. The file is then deleted from the server side, or maybe it is stored in the User's session and deleted at end of session.

Can someone point me in the right direction? If I can have the file not saved in the session at all, that'd be create and have it just have it sent to the client using FileOutputStream somehow..

here is my current code:

 private void excelCreator()
 {
   Workbook workbook = new HSSFWorkbook();

   Sheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("SSA User ID " + currentSSAIDSelection2.getSsaUserId()));

    Iterator<AuditLogEntry> auditLogEntrys = logList.iterator();

    int i = 0;
    while (auditLogEntrys.hasNext())
    {
     final AuditLogEntry auditLogEntry = auditLogEntrys.next();

     Row row = sheet.createRow(i);

     row.createCell(0).setCellValue(auditLogEntry.getTimeStamp());
     row.createCell(1).setCellValue(auditLogEntry.getSourceName());
     row.createCell(2).setCellValue(auditLogEntry.getCategory());
     row.createCell(3).setCellValue(auditLogEntry.getSsaAdmin());
     row.createCell(4).setCellValue(auditLogEntry.getAction());

     i++;
   }

   try
   {
       FileOutputStream output = new FileOutputStream("ssaUserIDAccess.xls");
       workbook.write(output);
       output.close();

   }catch(Exception e)
   {
      e.printStackTrace(); 
   }
  }
eaglei22
  • 2,589
  • 1
  • 38
  • 53
  • Nevermind I found this link http://stackoverflow.com/questions/7646270/how-to-use-wickets-downloadlink-with-a-file-generated-on-the-fly – eaglei22 Oct 15 '13 at 23:12

3 Answers3

0

You would have to create a DownloadLink with the temporary file as input. The temporary File must be deleted after download (file.delete())).

Alternatively you can try this:

IResourceStream stream = new ByteArrayResourceStream(data, "application/vnd.ms-excel");
RequestCycle.get().scheduleRequestHandlerAfterCurrent(new ResourceStreamRequestHandler(stream, filename).setContentDisposition(ContentDisposition.ATTACHMENT));

In this case data is the byte[] content of your workbook which can be for example retrieved with output.toByteArray().

thg
  • 1,209
  • 1
  • 14
  • 26
0

In case anyone runs into this problem here is my solution. There wasn't a lot of straight forward answers on this but this is my solution:

My excelCreator method handles the creation of the excel Sheet, and returns it as a file.

 private File excelCreator()
  {
   Workbook workbook = new HSSFWorkbook();
   File excelfile = new File("userIDAccess.xls");
   logList = getServer().findAuditLogs(getUserId(), null);
   Sheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("User ID " + getUserId()));

    Iterator<AuditLogEntry> auditLogEntrys = logList.iterator();

    int i = 0;
    while (auditLogEntrys.hasNext())
    {
     final AuditLogEntry auditLogEntry = auditLogEntrys.next();

     Row row = sheet.createRow(i);

     row.createCell(0).setCellValue(auditLogEntry.getTimeStamp());
     row.createCell(1).setCellValue(auditLogEntry.getSourceName());
     row.createCell(2).setCellValue(auditLogEntry.getCategory());
     row.createCell(3).setCellValue(auditLogEntry.getSsaAdmin());
     row.createCell(4).setCellValue(auditLogEntry.getAction());

     i++;
   }

   try
   {

       FileOutputStream output = new FileOutputStream(excelfile);
       workbook.write(output);
       output.close();


   }catch(Exception e)
   {
      e.printStackTrace(); 
   }

   return excelfile;
 }

   IModel excelFileModel = new AbstractReadOnlyModel()
       {
        public Object getObject() 
                { 
            return excelCreator();
        }
    };

I created an IModel to capture the file created inside my excelCreator() method and returned.

       auditDownloadlink = new DownloadLink("auditDownloadlink", excelFileModel);

       I pass the I.D. of the download link, and then pass the imodel. 

finally, 

I call,

   auditDownloadlink.setDeleteAfterDownload(true);
   auditDownloadlink.setCacheDuration(Duration.NONE);

This deletes the file after it is created. And the cache setting is a setting to make sure it is compatible with all browsers (That's how I interpreted it, but you may not need it).

The Imodel creates the File on the fly so it doesn't have to be stored anywhere, and then the file is deleted once it is downloaded.

Hope this helps someone!

eaglei22
  • 2,589
  • 1
  • 38
  • 53
0

You could create a Resource to do this, and make a ResourceLink.

public class ExcelProducerResource extends AbstractResource
{
    public ExcelProducerResource()
    {

    }

    @Override
    protected ResourceResponse newResourceResponse( Attributes attributes )
    {

        final String fileName = getFileName();

        ResourceResponse resourceResponse = new ResourceResponse();
        resourceResponse.setContentType( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
        resourceResponse.setCacheDuration( Duration.NONE );
        resourceResponse.setFileName( fileName );
        resourceResponse.setWriteCallback( new WriteCallback()
        {
            @Override
            public void writeData( Attributes attributes ) throws IOException
            {
                OutputStream outputStream = attributes.getResponse().getOutputStream();

                writeToStream( outputStream );
                outputStream.close();
            }
        } );
        return resourceResponse;
    }

    void writeToStream(OutputStream outputStream) throws IOException
    {
        //.. do stuff here :)
    }
    String getFileName()
    {
        //.. do stuff here :)
    }

}
Rob Audenaerde
  • 19,195
  • 10
  • 76
  • 121