如何解决此异常?我需要在zip上添加多个xlsx。第一个xlsx被添加到列表中,但第二个会抛出此错误:
public void downloadData() throws Exception {
FacesContext fc = FacesContext.getCurrentInstance();
setSourceList(new ArrayList<String>());
setTargetList(new ArrayList<String>());
List<String> tempList = dualList.getTarget();
System.out.println(tempList.size());
if (tempList != null && tempList.size() > 0) {
ExternalContext ec = fc.getExternalContext();
ec.responseReset();
ec.setResponseContentType("application/zip");
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"Export.zip\"");
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outByteStream);
OutputStream outStream = ec.getResponseOutputStream();
for (int i = 0; i < tempList.size(); i++) {
outByteStream = new ByteArrayOutputStream();
//zip = new ZipOutputStream(outByteStream);
// outStream = ec.getResponseOutputStream();
int id = ownerNameIdMap.get(tempList.get(i));
String oName = tempList.get(i);
String fileName = oName + ".xlsx";
if (petList != null && petList.size() > 0) {
petList.clear();
}
workBook = new XSSFWorkbook();
OwnerModel ownerModel = ownerMap.get(id);
ownerFirstName = ownerModel.getFirstName();
ownerLastName = ownerModel.getLastName();
workSheet = workBook.createSheet(ownerLastName + ", " + ownerFirstName);
petList = iOwnerRepository.getActivePetsOfOwner(ownerModel.getId());
petCount = petList.size();
createMasterSheet();
renderSheet(ownerModel);
workBook.write(outByteStream);
//addEntry(zip, fileName, outByteStream);
ZipEntry entry = new ZipEntry(fileName);
zip.putNextEntry(entry);
System.out.println(fileName);
zip.write(outByteStream.toByteArray());
zip.closeEntry();
workBook.write(zip);
outStream.write(outByteStream.toByteArray());
}
outStream.flush();
outStream.close();
zip.close();
fc.responseComplete();
}
}
我的堆栈跟踪
SEVERE: Received 'java.io.IOException' when invoking action listener '#{exportViewBean.downloadData}' for component 'j_idt83'
May 03, 2017 11:24:13 AM javax.faces.event.MethodExpressionActionListener processAction
SEVERE: java.io.IOException: Stream closed
at java.util.zip.ZipOutputStream.ensureOpen(ZipOutputStream.java:97)
at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:190)
at com.fetchinglife.modules.dataimport.views.ExportViewBean.downloadData(ExportViewBean.java:218)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:153)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:771)
at javax.faces.component.UICommand.broadcast(UICommand.java:300)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:786)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1251)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
答案 0 :(得分:0)
尝试合并使用outByteStream
。您在for
循环之前打开它并使用它初始化zip
但在for
循环内您将另一个ByteArrayOutputStream
实例分配给outByteStream
,然后使用此实例。我不确定这是否会导致您的异常,但可能值得尝试......
答案 1 :(得分:0)
你好,我有这个问题,仅将第一个文件添加到zip流中并抛出流关闭异常,因此我首先将文件转换为字节数组,而不在zip.write()方法中使用流,将我的代码更改为跟随
private byte[] _toByteArray(InputStream in) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
return os.toByteArray();
}
public byte[] getAllAssignmentSubmissionResourceAsZip(
long lmsAssignmentId) {
List<DLFileEntry> dlFileEntries =
lmsAssignmentFinder.getLastAssignmentSubmissionsResourceByLA(
lmsAssignmentId);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zout = new ZipOutputStream(baos);
try {
for (DLFileEntry dl : dlFileEntries) {
byte[] dlBytes = _toByteArray(dl.getContentStream());//output of getContenStream is InputSream type
ZipEntry zip = new ZipEntry(dl.getFileName());
zout.putNextEntry(zip);
zout.write(dlBytes);
zout.closeEntry();
}
}
catch (Exception e) {
System.out.println(e.getMessage());
}
try {
zout.flush();
zout.close();
}
catch (IOException e) {
e.printStackTrace();
}
return baos.toByteArray();
}
并设置为响应:
byte[] zipFile =
_lmsAssignmentService.getAllAssignmentSubmissionResourceAsZip(
siteId, assignmentId);
String fileName = "test";
String dispositionDesc = String.format(
"attachment;filename=\"%s\"", fileName);
Response.ResponseBuilder responseBuilder = Response.ok(zipFile);
responseBuilder.header("Content-Disposition", dispositionDesc);
responseBuilder.header("Content-Type", "application/zip");
我希望这个答案有帮助