简体   繁体   English

如何从Spring MVC导出到Excel

[英]How to export to Excel from Spring MVC

I want to export some data which I have retrieved from the database to the controller level. 我想将我从数据库中检索到的一些数据导出到控制器级别。 From the controller I need to export this data to an Excel file without using a view. 从控制器我需要将此数据导出到Excel文件而不使用视图。

I wrote: 我写:

        ReportSearchVO searchL = formL.getObjReportSearchG();

        loggerG.info("Resource List:" + searchL.getResourceListG());

        projDetailReportL = reportServiceG.createProjectDetailReport(formL);

        formL.setProjDetailReport(projDetailReportL);
        formL.setReportTypeEnum(ReportTypeEnum.PROJECTDETAILREPORT);
        formL.setObjReportSearchG(searchL);

        requestR.setAttribute("resLevelForm", formL);
        returnModelAndView = new ModelAndView(
            ViewConstants.FINAL_VIEW_PROJECT_DETAILS_REPORT, "reportForm",
            formL);

but this uses a view. 但这使用了一个视图。

Using AbstractExcelView and ModalAndView its possible in SpringMVC. 在SpringMVC中使用AbstractExcelView和ModalAndView。 Refer below for more details 请参阅下文了解更多详情

http://learnfromexamples.com/generate-excel-in-spring-mvc-application-using-apache-poi/ http://learnfromexamples.com/generate-excel-in-spring-mvc-application-using-apache-poi/

在过去,当我需要生成Excel文档时,我使用了Apache POI来创建文件。

Apache POI is inhertly supported by spring, it provides AbstractExcelView to provide excel downloads. Apache POI得到了春天的支持,它提供了AbstractExcelView来提供excel下载。

Sample code: 示例代码:

public class ExcelBuilder extends AbstractExcelView {

    @Override
    protected void buildExcelDocument(Map<String, Object> input,
            HSSFWorkbook workbook, HttpServletRequest arg2, HttpServletResponse response)
            throws Exception {
        response.setHeader("Content-Disposition", "attachment; filename=\"sample.xls\"");
         // create a new Excel sheet        
         HSSFSheet sheet = workbook.createSheet("Test");        
         sheet.setDefaultColumnWidth(30);                 
         // create style for header cells        
         CellStyle style = workbook.createCellStyle();       
         Font font = workbook.createFont();       
         font.setFontName("Arial");        
         style.setFillForegroundColor(HSSFColor.BLUE.index);      
         style.setFillPattern(CellStyle.SOLID_FOREGROUND);       
         font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);       
         font.setColor(HSSFColor.WHITE.index);      
         style.setFont(font);         
         // create header row       
         HSSFRow header = sheet.createRow(0);                
         header.createCell(0).setCellValue("Title");       
         header.getCell(0).setCellStyle(style);             
         header.createCell(1).setCellValue("col2");     
         header.getCell(1).setCellStyle(style);             
         header.createCell(2).setCellValue("col3");       
         header.getCell(2).setCellStyle(style);              
         header.createCell(3).setCellValue("col4");   
         header.getCell(3).setCellStyle(style);                
         header.createCell(4).setCellValue("col 5");      
         header.getCell(4).setCellStyle(style);
//Your data goes here
        }
    }

If you just want the excel download without poi, is just set the content dispostion header in your jsp and from controller direct return the view that suggests the jsp. 如果你只想要没有poi的excel下载,只需在你的jsp中设置内容dispostion头,并从控制器直接返回建议jsp的视图。 Be warned that when you do like this you are just pasting the content of jsp as html in the excel (a valid file can be opened on Microsoft excel too), so no macro's or function work with that. 请注意,当你这样做时,你只是将jsp的内容粘贴为excel中的html(也可以在Microsoft Excel上打开一个有效的文件),因此没有宏或函数可以使用它。

without using a view

To not use a view, you have to make the return type of your request mapping method to void 要不使用视图,必须将请求映射方法的返回类型设置为void

@Controller
public class MyController{

  @RequestMapping("/xyz")
  public void getExcel(HttpServletRequest request, HttpServletResponse response){
     // 1. Fetch your data
     // 2. Create your excel
     // 3. write excel file to your response.
  }

}

I believe you've already done part 1. Part 2 is completely differnt thing and you have to use some third party api to do that. 我相信你已经完成了第1部分。第2部分是完全不同的东西,你必须使用一些第三方api来做到这一点。 Apache POI is very simple and effective. Apache POI非常简单有效。 https://poi.apache.org/spreadsheet/ . https://poi.apache.org/spreadsheet/ Their quickguide is nice to sart with. 他们的快速指南非常适合。

Once you have created your file, now you need to write it to response so that it can be downloaded to client end. 创建文件后,现在需要将其写入响应,以便将其下载到客户端。 Here's how you can do that. 这是你如何做到这一点。 Lets say the excel you created is xyz.xls 可以说你创建的excel是xyz.xls

    response.setContentType("application/octet-stream");    // set content attributes for the response

    FileInputStream inputStream = new FileInputStream(new File("xyz.xls"));

    OutputStream outputStream = response.getOutputStream();             // get output stream of the response

    byte[] buffer = new byte[1024];
    int bytesRead = -1;
    while ((bytesRead = inputStream.read(buffer)) != -1) {  // write bytes read from the input stream into the output stream
        outputStream.write(buffer, 0, bytesRead);
    }

    outputStream.flush();

it's work 这是工作

In your controller 在你的控制器中

@RequestMapping(value = "/downloadExcel", method = RequestMethod.GET)
public ModelAndView downloadExcel(Model model) {

    List<String> usersGateways = uDAO.GetGwRoleUser();

    List<User> users = gatewayManagedDAO.findAll();
    return new ModelAndView(new ExcelView(), "users ", users );
    }
}

In your ExcelView 在ExcelView中

public class ExcelView extends AbstractXlsView{

@Override
public void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    // TODO Auto-generated method stub


    // change the file name
    response.setHeader("Content-Disposition", "attachment; filename=\"my-exported-file.xls\"");

    @SuppressWarnings("unchecked")
    List<User> users= (List<GatewayManage>) model.get("users");

    // create excel xls sheet
    Sheet sheet = workbook.createSheet("Users Detail");
    sheet.setDefaultColumnWidth(30);

    // create style for header cells
    CellStyle style = workbook.createCellStyle();
    Font font = workbook.createFont();
    font.setFontName("Arial");
    style.setFillForegroundColor(HSSFColor.BLUE.index);
    //style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    //font.setBold(true);
    font.setColor(HSSFColor.BLACK.index);
    style.setFont(font);


    // create header row
    Row header = sheet.createRow(0);
    header.createCell(0).setCellValue("First Name");
    header.getCell(0).setCellStyle(style);
    header.createCell(1).setCellValue("Last Name");
    header.getCell(1).setCellStyle(style);
    header.createCell(2).setCellValue("Number");
    header.getCell(2).setCellStyle(style);
    header.createCell(3).setCellValue("Age");
    header.getCell(3).setCellStyle(style);



    int rowCount = 1;
    for(User user : users){
        Row userRow =  sheet.createRow(rowCount++);
        gatewayRow.createCell(0).setCellValue(user.getFirstName());
        gatewayRow.createCell(1).setCellValue(gateway.getLastName());
        gatewayRow.createCell(2).setCellValue(gateway.getNumber());
        gatewayRow.createCell(3).setCellValue(gateway.getAge());

        }

}
}

You can replace my User class by yours (Studen, aBook ....) and it's work! 你可以用你的(Studen,aBook ....)替换我的用户类,这样就可以了!

Prepare your Excel sheet like this (using apache poi). 这样准备Excel表格(使用apache poi)。 And then (for example) in your Controller you can easily write it to the body : 然后(例如)在您的控制器中,您可以轻松地将其写入正文:

@GetMapping(value = "/alluserreportExcel")
public ResponseEntity<InputStreamResource> excelCustomersReport() throws IOException {
    List<AppUser> users = (List<AppUser>) userService.findAllUsers();
    ByteArrayInputStream in = GenerateExcelReport.usersToExcel(users);
    // return IO ByteArray(in);
    HttpHeaders headers = new HttpHeaders();
    // set filename in header
    headers.add("Content-Disposition", "attachment; filename=users.xlsx");
    return ResponseEntity.ok().headers(headers).body(new InputStreamResource(in));
}

The full blown example is here . 完整的例子在这里

A complete example for serving XLSX generated in memory: 提供在内存中生成的XLSX完整示例:

package io.github.baijifeilong.excel;

import lombok.SneakyThrows;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

/**
 * Created by BaiJiFeiLong@gmail.com at 2019-08-20 16:36
 */
@SpringBootApplication
@RestController
public class ExcelApp {

    public static void main(String[] args) {
        SpringApplication.run(ExcelApp.class, args);
    }

    @SneakyThrows
    @GetMapping(value = "/")
    public void index(HttpServletResponse response) {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet();
        XSSFRow row = sheet.createRow(0);
        row.createCell(0).setCellValue("OK");
        response.addHeader("Content-Disposition", "attachment; filename=world.xlsx");
        workbook.write(response.getOutputStream());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM