0

我正在使用 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(); 
   }
  }
4

3 回答 3

0

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

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

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

希望这对某人有帮助!

于 2013-10-16T17:53:46.777 回答
0

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

或者你可以试试这个:

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

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

于 2013-10-16T07:03:11.367 回答
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 :)
    }

}
于 2013-10-17T08:25:42.663 回答