Spring Конфигурация Java для распознавателя вида excel

У меня есть веб-приложение spring java config, использующее (jsp) view resolver. Теперь я хочу показать лист excel с некоторыми данными, когда пользователь нажимает на значок excel в приложении. По всему интернету я нашел только xml-конфигурацию spring для просмотра 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. Я уверен, что viewversion превращает его в jsp view. Может кто-нибудь указать, как я могу это исправить.

ИЗМЕНИТЬ

Я видел эту эквивалентную конфигурацию xml онлайн. Не уверен, как сделать это java config:

<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**);
}

Я не знаю, что положить в место. Я не могу дать строку. У меня нет view.xml, поскольку я использую java configs

Изменить (вот мой код после внесения изменений, как вы сказали)

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

EDIT:

Заголовок ответа:

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

Ответ 1

Вы можете вернуть ModelAndView из своего метода контроллера, установив View в экземпляр AbstractExcelView. Тогда вам не нужно вообще связываться с вашим XML.

Изменить: добавьте дополнительную информацию: Я много раз выполнял пользовательский подход "Просмотр" для обработки 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();
    }       
}

Далее вам нужно изменить метод контроллера

@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-контекст, изменять, как ваши beans соединяются вместе, создавать какие-либо службы или что-то еще. Просто создайте экземпляр своего пользовательского представления, передайте все, что вам нужно, чтобы создать таблицу, а затем установите представление в 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 );
                          }
        }); 
   }