3

I need to export the Excel sheet, so calling action class method through Ajax call from dialog window. I have Excel icon, when I click the icon calling method and processing the backend data, and finally going to execute the below code and return the result to download the Excel sheet.

jQuery Ajax calling:

function callajax() {
     jQuery.ajax({
     url : '<s:url action="part" method="export"/>',

Result method:

@Result(name="success",type=StreamResult.class,value="",params={"inputName","inputStream"})

Java code:

    public String method {
    -----------------
    method to call backend...
    --------------------------
    httpServletResponse.setContentType("application/vnd.ms-excel");
    String filename = filters.getPeriod() + "_" +filters.getRegion() ;
    httpServletResponse.setHeader("Content-disposition",
    "attachment; filename="+filename+".xls");
    ServletOutputStream outputStream = httpServletResponse.getOutputStream();
    builder.build(method1, method2, outputStream);
    outputStream.flush();
    return SUCCESS; }

In the build method has creating workbook

    WorkbookSettings workbookSettings = new WorkbookSettings();
    workbookSettings.setLocale(new Locale("en", "EN"));
    WritableWorkbook workbook =
    Workbook.createWorkbook(outputStream, workbookSettings);

and setting the all the values in sheet. Please advise.

Trying as your advise :

I'm using code behind , so result type on class name :

@Result(name="success",type=StreamResult.class,value="",params = {"contentType","application/octet-stream","inputName","inputStream","bufferSize","1024","contentDisposition","attachment;filename=\"${filename}\""})


public String method {
    -----------------
    method to call backend...
    --------------------------
String filename =   filters.getRegion() + "_" +
                filters.getCurrency();
File file = new File(filename);
inputStream = new FileInputStream(file); //getting error "java.io.FileNotFoundException:file "
builder.buildXL(OBJ1, OBJ2, file);
return SUCCESS;
}

buildxl(obj1,obj2,File file)
{
WorkbookSettings workbookSettings = new WorkbookSettings();
    workbookSettings.setLocale(new Locale("en", "EN"));
    WritableWorkbook workbook =
    Workbook.createWorkbook(file, workbookSettings);

-----
------
workbook.write(); 
workbook.close();
}

Params values :

params = 
{"contentType","application/octet-stream",
"inputName","inputStream",
"bufferSize","1024",
"contentDisposition","attachment;filename=\"${filename}\""})

Log :

2013-07-18 10:25:33,453 ERROR         org.apache.struts2.dispatcher.StreamResult - Can not find a java.io.InputStream with the name [] in the invocation stack. Check the <param name="inputName"> tag specified for this action.
2013-07-18 10:25:33,453 ERROR       org.apache.struts2.rest.RestActionInvocation - Exception processing the result.
java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [] in the invocation stack. Check the <param name="inputName"> tag specified for this action.
    at org.apache.struts2.dispatcher.StreamResult.doExecute(StreamResult.java:237)
    at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
    at org.apache.struts2.rest.RestActionInvocation.executeResult(RestActionInvocation.java:241)
    at org.apache.struts2.rest.RestActionInvocation.processResult(RestActionInvocation.java:198)
    at org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:146)
    at com.opensymphony.xwork2.DefaultActionProxy.execute(DefaultActionProxy.java:147)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:510)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)
    at org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:102)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3288)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3254)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
    at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2163)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2089)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2074)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1513)
    at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
2013-07-18 10:25:33,499 DEBUG       org.apache.struts2.rest.RestActionInvocation - No result returned for action at null

ClasspathPackageProvider:

org.apache.struts2.config.ClasspathPackageProvider - Adding parmeter[contentType:application/octet-stream] to result.
org.apache.struts2.config.ClasspathPackageProvider - Adding parmeter[inputName:inputStream] to result.
org.apache.struts2.config.ClasspathPackageProvider - Adding parmeter[bufferSize:1024] to result.
org.apache.struts2.config.ClasspathPackageProvider - Adding parmeter[contentDisposition:attachment;filename="${filename}"] to result.
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
user2444474
  • 623
  • 8
  • 21
  • 40
  • 1
    You'll need to be a bit more specific. It's also not clear what you're trying to do in that method. And, Codebehind is deprecated. – Dave Newton Jul 15 '13 at 18:16

1 Answers1

2

Return result as a binary stream

private InputStream inputStream;
private String filename; 

//getters here
public InputStream getInputStream() {
    return inputStream;
}

public String getFilename() {
  return filename;
}

@Result(name="success", type=StreamResult.class, value="inputStream", params={"contentType","application/octet-stream", "contentDisposition", "attachment;filename=\"${filename}\"", "inputName", "inputStream"})

String filename = filters.getPeriod() + "_" +filters.getRegion() ;
File file = new File(filename);
inputStream = new FileInputStream(file);
return SUCCESS;
Roman C
  • 49,761
  • 33
  • 66
  • 176
  • +${filename}+ "\"", - syntax error.$ is work here ? and i have to remove the all the headers and putting into params. – user2444474 Jul 16 '13 at 11:17
  • Please look into question section , i have updated.Because i'm sending outputstream to build method to create excel sheet all the properties.As we output stream servle response setting from setcontext type.Is there any way to keep these setting in code itself ? Otherwise core flow need to change. – user2444474 Jul 16 '13 at 11:28
  • You don't have to set content type (it's set by the result), and other code you should replace with the code from this answer. – Roman C Jul 16 '13 at 11:51
  • which one(file or inputstream) i suppose to pass to workbook ? Workbook.createWorkbook(outputStream, workbookSettings); – user2444474 Jul 17 '13 at 17:00
  • If the method takes an `OutputStream` then you pass the `FileOutputStream`. – Roman C Jul 17 '13 at 17:04
  • sorry I got confused...File file = new File(filename); inputStream = new FileInputStream(file); and Workbook.createWorkbook(file, workbookSettings); – user2444474 Jul 17 '13 at 17:22
  • You should create file first, then take an input stream of it, don't forget to call `write` and `close` on workbook returned by the `createWorkbook`. – Roman C Jul 17 '13 at 17:37
  • inputStream = new FileInputStream(file); - getting an error java.io.FileNotFoundException:...as updated in question section for reference. – user2444474 Jul 17 '13 at 17:52
  • I meant a file is created after build. – Roman C Jul 17 '13 at 17:54
  • builder method is working good , when return result type, its throwing error as "Error :org.apache.struts2.dispatcher.StreamResult - Can not find a java.io.InputStream with the name [] in the invocation stack. Check the tag specified for this action.java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [] in the invocation stack. Check the tag specified for this action.". Can you please advise. – user2444474 Jul 18 '13 at 07:58
  • The parameter `inputName` is specified in the `@Result` annotation. And this annotation has `params` property that should set parameters to the result. May be it doesn't support dynamic parameters, try to replace `${filename}` with the actual value, and don't forget that annotations are set on the class, not method in codebehind plugin. Why not to just switch to convention plugin and rid yourself of past mistakes? – Roman C Jul 18 '13 at 11:52
  • inputName : inputStream values not taking here . params = {"contentType","application/octet-stream","inputName","inputStream","bufferSize","1024","contentDisposition","attachment;filename=\"${filename}\""} – user2444474 Jul 18 '13 at 12:09
  • Parameters aren't set to the result config, it would be messiah, enable debug for `ClasspathPackageProvider` and post the output. – Roman C Jul 18 '13 at 14:22
  • Please advise how to enable debug ClasspathPackageProvider ? – user2444474 Jul 18 '13 at 16:39
  • Set the log level to debug, if you are using log4j then put `log4j.logger.org.apache.struts2.config=DEBUG` – Roman C Jul 18 '13 at 16:47
  • Have updated the classpathpackageprovider in question section. – user2444474 Jul 19 '13 at 11:00
  • Didn't you see that `inputName` parameter value should be printed in the error message but you say it was [], either you have a method in the action `getInputName` or you have such parameters in the value stack, you should check that both. – Roman C Jul 19 '13 at 11:14
  • What do you want to suppose, I don't like to suppose or guess something, I need the full action code to make decision about late apologizes. And it couldn't be solved until you debug the `StreamResult` and tell me why the value for the `inputName` is empty. You can remove the parameters `inputName`, `bufferSize` with their values from the `@Result` as they have the same default values as used in my code. – Roman C Jul 19 '13 at 11:47
  • Because in your code value="" , but value must be inputStream, so that java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [stream] in the invocation stack. – user2444474 Jul 19 '13 at 12:09
  • Hmm... Where in my code did you see it? The value `stream` I didn't use in this answer (used `inputStream`, and as I said it could be removed because this value is used by default), may be you got it from another one? – Roman C Jul 19 '13 at 12:15
  • Ouch, the `value` attribute, did you see if it affect the setting of parameters to the result? It would be strange if it's related only to the one parameter. And also keep in mind that parameters are set to the map by key-value pairs encountered by the `params` attribute. – Roman C Jul 19 '13 at 12:23
  • yes , which i mention in above comment that value attribute only. params key/value are good, but if set the value attribute , then name[stream] getting the value.@Result(name="success",type=StreamResult.class,value="stream",params = {"contentType","application/octet-stream","inputName","inputStream","contentDisposition","attachment;filename=\"${filename}\""}) – user2444474 Jul 19 '13 at 12:32
  • After set the value attribute i got error as "Can not find a java.io.InputStream with the name [stream] in the invocation stack. Check the tag specified for this action." – user2444474 Jul 19 '13 at 12:33
  • What do you mean it didn't work, is the result executed? If it did then it worked. – Roman C Jul 19 '13 at 12:57
  • Yes, the `value` overrides the `inputName` of stream result in codebehind plugin. – Roman C Jul 19 '13 at 13:18
  • This also good idea :), but now Can not find a java.io.InputStream with the name [inputStream] in the invocation stack.I have getter method for inputStream, then why getting this error. – user2444474 Jul 19 '13 at 13:39
  • Any other Possibilities ? – user2444474 Jul 19 '13 at 15:06
  • What other possibilities do you want? – Roman C Jul 28 '13 at 10:38