JAVA:将数据(从数据库)导出到excel并将其发送到客户端
正如标题所示,我需要将一些数据(从数据库中获取)放入 Excel 工作表中,然后将其发送到客户端,以便用户可以保存、打开或取消操作。
我看过一些与此相关的文章,最接近的一篇是: 如何让用户下载我的文件? (Java、MVC、Excel、POI)。参考史蒂文斯提供的链接,我尝试了以下代码:
public String execute(){
setContentDisposition("attachment; filename=\"" + ename + "\"");
try{
ServletContext servletContext = ServletActionContext.getServletContext();
String filePath = servletContext.getRealPath("/WEB-INF/template/excel/mytemplate.xls");
File file = new File(filePath);
Workbook wb = WorkbookFactory.create(new FileInputStream(file));
Sheet sheet = wb.getSheetAt(0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
wb.write(baos);
InputStream excelStream;
excelStream = new ByteArrayInputStream(baos.toByteArray());
}catch(Exception e){
System.out.println(e.getMessage());
}
return SUCCESS;
}
这里首先未定义 WorkbookFactory
。其次,我无法正确理解代码是如何工作的。
我还找到了这个链接:http://www.roseindia.net/answers/viewqa/Java-Beginners/14930-How-to-export-data-from-database-to-excel-sheet-by-using-java--in-独立项目.html。但这里的 excel 文件被保存在服务器上。我希望文件不应该保存在服务器端,它应该直接转到客户端
(如果有帮助的话)我正在使用:struts 2框架,hibernate
我愿意使用其他东西,如POI API,jQuery或任何其他好东西。
由于某种原因我无法使用 displayTag
。
Javascript 将是我的最后手段(尽管我已经用它实现了),因为它需要更改浏览器的一些默认安全设置(如果可以避免这种情况,我也对 javascript 持开放态度)。
请告知我现在应该如何处理这个问题。
谢谢!!
编辑:
<result-types>
<result-type name="jsp" class="org.apache.struts2.views.jsp"/>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
</result-types>
<action name="myActionName" class="package.myActionClass">
<result type="stream">
<param name="contentType">"application/vnd.ms-excel"</param>
<param name="inputName">excelStream</param>
<param name="contentDisposition">contentDisposition</param>
<param name="bufferSize">1024</param>
</result>
</action>
执行操作时出错:
java.lang.reflect.InvocationTargetException
java.lang.IncompatibleClassChangeError: Class org.apache.poi.hssf.usermodel.HSSFWorkbook does not implement the requested interface org.apache.poi.ss.usermodel.Workbook
As the title suggest, I need to put some data (which I have got from database) into an excel sheet, and then send it to client side so that user can save , open or cancel the action.
I have seen some articles regarding this, the closest one being : How can I get the user to download my file? (Java, MVC, Excel, POI). Referring to links provided by Stevens I tried out the following code :
public String execute(){
setContentDisposition("attachment; filename=\"" + ename + "\"");
try{
ServletContext servletContext = ServletActionContext.getServletContext();
String filePath = servletContext.getRealPath("/WEB-INF/template/excel/mytemplate.xls");
File file = new File(filePath);
Workbook wb = WorkbookFactory.create(new FileInputStream(file));
Sheet sheet = wb.getSheetAt(0);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
wb.write(baos);
InputStream excelStream;
excelStream = new ByteArrayInputStream(baos.toByteArray());
}catch(Exception e){
System.out.println(e.getMessage());
}
return SUCCESS;
}
Here firstly WorkbookFactory
is not defined. Secondly, I could not understand properly how the code is working.
I also found this link : http://www.roseindia.net/answers/viewqa/Java-Beginners/14930-How-to-export-data-from-database-to-excel-sheet-by-using-java--in-standalone-project.html. But here the excel file gets saved on the server. I want that the file should not be saved on the server side, it should directly go to client side
(If it helps) I am using : struts 2 framework, hibernate
I am open to using other things like POI API, jQuery or any other good stuff.
I can not use displayTag
for some reason.
Javascript would be my last resort (although I have implemented with it) because it requires changing some default security settings of the browser (If this can be avoided I am open to javascript as well).
Please advise how should I go about this now.
Thanks!!
EDIT :
<result-types>
<result-type name="jsp" class="org.apache.struts2.views.jsp"/>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
</result-types>
<action name="myActionName" class="package.myActionClass">
<result type="stream">
<param name="contentType">"application/vnd.ms-excel"</param>
<param name="inputName">excelStream</param>
<param name="contentDisposition">contentDisposition</param>
<param name="bufferSize">1024</param>
</result>
</action>
The error while executing action:
java.lang.reflect.InvocationTargetException
java.lang.IncompatibleClassChangeError: Class org.apache.poi.hssf.usermodel.HSSFWorkbook does not implement the requested interface org.apache.poi.ss.usermodel.Workbook
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的。所以最后我克服了所有的障碍,并找到了一种方法来做到这一点。
我意识到我面临的问题不是创建 Excel 文件,问题是将其发送到客户端,而且也没有在服务器上创建文件或临时文件。
因此,这是如何进行的(我已经从原始代码中删除了详细信息,以便您可以轻松理解它)。
在操作文件中,您首先必须创建一个 HSSFWorkbook 对象,将数据放入其中,然后不将其保存到服务器上的磁盘,而是使用输入流将其发送到客户端。
操作文件代码:
现在在 struts-config 文件中写入(请注意,excelStream 和 contentDisposition 已在操作本身中设置,这里的结果类型也是 org.apache.struts2.dispatcher.StreamResult ):
就是这样。现在,当执行该操作时,系统将提示用户保存或打开文件。
:)
Okay. So finally I am through with all the roadblocks and have figured out a way to do this.
I realized that the problem I was facing was not in creating the excel file, the problem was sending it to client side, and that too without creating a file or temporary file on the server.
So here is how to go about it (I have ripped off details from my original code so that you can easily understand it).
In the action file you first have to create a HSSFWorkbook object, put data on it and then without saving it to disk on server, send it to client using inputstream.
Action File code :
Now in the struts-config file just write (note that excelStream & contentDisposition has been set in the action itself also the result-type here is
org.apache.struts2.dispatcher.StreamResult
):Thats it. Now when the action is executed, the user will be prompted to save or open the file.
:)
您的类路径上有两份不同的 POI 副本,一份是旧的,一份是新的。这就是为什么您会收到异常 java.lang.IncompleteClassChangeError: Class org.apache.poi.hssf.usermodel.HSSFWorkbook does not Implement the requested interface org.apache.poi.ss.usermodel.Workbook - 您已经针对新副本进行了编译,但在运行时它发现了一些新的和一些旧的罐子。
POI 常见问题解答对此进行了介绍。理想情况下,您应该能够查看设置中的所有 jar,并删除旧的 POI。如果没有,POI 常见问题解答条目有一些示例代码,您可以使用它们来获取JVM 打印出它从何处加载 POI 类。这将显示 jar 文件名,您可以删除旧的文件。
You have two different copies of POI on your classpath, one old and one new. That's why you're getting the exception java.lang.IncompatibleClassChangeError: Class org.apache.poi.hssf.usermodel.HSSFWorkbook does not implement the requested interface org.apache.poi.ss.usermodel.Workbook - you've compiled against the new copy, but at runtime it's finding some new and some old jars.
This is covered in the POI FAQ. Ideally you should just be able to look at all the jars in your setup, and zap the old POI one. If not, the POI FAQ entry has some sample code you can use to get the JVM to print out where it has loaded POI classes from. That will show you the jar file name, and you can remove the old one.