我有一个上传excel电子表格的JSF页面。该电子表格具有一定数量的工作簿。在处理每一行之前,我想要全部计算并向用户询问类似"确认X行的处理?"
这是我的JSF代码(cancel.xhtml):
<h:form enctype="multipart/form-data" id="frmMassive">
<p:growl id="messagesUpload" showDetail="true" life="3000" />
<h:panelGrid id="panel" columns="2">
<h:outputText value="File" />
<p:fileUpload value="#{cancelView.file}" mode="simple" skinSimple="true" />
<p:spacer></p:spacer>
<p:commandButton value="Send file" ajax="false"
action="#{cancelView.preProcessMassive}" />
</h:panelGrid>
</p:panel>
</h:form>
<h:form id="frmConfirm">
<p:commandButton style="display: none" id="confirmButton"
actionListener="#{cancelView.postProcessMassive}">
<p:confirm header="Confirmation"
message="Confirm the processing of #{cancelView.lineCount} line(s)?"
icon="ui-icon-alert" />
</p:commandButton>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Yes" type="button"
styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button"
styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</h:form>
Managed Bean方法(CancelView.java):
public void preProcessMassive() {
HSSFWorkbook wb;
try {
wb = new HSSFWorkbook(this.file.getInputstream());
} catch (IOException e) {
e.printStackTrace();
return;
}
HttpSession session = Util.getSession();
session.setAttribute("cancelLineCount", sheet.getPhysicalNumberOfRows());
session.setAttribute("cancelSpreadSheet", file);
RequestContext context = RequestContext.getCurrentInstance();
context.execute("document.getElementById('frmConfirm:confirmButton').click()");
}
public int getLineCount() {
HttpSession session = Util.getSession();
if (session.getAttribute("cancelLineCount") == null) {
return 0;
} else {
return (Integer)session.getAttribute("cancelLineCount");
}
}
问题是我的JSF页面在上传电子表格之前调用方法getLineCount()
。
是否有另一种方法来计算电子表格的行并在处理之前将其返回给用户?
答案 0 :(得分:3)
你需要将你的方法分成(至少)2步 - wizzard。
在您能够确定工作表的任何内容之前,您(实际上是用户)已上传它。然而,上传并不意味着处理它,您可以将上传的文件保存在bean属性*中,直到用户决定最终处理它为止。
@ViewScoped
,@ConversationScoped
或@FlowScoped
注释可能会帮助您完成此任务,具体取决于您的需求。
*对于处理Excel文件,某些库只能用于持久文件,而不能用于内存中的对象。您也可以将它存储在临时位置。
答案 1 :(得分:0)
最后,我的解决方案基于JSF和Managed Bean之间的javascript消息传递。
JSF代码:
<h:form enctype="multipart/form-data" id="frmMassive">
<p:growl id="messagesUpload" showDetail="true" life="3000" />
<p:panel header="Massive Cancel" style="width: 640px;">
<h:panelGrid id="pnlMassiveCancel" columns="2">
<h:outputText value="File" />
<p:fileUpload value="#{cancelView.file}" mode="simple" skinSimple="true" />
<p:spacer></p:spacer>
<p:commandButton value="Send" ajax="false"
action="#{cancelView.preProcessMassive}" />
</h:panelGrid>
</p:panel>
</h:form>
<h:form id="frmConfirm">
<p:remoteCommand name="postProcessMassiveCancel"
update="messagesConfirm"
actionListener="#{cancelView.postProcessMassive}" />
<p:growl id="messagesConfirm" showDetail="true" life="3000" />
</h:form>
<h:outputScript library="js" name="cancelUtil.js" />
cancelUtil.js:
function confirmMassiveCancel(msg, postProcessFunction) {
var result = window.confirm(msg);
if (result == true) {
postProcessFunction();
}
}
Managed Bean代码:
public void preProcessMassive() {
HSSFWorkbook wb;
try {
wb = new HSSFWorkbook(this.file.getInputstream());
} catch (IOException e) {
e.printStackTrace();
return;
}
HSSFSheet sheet = wb.getSheetAt(0);
lineCount = sheet.getPhysicalNumberOfRows();
HttpSession session = Util.getSession();
RequestContext context = RequestContext.getCurrentInstance();
String script = "confirmMassiveCancel('Do you want to process "
+ String.valueOf(lineCount) + " line(s)?', postProcessMassiveCancel)";
context.execute(script);
}
不是一个优雅的解决方案,但解决了我的问题。