简体   繁体   English

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

[英]How to download excel file from web application?

I'm using Wicket (not sure if it matters) but I'm using Workbook to create an excel file for a user to download. 我正在使用Wicket(不确定是否重要),但正在使用Workbook创建一个供用户下载的excel文件。 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.. 如果我根本无法将文件保存在会话中,则可以创建该文件,然后使用FileOutputStream将其发送到客户端。

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

You would have to create a DownloadLink with the temporary file as input. 您将必须使用临时文件作为输入来创建DownloadLink。 The temporary File must be deleted after download (file.delete())). 下载后必须删除临时文件(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(). 在这种情况下,数据是工作簿的byte []内容,例如,可以使用output.toByteArray()进行检索。

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. 我的excelCreator方法处理excel工作表的创建,并将其作为文件返回。

 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. 我创建了一个IModel来捕获在excelCreator()方法中创建的文件并返回。

       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. Imodel动态创建文件,因此不必将其存储在任何地方,然后在下载文件后将其删除。

Hope this helps someone! 希望这对某人有帮助!

You could create a Resource to do this, and make a ResourceLink . 您可以创建一个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 :)
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM