如何从Web应用程序下载excel文件?

时间:2013-10-15 22:26:56

标签: excel download wicket

我正在使用Wicket(不确定它是否重要)但我正在使用Workbook创建一个excel文件供用户下载。但我不确定如何做到这一点。我想要发生的是用户单击按钮,创建日志并提示用户打开(并保存到临时文件)或保存到他们的计算机。然后从服务器端删除该文件,或者将其存储在用户会话中并在会话结束时删除。

有人能指出我正确的方向吗?如果我可以将文件保存在会话中,那就是创建并让它以某种方式使用FileOutputStream将它发送到客户端..

这是我目前的代码:

 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(); 
   }
  }

3 个答案:

答案 0 :(得分:0)

您必须使用临时文件作为输入创建DownloadLink。下载后必须删除临时文件(file.delete())。

或者你可以试试这个:

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

在这种情况下,data是工作簿的byte []内容,例如可以使用output.toByteArray()检索。

答案 1 :(得分:0)

如果有人遇到这个问题,这是我的解决方案。对此没有太多直接的答案,但这是我的解决方案:

我的excelCreator方法处理excel Sheet的创建,并将其作为文件返回。

 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();
        }
    };

我创建了一个IModel来捕获在我的excelCreator()方法中创建的文件并返回。

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

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

finally, 

我打电话,

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

这会在创建文件后删除该文件。缓存设置是一个设置,以确保它与所有浏览器兼容(这就是我如何解释它,但你可能不需要它)。

Imodel动态创建文件,因此不必存储在任何地方,然后在下载文件后将其删除。

希望这有助于某人!

答案 2 :(得分:0)

您可以创建Resource来执行此操作,然后制作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 :)
    }

}