1. 程式人生 > >POI 將按日期分表的資料彙總到一個excel中 大資料量

POI 將按日期分表的資料彙總到一個excel中 大資料量

一. 簡介

           現在有按時間分的使用者表,要在每月一號將這些表的資料彙總到一個excel中。每張表的資料量很大。

           昨天通宵搞得,只為紀念,方便以後遇見同樣的需求做參考。

           之前是想著每天匯出一個excel, 然後在月初一起彙總。但是合併excel的時候有問題,這樣跨表查也挺快的。

二. 程式碼

2.1 Ecxel常量類

package com.yzx.caasscs.constant;

/**
 * @author duxuebo
 * @date 2018/9/19
 * @description EXCEL常量類
 */
public class ExcelConstant {

    /**
     * 每個sheet儲存的記錄數 100W
     */
    public static final Integer PER_SHEET_ROW_COUNT = 1000000;

    /**
     * 每次向EXCEL寫入的記錄數(查詢每頁資料大小) 20W
     */
    public static final Integer PER_WRITE_ROW_COUNT = 200000;


    /**
     * 每個sheet的寫入次數 5
     */
    public static final Integer PER_SHEET_WRITE_COUNT = PER_SHEET_ROW_COUNT / PER_WRITE_ROW_COUNT;

}

2.2 EXCEL寫資料委託類

package com.yzx.caasscs.util;

import org.apache.poi.xssf.streaming.SXSSFSheet;

/**
 * @author duxuebo
 * @date 2018/9/20
 * @description EXCEL寫資料委託類
 */
public interface WriteExcelDataDelegated {

    /**
     * EXCEL寫資料委託類  針對不同的情況自行實現
     *
     * @param eachSheet     指定SHEET
     * @param startRowCount 開始行
     * @param endRowCount   結束行
     * @param currentPage   分批查詢開始頁
     * @param pageSize      分批查詢資料量
     * @throws Exception
     */
    public abstract void writeExcelData(SXSSFSheet eachSheet, Integer startRowCount, Integer endRowCount, Integer currentPage, Integer pageSize) throws Exception;


}

2.3 POI工具類

package com.yzx.caasscs.util;


import com.yzx.caasscs.constant.ExcelConstant;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;

/**
 * @author duxuebo
 * @date 2018/9/18
 * @description POI匯出工具類
 */
public class PoiUtil {

    private final static Logger logger = LoggerFactory.getLogger(PoiUtil.class);

    /**
     * 初始化EXCEL(sheet個數和標題)
     *
     * @param totalRowCount 總記錄數
     * @param titles        標題集合
     * @return XSSFWorkbook物件
     */
    public static SXSSFWorkbook initExcel(Integer totalRowCount, String[] titles) {

        // 在記憶體當中保持 100 行 , 超過的資料放到硬碟中在記憶體當中保持 100 行 , 超過的資料放到硬碟中
        SXSSFWorkbook wb = new SXSSFWorkbook(100);

        Integer sheetCount = ((totalRowCount % ExcelConstant.PER_SHEET_ROW_COUNT == 0) ?
                (totalRowCount / ExcelConstant.PER_SHEET_ROW_COUNT) : (totalRowCount / ExcelConstant.PER_SHEET_ROW_COUNT + 1));

        // 根據總記錄數建立sheet並分配標題
        for (int i = 0; i < sheetCount; i++) {
            SXSSFSheet sheet = wb.createSheet("sheet" + (i + 1));
            SXSSFRow headRow = sheet.createRow(0);

            for (int j = 0; j < titles.length; j++) {
                SXSSFCell headRowCell = headRow.createCell(j);
                headRowCell.setCellValue(titles[j]);
            }
        }

        return wb;
    }


    /**
     * 下載EXCEL到本地指定的資料夾
     *
     * @param wb         EXCEL物件SXSSFWorkbook
     * @param exportPath 匯出路徑
     * @param fileName   檔名稱
     * @return 檔案儲存路徑
     */
    public static String downLoadExcelToLocalPath(SXSSFWorkbook wb, String exportPath, String fileName) {
        FileOutputStream fops = null;
        try {

            File dir = new File(exportPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            File excelFile = new File(exportPath + "\\" + fileName + ".xlsx");
            if (excelFile.exists()) {
                excelFile.delete();
                excelFile.createNewFile();
            }

            fops = new FileOutputStream(excelFile);
            wb.write(fops);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != wb) {
                try {
                    wb.dispose();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (null != fops) {
                try {
                    fops.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return exportPath + "\\" + fileName + ".xlsx";
    }


    /**
     * 下載EXCEL到瀏覽器
     *
     * @param wb       EXCEL物件XSSFWorkbook
     * @param response
     * @param fileName 檔名稱
     * @throws IOException
     */
    public static void downLoadExcelToWebsite(SXSSFWorkbook wb, HttpServletResponse response, String fileName) throws IOException {

        response.setHeader("Content-disposition", "attachment; filename="
                + new String((fileName + ".xlsx").getBytes("utf-8"), "ISO8859-1"));//設定下載的檔名

        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            wb.write(outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != wb) {
                try {
                    wb.dispose();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 匯出Excel到本地指定路徑
     *
     * @param totalRowCount           總記錄數
     * @param titles                  標題
     * @param exportPath              匯出路徑
     * @param fileName                檔名稱
     * @param writeExcelDataDelegated 向EXCEL寫資料/處理格式的委託類 自行實現
     * @throws Exception
     */
    public static final void exportExcelToLocalPath(Integer totalRowCount, String[] titles, String exportPath, String fileName, WriteExcelDataDelegated writeExcelDataDelegated) throws Exception {

        logger.info("開始匯出:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));

        // 初始化EXCEL
        SXSSFWorkbook wb = PoiUtil.initExcel(totalRowCount, titles);

        // 呼叫委託類分批寫資料
        int sheetCount = wb.getNumberOfSheets();
        for (int i = 0; i < sheetCount; i++) {
            SXSSFSheet eachSheet = wb.getSheetAt(i);

            for (int j = 1; j <= ExcelConstant.PER_SHEET_WRITE_COUNT; j++) {

                int currentPage = i * ExcelConstant.PER_SHEET_WRITE_COUNT + j;
                int pageSize = ExcelConstant.PER_WRITE_ROW_COUNT;
                int startRowCount = (j - 1) * ExcelConstant.PER_WRITE_ROW_COUNT + 1;
                int endRowCount = startRowCount + pageSize - 1;


                writeExcelDataDelegated.writeExcelData(eachSheet, startRowCount, endRowCount, currentPage, pageSize);

            }
        }


        // 下載EXCEL
        PoiUtil.downLoadExcelToLocalPath(wb, exportPath, fileName);

        logger.info("匯出完成:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
    }


    /**
     * 匯出Excel到瀏覽器
     *
     * @param response
     * @param totalRowCount           總記錄數
     * @param fileName                檔名稱
     * @param titles                  標題
     * @param writeExcelDataDelegated 向EXCEL寫資料/處理格式的委託類 自行實現
     * @throws Exception
     */
    public static final void exportExcelToWebsite(HttpServletResponse response, Integer totalRowCount, String fileName, String[] titles, WriteExcelDataDelegated writeExcelDataDelegated) throws Exception {

        logger.info("開始匯出:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));

        // 初始化EXCEL
        SXSSFWorkbook wb = PoiUtil.initExcel(totalRowCount, titles);


        // 呼叫委託類分批寫資料
        int sheetCount = wb.getNumberOfSheets();
        for (int i = 0; i < sheetCount; i++) {
            SXSSFSheet eachSheet = wb.getSheetAt(i);

            for (int j = 1; j <= ExcelConstant.PER_SHEET_WRITE_COUNT; j++) {

                int currentPage = i * ExcelConstant.PER_SHEET_WRITE_COUNT + j;
                int pageSize = ExcelConstant.PER_WRITE_ROW_COUNT;
                int startRowCount = (j - 1) * ExcelConstant.PER_WRITE_ROW_COUNT + 1;
                int endRowCount = startRowCount + pageSize - 1;

                writeExcelDataDelegated.writeExcelData(eachSheet, startRowCount, endRowCount, currentPage, pageSize);

            }
        }


        // 下載EXCEL
        PoiUtil.downLoadExcelToWebsite(wb, response, fileName);

        logger.info("匯出完成:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
    }


    /**
     * 建立一個excel
     *
     * @param titles 標題列表
     * @return SXSSFWorkbook
     */
    public static SXSSFWorkbook createExcel(String[] titles) {

        SXSSFWorkbook wb = new SXSSFWorkbook(100);

        SXSSFSheet sheet = wb.createSheet("sheet0");
        SXSSFRow headRow = sheet.createRow(0);

        for (int j = 0; j < titles.length; j++) {
            headRow.createCell(j).setCellValue(titles[j]);
        }

        return wb;
    }


    /**
     * 新增一個sheet
     *
     * @param wb     SXSSFWorkbook
     * @param titles 標題陣列
     * @return SXSSFWorkbook
     */
    public static SXSSFWorkbook addSheet(SXSSFWorkbook wb, String[] titles) {

        int sheetCount = wb.getNumberOfSheets();
        SXSSFSheet currentSheet = wb.createSheet("sheet" + sheetCount);
        SXSSFRow headRow = currentSheet.createRow(0);

        for (int i = 0; i < titles.length; i++) {
            headRow.createCell(i).setCellValue(titles[i]);
        }

        return wb;
    }


    public static void main(String[] args) {

        String relativePath = "E:\\temp\\excel";
        String fileName = "test";
        String[] titles = {"姓名", "年齡", "性別"};

        SXSSFWorkbook wb = createExcel(titles);
        wb = addSheet(wb, titles);

        downLoadExcelToLocalPath(wb, relativePath, fileName);
    }


}

2.4 使用者VO類

package com.yzx.caasscs.vo.organiza;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.yzx.caasscs.vo.sys.MenuVO;
import io.swagger.annotations.ApiModelProperty;

import java.util.Date;
import java.util.List;

/**
 * @author duxuebo
 * @date 2018/9/3
 * @description 使用者VO物件
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserVO {

    @ApiModelProperty("使用者ID")
    private Long uid;

    @ApiModelProperty("賬號")
    private String username;

    @ApiModelProperty("密碼")
    private String password;

    @ApiModelProperty("狀態:0刪除,1啟用,2停用")
    private Integer userState;

    @ApiModelProperty("暱稱")
    private String nickname;

    @ApiModelProperty("職位")
    private String position;

    @ApiModelProperty("手機號")
    private String mobile;

    @ApiModelProperty("郵箱")
    private String email;

    @ApiModelProperty("建立人UID")
    private Long createUid;

    @ApiModelProperty("建立時間 格式:yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    @ApiModelProperty("修改人UID")
    private Long updateUid;

    @ApiModelProperty("修改時間 格式:yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

    @ApiModelProperty("登入使用者UID")
    private Long loginUid;

    @ApiModelProperty("選單集合")
    List<MenuVO> menuVOList;

    @ApiModelProperty("部門ID")
    private Long apartmentId;

    @ApiModelProperty("角色ID集合 格式:['roleIdList':['1','2','3']]")
    public List<Long> roleIdList;

    @ApiModelProperty("部門名稱")
    private String apartmentName;

    @ApiModelProperty("角色名稱:如果有多個,逗號分隔")
    private String roleNames;

    @ApiModelProperty("建立人名稱")
    private String createUsername;

    @ApiModelProperty("修改人名稱")
    private String updateUsername;

    @ApiModelProperty("使用者角色關係VO集合")
    List<UserRoleVO> userRoleVOList;

    @ApiModelProperty("當前頁碼")
    private Integer currentPage;

    @ApiModelProperty("每頁記錄數")
    private Integer pageSize;

    @ApiModelProperty("日期字串 yyyyMMdd格式")
    private String Date;

    public Long getUid() {
        return uid;
    }

    public void setUid(Long uid) {
        this.uid = uid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public Integer getUserState() {
        return userState;
    }

    public void setUserState(Integer userState) {
        this.userState = userState;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname == null ? null : nickname.trim();
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position == null ? null : position.trim();
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile == null ? null : mobile.trim();
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email == null ? null : email.trim();
    }

    public Long getCreateUid() {
        return createUid;
    }

    public void setCreateUid(Long createUid) {
        this.createUid = createUid;
    }

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Long getUpdateUid() {
        return updateUid;
    }

    public void setUpdateUid(Long updateUid) {
        this.updateUid = updateUid;
    }

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public List<MenuVO> getMenuVOList() {
        return menuVOList;
    }

    public void setMenuVOList(List<MenuVO> menuVOList) {
        this.menuVOList = menuVOList;
    }

    public Long getApartmentId() {
        return apartmentId;
    }

    public void setApartmentId(Long apartmentId) {
        this.apartmentId = apartmentId;
    }

    public List<Long> getRoleIdList() {
        return roleIdList;
    }

    public void setRoleIdList(List<Long> roleIdList) {
        this.roleIdList = roleIdList;
    }

    public Long getLoginUid() {
        return loginUid;
    }

    public void setLoginUid(Long loginUid) {
        this.loginUid = loginUid;
    }

    public String getApartmentName() {
        return apartmentName;
    }

    public void setApartmentName(String apartmentName) {
        this.apartmentName = apartmentName;
    }

    public String getCreateUsername() {
        return createUsername;
    }

    public void setCreateUsername(String createUsername) {
        this.createUsername = createUsername;
    }

    public String getUpdateUsername() {
        return updateUsername;
    }

    public void setUpdateUsername(String updateUsername) {
        this.updateUsername = updateUsername;
    }

    public List<UserRoleVO> getUserRoleVOList() {
        return userRoleVOList;
    }

    public void setUserRoleVOList(List<UserRoleVO> userRoleVOList) {
        this.userRoleVOList = userRoleVOList;
    }

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public String getRoleNames() {
        return roleNames;
    }

    public void setRoleNames(String roleNames) {
        this.roleNames = roleNames;
    }

    public String getDate() {
        return Date;
    }

    public void setDate(String date) {
        Date = date;
    }
}

2.5 使用者控制類

package com.yzx.caasscs.controller.organiza;

import com.yzx.caasscs.controller.BaseController;
import com.yzx.caasscs.service.organiza.UserService;
import com.yzx.caasscs.vo.PageVO;
import com.yzx.caasscs.vo.ResultVO;
import com.yzx.caasscs.vo.organiza.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;

/**
 * @author duxuebo
 * @date 2018/8/30
 * @description 使用者控制類
 */
@Api(tags = {"UserController"}, description = "使用者Controller")
@RestController
@RequestMapping(value = "/user")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    // http://localhost:8080/user/send/email
    @GetMapping("/send/email")
    public ResultVO<Void> sendUserEmail(@ApiIgnore UserVO userVO) throws Exception {
        return this.userService.sendUserEmail(userVO);
    }

}

2.6 使用者service

package com.yzx.caasscs.service.organiza;

import com.yzx.caasscs.vo.PageVO;
import com.yzx.caasscs.vo.ResultVO;
import com.yzx.caasscs.vo.organiza.UserVO;

import javax.servlet.http.HttpServletResponse;

/**
 * @author duxuebo
 * @date 2018/8/30
 * @description 使用者SERVICE
 */
public interface UserService {

    /**
     * 傳送使用者Email
     * @param userVO
     * @return
     * @throws Exception
     */
    ResultVO<Void> sendUserEmail(UserVO userVO) throws Exception;
}

2.7 使用者serviceImpl

package com.yzx.caasscs.service.impl.organiza;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yzx.caasscs.constant.ExcelConstant;
import com.yzx.caasscs.constant.middleware.RedisConstant;
import com.yzx.caasscs.constant.organiza.UserApartmentConstant;
import com.yzx.caasscs.constant.organiza.UserConstant;
import com.yzx.caasscs.constant.organiza.UserRoleConstant;
import com.yzx.caasscs.constant.sys.SysLogConstant;
import com.yzx.caasscs.entity.dscaasscs.organiza.User;
import com.yzx.caasscs.entity.dscaasscs.organiza.UserApartment;
import com.yzx.caasscs.entity.dscaasscs.organiza.UserRole;
import com.yzx.caasscs.mapper.dscaasscs.organiza.UserApartmentMapper;
import com.yzx.caasscs.mapper.dscaasscs.organiza.UserMapper;
import com.yzx.caasscs.mapper.dscaasscs.organiza.UserRoleMapper;
import com.yzx.caasscs.mapper.dscaasscs.sys.RoleMenuMapper;
import com.yzx.caasscs.service.organiza.UserService;
import com.yzx.caasscs.service.sys.SysLogService;
import com.yzx.caasscs.util.CommonUtil;
import com.yzx.caasscs.util.DateUtil;
import com.yzx.caasscs.util.PoiUtil;
import com.yzx.caasscs.util.WriteExcelDataDelegated;
import com.yzx.caasscs.vo.PageVO;
import com.yzx.caasscs.vo.ResultVO;
import com.yzx.caasscs.vo.organiza.UserApartmentVO;
import com.yzx.caasscs.vo.organiza.UserRoleVO;
import com.yzx.caasscs.vo.organiza.UserVO;
import com.yzx.caasscs.vo.sys.MenuVO;
import com.yzx.caasscs.vo.sys.RoleMenuVO;
import com.yzx.caasscs.vo.sys.SysLogVO;
import net.sf.json.JSONObject;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * @author duxuebo
 * @date 2018/8/30
 * @description 使用者SERVICEIMPL
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;


    @Override
    public ResultVO<Void> sendUserEmail(UserVO userVO) throws Exception {

        System.out.println("開始計時:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));


        // 有5個執行的任務
        for (int i = 0; i < 1; i++) {

            // 1. 建立excel表 並設定標題  excel的名稱為任務的主鍵
            String relativePath = "E:\\temp\\excel\\2018\\09";
            String fileName = i + "";
            String[] titles = {"使用者ID", "使用者名稱", "暱稱", "手機號", "建立時間"};
            SXSSFWorkbook wb = PoiUtil.createExcel(titles);


            // 2. 獲取當前月份的所有日期格式化字串集合
            List<String> dateList = new ArrayList<>();
            dateList.add("20180901");
            dateList.add("20180902");
            dateList.add("20180903");
            dateList.add("20180904");
            dateList.add("20180905");


            // 3. 遍歷所有日期的符合條件的話單表獲取到總資料量來確定sheet數量 並標記每天的資料量
            Integer totalRowCount = 0;
            Map<String, Integer> dayAndCountMap = new HashMap<>();
            for (String eachDate : dateList) {
                userVO.setDate(eachDate);
                Integer eachDayCount = this.userMapper.selectUserDateCount(userVO);
                dayAndCountMap.put(eachDate, eachDayCount);
                totalRowCount = totalRowCount + eachDayCount;
            }

            Integer sheetCount = totalRowCount % ExcelConstant.PER_SHEET_ROW_COUNT == 0 ?
                    totalRowCount / ExcelConstant.PER_SHEET_ROW_COUNT : (totalRowCount / ExcelConstant.PER_SHEET_ROW_COUNT + 1);
            for (int j = 1; j < sheetCount; j++) {
                PoiUtil.addSheet(wb, titles);
            }


            // 4. 將當前月份的日期表全部遍歷一遍,並寫到excel中
            Integer currentSheetIndex = 0;
            Integer startWriteRowIndex = 1;

            for (String eachDate : dateList) {

                userVO.setDate(eachDate);
                Integer currentDayCount = dayAndCountMap.get(eachDate);

                // 如果當前寫的開始行索引 + 當前天的記錄數量 大於一個sheet的儲存上限,則換到另一個sheet開始寫
                // 注意: 此處要大於+1  例如:50萬零1 + 50W > 100W零1的時候才會建立新的sheet
                if(startWriteRowIndex + currentDayCount > ExcelConstant.PER_SHEET_ROW_COUNT) {
                    currentSheetIndex = currentSheetIndex + 1;
                    startWriteRowIndex = 1;
                }

                Integer writeCount = currentDayCount % ExcelConstant.PER_WRITE_ROW_COUNT == 0 ?
                        currentDayCount / ExcelConstant.PER_WRITE_ROW_COUNT : (currentDayCount / ExcelConstant.PER_WRITE_ROW_COUNT + 1);

                for (int j = 1; j <= writeCount; j++) {

                    if (j != writeCount) {

                        PageHelper.startPage(j, ExcelConstant.PER_WRITE_ROW_COUNT);
                        List<UserVO> userVOList = this.userMapper.selectUserDateList(userVO);

                        // 寫資料
                        writeExcelData(wb, currentSheetIndex, startWriteRowIndex, userVOList);

                        startWriteRowIndex = startWriteRowIndex + ExcelConstant.PER_WRITE_ROW_COUNT;

                    } else {
                        PageHelper.startPage(j, currentDayCount % ExcelConstant.PER_WRITE_ROW_COUNT);
                        List<UserVO> userVOList = this.userMapper.selectUserDateList(userVO);

                        // 寫資料
                        writeExcelData(wb, currentSheetIndex, startWriteRowIndex, userVOList);

                        startWriteRowIndex = startWriteRowIndex + currentDayCount % ExcelConstant.PER_WRITE_ROW_COUNT;
                    }
                }
            }


            // 4. 下載excel到webroot目錄下
            String excelPath = PoiUtil.downLoadExcelToLocalPath(wb, relativePath, fileName);
            System.out.println(excelPath);

            // 5. 傳送郵件

        }

        System.out.println("結束計時:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));

        return ResultVO.getSuccess("傳送使用者Email成功");
    }


    private void writeExcelData(SXSSFWorkbook wb, Integer currentSheetIndex, Integer startWriteRowIndex, List<UserVO> userVOList) {
        if (!CollectionUtils.isEmpty(userVOList)) {
            for (UserVO eachUserVO : userVOList) {
                SXSSFSheet currentSheet = wb.getSheetAt(currentSheetIndex);
                SXSSFRow row = currentSheet.createRow(startWriteRowIndex);
                if (null != eachUserVO.getUid()) {
                    row.createCell(0).setCellValue(eachUserVO.getUid());
                }
                row.createCell(1).setCellValue(eachUserVO.getUsername() == null ? "" : eachUserVO.getUsername());
                row.createCell(2).setCellValue(eachUserVO.getNickname() == null ? "" : eachUserVO.getNickname());
                row.createCell(3).setCellValue(eachUserVO.getMobile() == null ? "" : eachUserVO.getMobile());
                if (null != eachUserVO.getCreateTime()) {
                    row.createCell(0).setCellValue(DateUtil.formatDate(eachUserVO.getCreateTime(), DateUtil.YYYY_MM_DD_HH_MM_SS));
                }
                startWriteRowIndex = startWriteRowIndex + 1;
            }
        }
    }
}

2.8 使用者mapper

package com.yzx.caasscs.mapper.dscaasscs.organiza;

import com.yzx.caasscs.entity.dscaasscs.organiza.User;
import com.yzx.caasscs.vo.organiza.UserVO;

import java.util.List;

/**
 * @author duxuebo
 * @date 2018/8/29
 * @description 使用者MAPPER
 */
public interface UserMapper {

     /**
     * 查詢指定日期的使用者表總數
     *
     * @param userVO
     * @return 總數
     * @throws Exception
     */
    Integer selectUserDateCount(UserVO userVO) throws Exception;


    /**
     * 查詢指定日期的使用者列表
     *
     * @param userVO
     * @return UserVO列表
     * @throws Exception
     */
    List<UserVO> selectUserDateList(UserVO userVO) throws Exception;
}

2.9 使用者mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.yzx.caasscs.mapper.dscaasscs.organiza.UserMapper" >

  <resultMap id="BaseResultMap" type="com.yzx.caasscs.entity.dscaasscs.organiza.User" >
    <id column="uid" property="uid" jdbcType="BIGINT" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="state" property="state" jdbcType="INTEGER" />
    <result column="nickname" property="nickname" jdbcType="VARCHAR" />
    <result column="position" property="position" jdbcType="VARCHAR" />
    <result column="mobile" property="mobile" jdbcType="VARCHAR" />
    <result column="email" property="email" jdbcType="VARCHAR" />
    <result column="create_uid" property="createUid" jdbcType="BIGINT" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
    <result column="update_uid" property="updateUid" jdbcType="BIGINT" />
    <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
  </resultMap>


  <!-- 查詢指定日期的使用者列表 -->
  <resultMap id="SelectUserDateListMap" type="com.yzx.caasscs.vo.organiza.UserVO" >
    <id column="uid" property="uid" jdbcType="BIGINT" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="nickname" property="nickname" jdbcType="VARCHAR" />
    <result column="mobile" property="mobile" jdbcType="VARCHAR" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
  </resultMap>


  <sql id="Base_Column_List" >
    uid, username, password, state, nickname, position, mobile, email, create_uid, create_time,
    update_uid, update_time
  </sql>


  <!-- 查詢指定日期的使用者表的總數 -->
  <select id="selectUserDateCount" parameterType="com.yzx.caasscs.vo.organiza.UserVO" resultType="java.lang.Integer">
    SELECT
        count(1)
    FROM
        user_${date}
  </select>


  <!-- 查詢指定日期的使用者列表 -->
  <select id="selectUserDateList" parameterType="com.yzx.caasscs.vo.organiza.UserVO" resultMap="SelectUserDateListMap">
    SELECT
        uid, username, nickname, mobile, create_time
    FROM
        user_${date}
  </select>

</mapper>