所以我有一个方法是在doGet(HttpServletRequest request, HttpServletResponse response)
调用时正确创建一个包含大量数据的CSV文件,当我创建一个这样的按钮时调用该文件:
link = new HtmlOutputLink();
HtmlGraphicImage img = new HtmlGraphicImage();
img.setStyle("background-color: #FFFFFF;");
img.setTitle("Click to Export these requests to csv file");
img.setValue("../images/Export.PNG");
link.getChildren().add(img);
link.setValue(resp.encodeURL(Constants.TXT_ALL_DIV_TEAM_EXPORT_LINK));
cell = new DataTableCell();
cell.setType(CellType.DATA);
cell.setFormat(new Format(Format.CENTER));
cell.addElement(link);
headerRow.addElement(cell);
当单击该按钮时,doGet方法然后调用创建CSV文件的方法(再次,从doGet调用正确的方法)。
但是,我必须将其从图像更改为CommandButton,命令按钮是一个扩展javax.faces.component.html.HtmlCommandButton包的自定义类,所以现在我有了这个:
HtmlOutputLink link = new HtmlOutputLink();
CommandButton alertsButton = new CommandButton();
alertsButton.setId(UI_EXPORT_ID);
alertsButton.setValue(UI_EXPORT_TXT);
alertsButton.setOnclick("javascript:showWaitLayer();jsCBDupdateComponent('" + "form" + "', this );");
alertsButton.setBlockSubmit(true);
alertsButton.setImmediate(true);
alertsButton.addActionListener(this);
link.getChildren().add(alertsButton);
cell = new DataTableCell();
cell.setType(CellType.DATA);
cell.setFormat(new Format(Format.CENTER));
cell.addElement(link);
headerRow.addElement(cell);
当单击此按钮时,它调用processAction(),其中我实例化用于传入工作方法的HttpServletResponse。
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
response.setContentType("application/octet-stream");
HomeController homeController = (HomeController) context.getApplication().createValueBinding("#{HomeController}").getValue(context);
homeController.createExportFile(response);
编辑:添加createExportFile方法,其中包含大量可读性。
EDIT2:我已经更改了createExportFile,因此不需要传入HttpServletResponse。这样,该方法对传入的参数没有任何依赖性。两个按钮(带有img的按钮和一个带有CommandButton的按钮)调用此方法并在完全相同的方法中无错误地运行。只有img按钮可以创建excel文件。
public void createExportFile()
throws IOException, PersistenceException, SQLException {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse resp = (HttpServletResponse) context.getExternalContext().getResponse();
resp.setContentType("application/octet-stream");
resp.setContentLength(500 * this.getWorkAllDivDeptList().size());
resp.setHeader("Content-Disposition", "attachment; filename=\""
+ "AllDivTeam.csv" + "\""); Map<String, HashSet<String>> stateDateMap = new HashMap<String, HashSet<String>>();
ArrayList<DynamicFieldInfo> txtFieldAllList = new ArrayList<DynamicFieldInfo>();
RequestReader kanbanReader;
try {
//Get all of the data from the DB
} catch (MidTierException mte) {
mte.printStackTrace();
}
String rowTxt = getExportRowHdrTxt(txtFieldAllList, addlColCnt);
response.getOutputStream().write(rowTxt.getBytes(), 0, rowTxt.length());
kanbanReader = new RequestReader("");
for (AllActiveWorkListInfo bwi : (ArrayList<AllActiveWorkListInfo>) this
.getFilteredAllDivDeptList()) {
HashSet<String> set = (HashSet<String>) stateDateMap.get(bwi.getMID());
if (null != set && !set.isEmpty()) {
Iterator<String> itr = set.iterator();
while (itr.hasNext()) {
rowTxt = getExportRowTxt(bwi, txtFieldAllList,
kanbanReader, (String) itr.next());
response.getOutputStream().write(rowTxt.getBytes(), 0,
rowTxt.length());
}
} else {
rowTxt = getExportRowTxt(bwi, txtFieldAllList, kanbanReader, "");
response.getOutputStream().write(rowTxt.getBytes(), 0,
rowTxt.length());
}
if (count++ == 200) {
response.getOutputStream().flush();
}
}
response.getOutputStream().flush();
response.getOutputStream().close();
}
添加标题:
(Request-Line) POST /kanban/faces/kanbanRepAllDivDeptTickets HTTP/1.1
Accept */*
Accept-Encoding gzip, deflate
Accept-Language en-us
Cache-Control no-cache
Connection Keep-Alive
Content-Length 530
Content-Type application/x-www-form-urlencoded
Cookie _cbdModemCheck=false; JSESSIONID=08ADA3D60982F9D13478AF729D6E5205; s_fid=24245A567AE4BB33-0F8E3B5CF3FBEED7
Host localhost:8080
Referer http://localhost:8080/kanban/faces/kanbanRepAllDivDeptTickets
User-Agent Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3)
当我进行调试时,它会完成所有创建csv的过程,就像从doGet调用时一样,但它永远不会打开下载或取消的对话框。它没有任何例外,我完全没有想法。
有谁看到我做出错误假设的地方?
谢谢你的时间, 麦克
答案 0 :(得分:0)
您无法将文件写入输出流。您应该将文件写入输出流。 这是为我工作的示例代码。希望它可以帮到你。
int BUFSIZE = 4096;
int length = 0;
ServletOutputStream outStream = response.getOutputStream();
String mimeType = "text/csv";
response.setContentType(mimeType);
response.setContentLength((int)document.length());
String documentName = document.getName();
response.setHeader("Content-Disposition", "attachment; filename=\"" + yourCsvFileName + "\"");
byte[] byteBuffer = new byte[BUFSIZE];
DataInputStream in = new DataInputStream(new FileInputStream(document));
while((null != in) && ((length = in.read(byteBuffer)) != -1)) {
outStream.write(byteBuffer, 0, length);
}
in.close();
outStream.close();