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