SpringMvc實現匯出Excel檢視
阿新 • • 發佈:2018-12-11
SpringMvc提供了AbstractXlsView提供Excel檢視,它是一個抽象類,提供了一個抽象方法-buildExcelDocument要去實現,其它方法,AbstractXlsView其它方法已經實現了
buildExcelDocuent主要任務是去建立一個workbook,它要用到POI的API
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.15</version> </dependency>
然後我們開始實現這個檢視,這個檢視不是一個邏輯檢視,所以無需檢視解析器也可以實現它,程式碼如下
package com.example.eurekaclient.excel; import org.apache.commons.lang.StringUtils; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.web.servlet.view.document.AbstractXlsView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; /** * @ClassName ExcelView * @Description TODO * @Author Mr.G * @Date 2018/9/20 18:19 * @Version 1.0 */ public class ExcelView extends AbstractXlsView { private String fileName=null; private ExcelExportService excelExportService=null; public ExcelView(ExcelExportService excelExportService){ this.excelExportService=excelExportService; } public ExcelView(String fileName,ExcelExportService excelExportService){ this.fileName=fileName; this.excelExportService=excelExportService; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public ExcelExportService getExcelExportService() { return excelExportService; } public void setExcelExportService(ExcelExportService excelExportService) { this.excelExportService = excelExportService; } /** * Application-provided subclasses must implement this method to populate * the Excel workbook document, given the model. * * @param model the model Map * @param workbook the Excel workbook to populate * @param request in case we need locale etc. Shouldn't look at attributes. * @param response in case we need to set cookies. Shouldn't write to it. */ @Override protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { if(excelExportService==null){ throw new RuntimeException("匯出介面不能為空"); } if(!StringUtils.isEmpty(fileName)){ String reqCharset=request.getCharacterEncoding(); reqCharset=reqCharset==null?"UTF-8":reqCharset; fileName=new String(fileName.getBytes(reqCharset),"ISO8859-1"); response.setHeader("Content-disposition","attachment;fileName="+fileName); } excelExportService.makeWorkBook(model,workbook); } }
fileName是下載檔案的名字,excelExportService是建立Workbook的規則,因為我們會根據不同需求建立不同形式的excel表格,所以我們把這個介面抽象出來當作公用介面,有不同需求的話,就用不同的方式去實現
寫出這個介面
package com.example.eurekaclient.excel; import org.apache.poi.ss.usermodel.Workbook; import java.util.Map; /** * @ClassName ExcelExportService * @Description TODO * @Author Mr.G * @Date 2018/9/11 22:23 * @Version 1.0 */ public interface ExcelExportService { public void makeWorkBook(Map<String,Object> model, Workbook workbook); }
然後去寫這個介面的實現
package com.example.eurekaclient.excel;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import com.example.eurekaclient.swagger2.entity.User;
import com.example.eurekaclient.swagger2.server.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.Map;
/**
* @ClassName ExcelController
* @Description TODO
* @Author Mr.G
* @Date 2018/9/21 10:16
* @Version 1.0
*/
@RestController
@RequestMapping("excel")
public class ExcelController {
@Autowired
private UserService userService;
@RequestMapping(value="export",method=RequestMethod.GET)
public ModelAndView export(){
ModelAndView mv=new ModelAndView();
ExcelView ev=new ExcelView(exportService());
ev.setFileName("所有角色.xlsx");
List<User> userList =userService.selectAll();
mv.addObject("userList",userList);
mv.setView(ev);
return mv;
}
@SuppressWarnings({ "unchecked"})
private ExcelExportService exportService(){
return (Map<String,Object> model,Workbook workbook)->{
List<User> userList=(List<User>)model.get("userList");
Sheet sheet=workbook.createSheet("所有角色");
Row title= sheet.createRow(0);
title.createCell(0).setCellValue("姓名");
title.createCell(1).setCellValue("年紀");
for(int i=0;i<userList.size();i++){
User user=userList.get(i);
Row row=sheet.createRow(i+1);
row.createCell(0).setCellValue(user.getName());
row.createCell(1).setCellValue(user.getAge());
}
};
}
}
我們這裡用了lambda表示式,去實現Workbook格式的介面,檔名是所有角色,表格有兩列,用的是springCloud系列的資料庫
user表
這裡講解一個我當時困惑後來想明白的點,我們的Excel檢視是繼承AbstactXlsView,而AbstactXlsView繼承ModelAndView,所以當我們返回mv時,它會通過呼叫渲染的方法,而AbstactXlsView是實現了自己的渲染方法,我們規則都給了它,它會根據這些規則渲染我們需要的表格
程式碼結束了,上效果圖