Spring MVC 實例:Excel視圖的使用


  對於Excel而言,Spring MVC所推薦的是使用AbstractXlsView,它實現了視圖接口,從其命名也可以知道它只是一個抽象類,不能生成實例對象。它自己定義了一個抽象方法——buildExcelDocument要去實現。其他的方法Spring的AbstractXlsView已經實現了,所以對於我們而言完成這個方法便可以使用Excel的視圖功能了
  buildExcelDocument方法的主要任務是創建一個Workbook,它要用到POI的API,這需要我們自行下載並導入項目中。這里的參數在代碼中也給出了,在Spring MVC中已經對導出Excel進行了很多的封裝,所以很多細節我們並不需要關心。

<!-- poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>

 

  假設需要一個導出所有角色信息的功能,但是將來也許還有其他的導出功能。為了方便,先定義一個接口,這個接口主要是讓開發者自定義生成Excel的規則,如代碼清單15-46所示。
  代碼清單15-46:自定義導出接口定義

package com.ssm.chapter15.view;

import org.apache.poi.ss.usermodel.Workbook;

import java.util.Map;

public interface ExcelExportService {

    /***
     * 生成exel文件規則
     * @param model 數據模型
     * @param workbook excel workbook
     */
    public void makeWorkBook(Map<String, Object> model, Workbook workbook);

}

 

  有了這個接口還需要完成一個可實例化的Excel視圖類——ExcelView,對於導出而言還需要一個下載文件名稱,所以還會定義一個文件名(fileName)屬性,由於該視圖不是一個邏輯視圖,所以無須視圖解析器也可以運行它,其定義如代碼清單15-47所示。
  代碼清單15-47:定義Excel視圖

package com.ssm.chapter15.view;

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.view.document.AbstractXlsView;

public class ExcelView extends AbstractXlsView {

    //文件名
    private String fileName = null;

    //導出視圖自定義接口
    private ExcelExportService excelExpService = null;

    //構造方法1
    public ExcelView(ExcelExportService excelExpService) {
        this.excelExpService = excelExpService;
    }

    //構造方法2
    public ExcelView(String viewName, ExcelExportService excelExpService) {
        this.setBeanName(viewName);
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public ExcelExportService getExcelExpService() {
        return excelExpService;
    }

    public void setExcelExpService(ExcelExportService excelExpService) {
        this.excelExpService = excelExpService;
    }

    @Override
    protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception {

        //沒有自定義接口
        if (excelExpService == null) {
            throw new RuntimeException("導出服務接口不能為null!!");
        }
        // 文件名不為空,為空則使用請求路徑中的字符串作為文件名
        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);
        }
        // 回調接口方法,使用自定義生成Excel文檔
        excelExpService.makeWorkBook(model, workbook);
    }
}

 

  上面的代碼實現了生成Excel的buildExcelDocument方法,這樣就完成了一個視圖類。回調了自定義的接口方法可以根據需要進行自定義生成Excel的規則,接着我們需要在角色控制器中加入新的方法,來滿足導出所有角色的要求,如代碼清單15-48所示。

  代碼清單15-48:使用ExcelView導出Excel

package com.ssm.chapter15.controller;

import com.ssm.chapter15.pojo.PageParams;
import com.ssm.chapter15.pojo.Role;
import com.ssm.chapter15.pojo.RoleParams;
import com.ssm.chapter15.view.ExcelExportService;
import com.ssm.chapter15.view.ExcelView;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/excel")
public class ExcelController {

    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public ModelAndView export() {
        //模型和視圖
        ModelAndView mv = new ModelAndView();
        // Excel視圖,並設置自定義導出接口
        ExcelView ev = new ExcelView(exportService());
        //文件名
        ev.setFileName("所有角色.xlsx");
        // // 設置SQL后台參數
        // RoleParams roleParams = new RoleParams();
        // // 限制1萬條
        // PageParams page = new PageParams();
        // page.setStart(0);
        // page.setLimit(10000);
        // roleParams.setPageParams(page);
        // 查詢
        // List<Role> roleList = roleService.findRoles(roleParams);
        List<Role> roleList = new ArrayList<>();
        roleList.add(new Role(1l, "射手", "遠程物理輸出"));
        roleList.add(new Role(2l, "法師", "魔法輸出"));
        // 加入數據模型
        mv.addObject("roleList", roleList);
        mv.setView(ev);
        return mv;
    }

    @SuppressWarnings({"unchecked"})
    private ExcelExportService exportService() {
        // 使用Lambda表達式自定義導出excel規則
        return (Map<String, Object> model, Workbook workbook) -> {
            // 獲取用戶列表
            List<Role> roleList = (List<Role>) model.get("roleList");
            // 生成Sheet
            Sheet sheet = workbook.createSheet("所有角色");
            // 加載標題
            Row title = sheet.createRow(0);
            title.createCell(0).setCellValue("編號");
            title.createCell(1).setCellValue("名稱");
            title.createCell(2).setCellValue("備注");
            //便利角色列表,生成一行行的數據
            for (int i = 0; i < roleList.size(); i++) {
                Role role = roleList.get(i);
                int rowIdx = i + 1;
                Row row = sheet.createRow(rowIdx);
                row.createCell(0).setCellValue(role.getId());
                row.createCell(1).setCellValue(role.getRoleName());
                row.createCell(2).setCellValue(role.getNote());
            }
        };
    }

}

 

  這樣就能夠導出Excel了,ExcelExportService接口的實現使用了Lambda表達式,因此Java版本是8及以上,Java 8以下的版本可以使用匿名類的方法去實現它。這里使用了ExcelExportService接口,就可以在自己的控制器上自定義導出規則,這樣就可以根據需要開發了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM