我有一个带有(jsp)视图解析器的基于Spring java配置的Web应用程序。 现在,我想在用户点击app中的excel图标时显示包含一些数据的Excel表格。 在互联网上我只找到了基于xml的弹簧配置,用于我不熟悉的excel视图。 我在一定程度上解码了,并且非常接近完成我的任务。以下是我得到的。
我在下面的链接中有类似的控制器和主页:
http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch17s06.html
控制代码:
@Controller
public class ExcelController extends AbstractController {
@Override
@RequestMapping(value = "/Excel", method = RequestMethod.POST)
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
BufferedReader in = null;
try {
URL oracle = new URL("example.com");
URLConnection yc =null;
yc = oracle.openConnection();
in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
}
catch(Exception e){
System.err.println(e);
}
Map map = new HashMap();
map.put("input", in);
return new ModelAndView("xl", map);
}
}
查看代码:
public class ExcelReportView extends AbstractExcelView{
@Override
protected void buildExcelDocument(Map model, HSSFWorkbook workbook,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
HSSFSheet sheet;
HSSFRow row;
HSSFCell cell;
try {
BufferedReader in = (BufferedReader) model.get("input");
sheet=workbook.createSheet("spring");
String inputLine;
int rowNum =0;
while ((inputLine = in.readLine()) != null) {
row = sheet.createRow(rowNum++);
String[] coloumns = inputLine.split("\t");
int cellNum =0;
for(String coloumn: coloumns){
cell = row.createCell(cellNum++);
cell.setCellValue(coloumn);
}
System.out.println(inputLine);
}
in.close();
System.out.println("Excel written successfully..");
} catch (IOException e) {
e.printStackTrace();
}
} }
view.properties
xl.class=package.ExcelReportView
WebAppConfig.java
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "package")
public class WebAppContextConfig extends WebMvcConfigurerAdapter {
// Resolve logical view names to .jsp resources in /WEB-INF/views directory
@Bean
public InternalResourceViewResolver configureInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/scripts/**").addResourceLocations(
"/scripts/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/img/**").addResourceLocations("/img/");
}
}
前端代码:
function AjaxCallForExcel(){
$.ajax({
type: 'POST',
url: location.href + '/Excel',
data: ({name:name })
});
}
以下是我在日志中看到的内容:
DispatcherServlet with name 'appServlet' processing POST request for [/App/Excel]
Looking up handler method for path /App/Excel
Returning handler method [protected org.springframework.web.servlet.ModelAndView package.ExcelController.handleRequestInternal(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception]
Returning cached instance of singleton bean 'excelController'
Invoking afterPropertiesSet() on bean with name 'xl'
Rendering view [org.springframework.web.servlet.view.JstlView: name 'xl'; URL [**/WEB-INF/jsp/xl.jsp**]] in DispatcherServlet with name 'appServlet'
Added model object 'org.springframework.validation.BindingResult.input' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'xl'
Added model object 'input' of type [java.io.BufferedReader] to request in view with name 'xl'
Forwarding to resource [/WEB-INF/jsp/xl.jsp] in InternalResourceView 'xl'
Successfully completed request
我不知道如何避免它将其转发到xl.jsp。我确信视图解析器正在进入jsp视图。有人能指出我该如何解决它。
修改
我在网上看到了这个xml等效配置。不知道如何使它成为java配置:
<bean id="excelViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="order" value="1"/>
<property name="location" value="/WEB-INF/views.xml"/>
</bean>
我尝试按以下方式转换它:
@Bean
public XmlViewResolver configureXmlViewResolver(){
XmlViewResolver resolver = new XmlViewResolver();
resolver.setOrder(1);
resolver.setLocation(**WHAT SHOULD BE HERE**);
}
我不知道该把位置放在哪里。我不能给字符串。我没有views.xml,因为我使用java配置
修改(按照您的说法进行更改后,这是我的代码)
public class ExcelReportView extends AbstractExcelView{
BufferedReader in;
ExcelReportView(BufferedReader in){
this.in = in;
}
@Override
protected void buildExcelDocument(Map model, HSSFWorkbook workbook,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
HSSFSheet sheet;
HSSFRow row;
HSSFCell cell;
response.setHeader("Content-Type", "application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=MyExcelSpreadsheet.xls");
try {
//BufferedReader in = (BufferedReader) model.get("input");
sheet=workbook.createSheet("spring");
String inputLine;
int rowNum =0;
while ((inputLine = in.readLine()) != null) {
row = sheet.createRow(rowNum++);
String[] coloumns = inputLine.split("\t");
int cellNum =0;
for(String coloumn: coloumns){
cell = row.createCell(cellNum++);
cell.setCellValue(coloumn);
}
System.out.println(inputLine);
}
in.close();
System.out.println("Excel written successfully..");
} catch (IOException e) {
e.printStackTrace();
}
OutputStream outStream = null;
try {
outStream = response.getOutputStream();
workbook.write(outStream);
outStream.flush();
} finally {
outStream.close();
}
}
}
控制器代码:
@Controller
public class ExcelController {
@RequestMapping(value = "/Excel", method = RequestMethod.POST)
protected ModelAndView generateCSV(HttpServletRequest request,
HttpServletResponse response) throws Exception {
BufferedReader in = null;
try {
URL oracle = new URL("http://service.com");
URLConnection yc =null;
yc = oracle.openConnection();
in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
}
catch(Exception e){
System.err.println(e);
}
ModelAndView mav = new ModelAndView();
mav.setView(new ExcelReportView( in));
return mav;
}
}
日志输出:
DispatcherServlet with name 'appServlet' processing POST request for [/App/Excel]
Looking up handler method for path /App/Excel
Returning handler method [protected org.springframework.web.servlet.ModelAndView com.package.ExcelController.generateCSV(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception]
Returning cached instance of singleton bean 'excelController'
Rendering view [com.package.controllers.ExcelReportView: unnamed] in DispatcherServlet with name 'appServlet'
Created Excel Workbook from scratch
Title Id required
Excel written successfully..
Successfully completed request
修改
响应标题:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Pragma: private
Cache-Control: private, must-revalidate
Content-Disposition: attachment; filename=MyExcelSpreadsheet.xls
Content-Type: application/octet-stream;charset=ISO-8859-1
Content-Language: en-US
Transfer-Encoding: chunked
Date: Tue, 12 Mar 2013 16:36:52 GMT
答案 0 :(得分:9)
您可以从控制器方法返回ModelAndView,将View设置为AbstractExcelView的实例。然后你根本不需要弄乱你的XML。
修改:添加一些其他信息: 我已经多次完成自定义View方法来处理CSV下载。
首先,您需要创建AbstractExcelView的实例化。您可以通过覆盖buildExcelDeocument()方法来实现。您需要POI库,因为我认为这是必需的。例如:
@Override
public void buildExcelDocument(Map<String, Object> model, HSSFWorkbook workbook,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Set the headers
response.setHeader("Content-Type", "application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=MyExcelSpreadsheet.xls");
// Here is where you will want to put the code to build the Excel spreadsheet
OutputStream outStream = null;
try {
outStream = response.getOutputStream();
workbook.write(outStream);
outStream.flush();
} finally {
outStream.close();
}
}
接下来,您需要修改Controller方法
@RequestMapping(params = "actionMethod="+Constants.ACTION_METHOD_REPORT)
public ModelAndView generateCSV(
@ModelAttribute(Constants.REPORT_FORMBEAN_MODEL_ATTRIBUTE) FormBean formBean,
ModelAndView mav,
HttpServletRequest request,
HttpServletResponse response) {
mav.setView(new MyExcelView( /* modify your constructor to pass in your data so the view can build the output */ ));
return mav;
}
无需编辑上下文XML,修改bean连接在一起的方式,创建任何服务或任何内容。只需创建自定义视图的实例,传入您需要的任何内容以构建电子表格,然后在ModelAndView上设置视图。就这么简单。
编辑 - 你需要这样做......
您需要更改AJAX调用,以便判断其是否已完成或出现错误。你现在正在盲目地飞行:
function AjaxCallForExcel(){
$.ajax({
type: 'POST',
url: location.href + '/Excel',
data: ({name:name }),
complete: function(jqXHR,textStatus ) {
alert("Complete: "+textStatus );
},
error: function(jqXHR,textStatus,errorThrown ) {
alert("Status: "+textStatus+"\nerror: "+errorThrown );
}
});
}