1. 程式人生 > >Java Web匯出excel表,瀏覽器下載匯出excel表

Java Web匯出excel表,瀏覽器下載匯出excel表

1 自定義註解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelTable {
    String value() default "";
}

2 使用在欄位上

/**
* 使用舉例
*/
public class User {

    //姓名
    @ExcelTable("姓名")
    private String name;

    //性別
    @ExcelTable("性別")
    private String sex;

    //年齡
    @ExcelTable("年齡")
    private String age;

}

3 匯出excel表的工具類

/**
 * Excel匯出工具類
 *
 * @author ellen
 * @version 1.0
 * @date 2018/11/11
 */
public class ExcelUtil {

    /**
     * @param list
     * @param sheetName
     * @param response
     * @param <T>
     * @throws Exception
     * @Description : 匯出Excel(匯出到瀏覽器,工作表的大小是2003支援的最大值)
     */
    public static <T> void listToExcel(List<T> list, String sheetName, HttpServletResponse response) throws Exception {
        listToExcel(list, sheetName, 65535, response);
    }

    /**
     * @param list
     * @param sheetName
     * @param response
     * @param <T>
     * @throws Exception
     * @Description : 匯出Excel(匯出到瀏覽器,可以自定義工作表的大小)
     */
    public static <T> void listToExcel(List<T> list, String sheetName, int sheetSize, HttpServletResponse response) throws Exception {

        //設定預設檔名為當前時間:年月日時分秒
        String fileName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()).toString();
        //設定response頭資訊
        response.reset();
        //改成輸出excel檔案
        response.setContentType("application/vnd.ms-excel");
        //設定檔案下載頭
        response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xls");
        try {
            OutputStream out = response.getOutputStream();
            listToExcel(list, sheetSize, sheetName, out);
        } catch (Exception e) {
            e.printStackTrace();

            //如果是ExcelException,則直接丟擲
            if (e instanceof CustomException) {
                throw (CustomException) e;
                //否則將其它異常包裝成ExcelException再丟擲
            } else {
                throw new CustomException("匯出Excel失敗");
            }
        }
    }

    /**
     * 一次匯出全部
     *
     * @param list
     * @param sheetSize 每個工作表記錄的最大數值
     * @param sheetName 每個工作表的名字
     * @param out       匯出流
     * @param <T>
     * @throws Exception
     * @Description : 匯出Excel(可以匯出到本地檔案系統,可自定義工作表大小)
     */
    public static <T> void listToExcel(List<T> list, int sheetSize, String sheetName, OutputStream out) throws Exception {

        if (list.size() == 0 || list == null) {
            throw new CustomException("資料來源中沒有任何資料");
        }
        //最大數值為65535
        if (sheetSize > 65535 || sheetSize < 1) {
            sheetSize = 65535;
        }

        //新建一個xls工作簿
        Workbook wb = new HSSFWorkbook();
        CreationHelper createHelper = wb.getCreationHelper();
        Sheet sheet = null;
        //如果數值太多,放到多個工作表中
        //計算一共有多少個工作表
        double sheetNum = Math.ceil(list.size() / new Integer(sheetSize).doubleValue());

        //多個工作表的情況
        for (int i = 0; i < sheetNum; i++) {

            if (sheetNum == 1) {
                //新建一個表
                sheet = wb.createSheet(sheetName);//表的名字是Excel不得超過31個字元
                fillSheet(list, sheet, 0, list.size() - 1);
            } else {
                //獲取開始索引和結束索引
                int firstIndex = i * sheetSize;
                int lastIndex = (i + 1) * sheetSize - 1 > list.size() - 1 ? list.size() - 1 : (i + 1) * sheetSize - 1;

                sheet = wb.createSheet(sheetName + (i + 1));
                fillSheet(list, sheet, firstIndex, lastIndex);
            }

        }

        // Write the output to a file
        wb.write(out);
    }

    /**
     * 填充資料
     *
     * @param list
     * @param sheet      工作表插入
     * @param firstIndex 開始索引
     * @param lastIndex  結束索引
     * @param <T>
     * @throws Exception
     */
    private static <T> void fillSheet(List<T> list, Sheet sheet, int firstIndex, int lastIndex) throws Exception {
        Field[] fields = list.get(0).getClass().getDeclaredFields();
        //記錄行數
        int rowNum = 0;
        //記錄列數
        int cellNum = 0;
        Row row = sheet.createRow(0);
        row.setHeightInPoints(30);
        rowNum++;
        List<String> keylist = new ArrayList<>();
        for (Field field : fields) {

            Cell cell = row.createCell(cellNum);
            if (field.isAnnotationPresent(ExcelTable.class)) {
                ExcelTable excelRowName = field.getAnnotation(ExcelTable.class);
                cell.setCellValue(excelRowName.value());
                //儲存到list
                keylist.add(field.getName());
                cellNum++;
            }

        }

        for (int index = firstIndex; index <= lastIndex; index++) {

            T object = list.get(index);
            Row row1 = sheet.createRow(rowNum);
            rowNum++;
            cellNum = 0;
            for (String string : keylist) {
                Field field = object.getClass().getDeclaredField(string);
                //設為可見
                field.setAccessible(true);
                Object value = field.get(object);
                Cell cell = row1.createCell(cellNum);

                //不需要做處理
                if (value != null) {
                    cell.setCellValue(value.toString());
                }

                cellNum++;
            }

        }
    }

    /**
     * 分工作表匯出
     *
     * @param list
     * @param sheetSize 每個工作表的行數(不得超過65535)
     * @param sheetName 工作表的名稱
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> Workbook CreateExcelWorkbook(List<T> list, int sheetSize, String sheetName) throws Exception {

        if (list.size() == 0 || list == null) {
            throw new CustomException("資料來源中沒有任何資料");
        }
        //最大數值為65535
        if (sheetSize > 65535 || sheetSize < 1) {
            throw new CustomException("sheetSize數值有誤");
        }

        //新建一個xls工作簿
        Workbook wb = new HSSFWorkbook();
        CreationHelper createHelper = wb.getCreationHelper();
        Sheet sheet = null;

        //新建一個表
        sheet = wb.createSheet(sheetName);//表的名字是Excel不得超過31個字元
        fillSheet(list, sheet, 0, list.size() - 1);

        return wb;
    }

    /**
     * 新增資料
     *
     * @param list
     * @param sheetSize
     * @param sheetName
     * @param FilePath
     * @param <T>
     * @throws Exception
     */
    public static <T> void addListToExcel(List<T> list, int sheetSize, String sheetName, String FilePath) throws Exception {
        if (list.size() == 0 || list == null) {
            throw new CustomException("資料來源中沒有任何資料");
        }
        // 判斷資料大小是否比最後一個表剩餘的大小小,小的話可以直接在表中繼續寫,大的話在當前表中寫完後繼續在後面表中寫
        //獲得一個xls工作簿
        Workbook wb = returnWorkBookByFileName(FilePath);
        CreationHelper createHelper = wb.getCreationHelper();
        //獲得最後一個工作表
        Sheet sheet = wb.getSheetAt(wb.getNumberOfSheets() - 1);
        //記錄行數
        int rowNum = sheet.getLastRowNum();

        double sheetNum = 0;
        if (sheetSize > (65535 - sheet.getLastRowNum())) {
            // 判斷當前表填滿後還需要多少個表
            sheetNum = Math.ceil((list.size() - (65535 - sheet.getLastRowNum())) / new Integer(65535).doubleValue());
        }

        // 如果在當前表中可以能容納list大小的資料
        if (sheetNum == 0) {
            ContinueToSheet(list, sheet, rowNum, 0, list.size() - 1);
        } else {
            int i = 0;
            // 將當前表填充完整
            ContinueToSheet(list, sheet, rowNum, 0, 65535 - sheet.getLastRowNum());
            i = 65535 - sheet.getLastRowNum();
            // 繼續將新建表填充
            for (int index = 0; index < sheetNum; index++) {
                sheet = wb.createSheet(sheetName + (i + 1));
                ContinueToSheet(list, sheet, rowNum, i + 1, i + 65535);
                i += 65535;
            }
        }

        // Write the output to a file
        FileOutputStream fileOut = new FileOutputStream(FilePath);
        wb.write(fileOut);
        fileOut.close();
    }

    /**
     * @param list
     * @param sheet      工作表插入
     * @param beginIndex 開始索引
     * @param endIndex   結束索引
     * @param <T>
     * @throws Exception
     */
    private static <T> void ContinueToSheet(List<T> list, Sheet sheet, int rowNum, int beginIndex, int endIndex) throws Exception {
        Field[] fields = list.get(0).getClass().getDeclaredFields();

        // 獲得最後一行
        Row row = sheet.getRow(rowNum);
        //記錄列數
        int cellNum = 0;

        // 列數
        List<String> keylist = null;
        //  row.setHeightInPoints(30);
        keylist = new ArrayList<>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ExcelTable.class)) {
                ExcelTable excelRowName = field.getAnnotation(ExcelTable.class);
                //儲存到list
                keylist.add(field.getName());
                cellNum++;
            }

        }

        for (int index = beginIndex; index <= endIndex; index++) {

            T object = list.get(index);
            Row row1 = sheet.createRow(rowNum);
            rowNum++;
            cellNum = 0;
            for (String string : keylist) {
                Field field = object.getClass().getDeclaredField(string);
                //設為可見
                field.setAccessible(true);
                Object value = field.get(object);
                Cell cell = row1.createCell(cellNum);
                if (value == null) {
                    cell.setCellValue(" ");
                } else {
                    //不需要做處理
                    if (value != null) {
                        cell.setCellValue(value.toString());
                    }
                }
                cellNum++;
            }

        }

    }

    /**
     * 通過檔案輸入流得到一個工作蒲
     *
     * @param is
     * @return
     * @throws IOException
     */
    private static HSSFWorkbook returnWorkBookByFileStream(InputStream is) throws IOException {
        HSSFWorkbook wb = null;
        wb = new HSSFWorkbook(is);
        return wb;
    }

    /**
     * 通過檔案路徑得到一個工作蒲
     *
     * @param FilePath
     * @return
     * @throws IOException
     */
    private static HSSFWorkbook returnWorkBookByFileName(String FilePath) throws IOException {
        InputStream inp = new FileInputStream(FilePath);
        return returnWorkBookByFileStream(inp);
    }

    /**
     * @param list
     * @param sheetName
     * @param <T>
     * @throws Exception
     * @Description : 匯出Excel(可以匯出到本地檔案系統,工作表大小為2003支援的最大值)
     */
    public static <T> void listToExcel(List<T> list, String sheetName, OutputStream outputStream) throws Exception {
        listToExcel(list, 65535, sheetName, outputStream);
    }

    /**
     * @param list
     * @param sheetSize
     * @param sheetName
     * @param FilePath
     * @param <T>
     * @throws Exception
     */
    public static <T> void addListToExcel(List<T> list, int sheetSize, String sheetName, String FilePath, OutputStream out) throws Exception {

        if (list.size() == 0 || list == null) {
            throw new CustomException("資料來源中沒有任何資料");
        }
        //最大數值為65535
        if (sheetSize > 65535 || sheetSize < 1) {
            sheetSize = 65535;
        }

        //獲得一個xls工作簿
        Workbook wb = returnWorkBookByFileName(FilePath);
        CreationHelper createHelper = wb.getCreationHelper();
        //獲得最後一個工作表
        Sheet sheet = wb.getSheetAt(wb.getNumberOfSheets() - 1);

        //判斷當前新增的表
        if (sheetSize > (65535 - sheet.getLastRowNum())) {

        }
        double sheetNum = Math.ceil((list.size() + sheet.getLastRowNum()) / new Integer(sheetSize).doubleValue());

        //多個工作表的情況
        for (int i = 0; i < sheetNum; i++) {

            if (sheetNum == 1) {
                //新建一個表
                //    sheet = wb.createSheet(sheetName);//表的名字是Excel不得超過31個字元
                addSheet(list, sheet, 0, list.size() - 1);
            } else {
                //獲取開始索引和結束索引
                int firstIndex = i * sheetSize;
                int lastIndex = (i + 1) * sheetSize - 1 > list.size() - 1 ? list.size() - 1 : (i + 1) * sheetSize - 1;

                sheet = wb.createSheet(sheetName + (i + 1));
                fillSheet(list, sheet, firstIndex, lastIndex);
            }

        }

        // Write the output to a file
        FileOutputStream fileOut = new FileOutputStream(FilePath);
        wb.write(fileOut);
        fileOut.close();

    }


    /**
     * @param list
     * @param sheet      工作表插入
     * @param firstIndex 開始索引
     * @param lastIndex  結束索引
     * @param <T>
     * @throws Exception
     */
    private static <T> void addSheet(List<T> list, Sheet sheet, int firstIndex, int lastIndex) throws Exception {
        Field[] fields = list.get(0).getClass().getDeclaredFields();
        //記錄行數
        int rowNum = sheet.getLastRowNum();
        //獲得最後一行
        Row row = sheet.getRow(rowNum);
        //記錄列數
        int cellNum = 0;


        //  row.setHeightInPoints(30);
        rowNum++;
        List<String> keylist = new ArrayList<>();
        for (Field field : fields) {

            Cell cell = row.createCell(cellNum);
            if (field.isAnnotationPresent(ExcelTable.class)) {
                ExcelTable excelRowName = field.getAnnotation(ExcelTable.class);
                cell.setCellValue(excelRowName.value());
                //儲存到list
                keylist.add(field.getName());
                cellNum++;
            }

        }

        for (int index = firstIndex; index <= lastIndex; index++) {

            T object = list.get(index);
            Row row1 = sheet.createRow(rowNum);
            rowNum++;
            cellNum = 0;
            for (String string : keylist) {
                Field field = object.getClass().getDeclaredField(string);
                //設為可見
                field.setAccessible(true);
                Object value = field.get(object);
                Cell cell = row1.createCell(cellNum);
                if (value == null) {
                    cell.setCellValue(" ");
                } else {
                    cell.setCellValue(value.toString());
                }
                cellNum++;
            }

        }

    }

    public static Workbook addDate(List<T> list, int sheetSize, String sheetName, Workbook wb) {

        if (list.size() == 0 || list == null) {
            throw new CustomException("資料來源中沒有任何資料");
        }
        //最大數值為65535
        if (sheetSize > 65535 || sheetSize < 1) {
            sheetSize = 65535;
        }

        CreationHelper createHelper = wb.getCreationHelper();
        //獲得最後一個工作表
        Sheet sheet = wb.getSheetAt(wb.getNumberOfSheets() - 1);

        //如果數值太多,放到多個工作表中
        //計算一共有多少個工作表
        double sheetNum = Math.ceil(list.size() + sheet.getLastRowNum() / new Integer(sheetSize).doubleValue());

        //多個工作表的情況
        for (int i = 0; i < sheetNum; i++) {

//            if(sheetNum == 1){
//                //新建一個表
//                //    sheet = wb.createSheet(sheetName);//表的名字是Excel不得超過31個字元
//                addSheet(list,sheet,0,list.size()-1);
//            }
//            else {
//                //獲取開始索引和結束索引
//                int firstIndex=i * sheetSize;
//                int lastIndex=(i+1)*sheetSize-1>list.size()-1 ? list.size()-1 : (i+1)*sheetSize-1;
//
//                sheet = wb.createSheet(sheetName + (i+1));
//                fillSheet(list,sheet,firstIndex,lastIndex);
//            }
//
//
//        }
//
//        // Write the output to a file
//        FileOutputStream fileOut = new FileOutputStream(FilePath);
//        wb.write(fileOut);
//        fileOut.close();

        }

        return wb;
    }

}