zoukankan      html  css  js  c++  java
  • 自定义注解

    自定义注解 - 实体转Excel
    原创swotXu 发布于2019-12-29 18:29:14 阅读数 14  收藏
    展开

    自定义注解 - 实体转Excel
    一、环境准备
    1、JDK安装配置
    2、MAVEN安装配置
    3、POM依赖引入
    二、代码演示
    三、代码实现
    1、@ExcelColunm 注解
    2、ExcelColunmParse
    3、ExcelSheet
    4、ExcelParse2SheetAdapte
    5、ExcelHandle
    一、环境准备
    由于平时工作中,经常会有这种,将某个列表的数据导出成excel的需求。此功能就属于比较通用的功能了,于是呢,为了避免重复代码,就设计了此种方式进行实现。

    博主这里创建的 springboot 2.2.1.RELEASE 项目。使用的 jdk1.8 + poi 3.16, 另外日志用到了 lombok 1.18.10。

    1、JDK安装配置
    参考我的另外一篇博客:
    链接: JDK安装配置-swotXu.

    2、MAVEN安装配置
    参考我的另外一篇博客:
    链接: MAVEN安装配置-swotXu.

    3、POM依赖引入

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.16</version>
    </dependency>



    二、代码演示
    先来看看怎么使用。大家如果觉得使用比较方便有趣,咱们再看看怎么实现的。
    这里使用的几个封装类简单介绍下:

    ExcelParse2SheetAdapte 对象
    实体数据解析与ExcelSheet的适配器,用于将实体数据集 转换为 ExcelSheet 对象
    提供ExcelSheet getExcelSheet(String title, boolean hasOrderNum) 方法获取对象。
    ExcelSheet 对象
    承载excel映射的对象,封装了对于POI相关操作,用于生成excel。
    ExcelHandle 对象
    工具类,用于将 ExcelSheet对象输出生成具体的excel文件。
    支持生成到具体磁盘目录、输出到指定流、web端直接输出下载三种方式。
    HandleTimer 对象
    HandleTimer.runTime() 是用来统计方法耗时的一个工具类
    详细信息可参考我的另外一篇文章:
    链接: JDK1.8 - lamda 接口耗时统计-swotXu.
    import com.swotxu.verifyideas.common.algorithm.timer.HandleTimer;
    import com.swotxu.verifyideas.demo02.pojo.PeopleEntity;
    import com.swotxu.verifyideas.demo02.utils.ExcelHandle;
    import com.swotxu.verifyideas.demo02.utils.ExcelParse2SheetAdapte;
    import com.swotxu.verifyideas.demo02.utils.ExcelSheet;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFFont;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.UUID;

    /**
     * @Classname: springboot-parent
     * @Date: 2019/12/16 0016 13:48
     * @Author: swotXu
     */
    public class TestMain {
        /**
         * 生成测试数据  list
         * @return
         */
        public static List<PeopleEntity> getTestDataList(){
            List<PeopleEntity> dataList = new ArrayList<>();
            Random random = new Random();
            for (int i = 0; i < 10; i++) {
                PeopleEntity entity = new PeopleEntity();
                entity.setIdCard(UUID.randomUUID().toString());
                entity.setName("name" + i);
                entity.setAge(random.nextInt(100));
                entity.setSex(random.nextBoolean()? "男" : "女");

                dataList.add(entity);
            }
            return dataList;
        }
        public static void execute(){
            // 获取测试数据
            List<PeopleEntity> dataList1 = getTestDataList();
            // 根据实体数据,获取excelSheet的适配器
            ExcelParse2SheetAdapte<PeopleEntity> sheetAdapte1 = new ExcelParse2SheetAdapte(dataList1, PeopleEntity.class);
            // 通过适配器拿到 excelSheet 对象,设置标题,开启序号列
            ExcelSheet sheet1 = sheetAdapte1.getExcelSheet("测试table1", ExcelSheet.USE_ORDER_NUMBER);
            
            // 获取测试数据
            List<PeopleEntity> dataList2 = getTestDataList();
            // 根据实体数据,获取excelSheet的适配器
            ExcelParse2SheetAdapte<PeopleEntity> sheetAdapte2 = new ExcelParse2SheetAdapte(dataList2, PeopleEntity.class);
            // 通过适配器拿到 excelSheet 对象,设置标题,关闭序号列
            ExcelSheet sheet2 = sheetAdapte2.getExcelSheet("测试table2", ExcelSheet.DEL_ORDER_NUMBER);
            // 可以手动设置单元格样式, 也可不设置 - 使用默认样式
            sheet2.setBodyColumnTopStyleFun(workbook -> {
                // 设置字体
                HSSFFont font = workbook.createFont();
                font.setFontHeightInPoints((short)10); //设置字体大小
                font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //字体加粗
                font.setFontName("Courier New"); //设置字体名字
                //设置样式;
                HSSFCellStyle style = workbook.createCellStyle();
                style.setBorderBottom(HSSFCellStyle.BORDER_THIN); //设置底边框;
                style.setFont(font); //在样式用应用设置的字体;

                return style;
            });
            

            // 通过 ExcelHandle 设置sheet页,并输出到指定目录
            ExcelHandle.builder().setSheet(sheet1).setSheet(sheet2).build("D:\test\files\test.xls");
        }

        public static void main(String[] args) {
            // HandleTimer.runTime() 是用来统计方法耗时的一个工具类
            HandleTimer.runTime(TestMain::execute);
        }
    }


    import com.swotxu.verifyideas.demo02.annotation.ExcelColunm;
    import lombok.Getter;
    import lombok.Setter;

    /**
     * @Date: 2019/12/14 22:47
     * @Author: swotXu
     */
    public class PeopleEntity {
        @Getter
        @Setter
        @ExcelColunm(colunmName = "姓名", order = 20)
        private String name;

        @Getter
        @Setter
        @ExcelColunm(colunmName = "性别", order = 10)
        private String sex;

        @Getter
        @Setter
        @ExcelColunm(colunmName = "年龄", order = 40)
        private int age;

        @Getter
        @Setter
        @ExcelColunm(colunmName = "身份证", order = 30)
        private String idCard;
    }

    上面代码演示生成有两个sheet页的excel。
    sheet1,使用默认样式,开启序号列,结果如下

    sheet2,使用指定样式,关闭序号列,结果如下


    三、代码实现
    咱们先看看类结构图:


    1、@ExcelColunm 注解
    我们先来创建一个 @ExcelColunm 注解,用于标记实体属性上。
    其中:
    colunmName 用于标识实体属性与excel中table表列的映射关系
    order 用于标识excel中table表列的排列顺序

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    /**
     * 此注解标记于实体属性上,用于声明实体转Excel表头的对应关系
     * @Date: 2019/12/14 21:51
     * @Author: swotXu
     */
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    public @interface ExcelColunm {
        /**
         * Excel 列名
         * @return
         */
        String colunmName() default "";

        /**
         * 列排序 由小到大
         * @return
         */
        int order() default 0;
    }

    2、ExcelColunmParse
    接下来,编写解析注解的工具类
    ExcelColunmParse 用于解析实体上的 @ExcelColunm注解

    import com.swotxu.verifyideas.demo02.annotation.ExcelColunm;
    import com.swotxu.verifyideas.demo02.pojo.PeopleEntity;
    import lombok.Getter;
    import lombok.Setter;
    import lombok.extern.slf4j.Slf4j;

    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;

    /**
     * @ExcelColunm 的解析工具
     *
     * @Date: 2019/12/14 21:53
     * @Author: swotXu
     */
    @Slf4j
    public class ExcelColunmParse {
        public static void main(String[] args) {
            List<ParseResult> results = parseExcelColunm(PeopleEntity.class);
            log.info("{}", results);
        }

        /**
         * 解析实体类中 @ExcelColunm
         * @param aClass
         * @return
         */
        public static List<ParseResult> parseExcelColunm(Class<?> aClass){
            return Arrays.stream(aClass.getDeclaredFields())
                    // 类型转换:将 field 对象转换为 ParseResult 对象
                    .map(field -> {
                        if (field.isAnnotationPresent(ExcelColunm.class)) {
                            ExcelColunm excelColunm = field.getAnnotation(ExcelColunm.class);
                            ParseResult parseResult = new ParseResult(field.getName()
                                    , excelColunm.colunmName(), excelColunm.order());
                            return parseResult;
                        }
                        return null;
                    })
                    // 过滤空对象
                    .filter(parseResult -> parseResult != null)
                    // 根据 order 排序
                    .sorted((r1, r2) -> r1.getOrder() - r2.getOrder())
                    .collect(Collectors.toList());
        }
        /**
         * @ExcelColunm 解析后的封装对象
         */
        public static class ParseResult {
            @Getter
            @Setter
            private String sourceKey;

            @Getter
            @Setter
            private String colunmName;

            @Getter
            @Setter
            private int order;

            private ParseResult(String sourceKey, String colunmName, int order) {
                this.sourceKey = sourceKey;
                this.colunmName = colunmName;
                this.order = order;
            }
        }
    }

    3、ExcelSheet
    然后,创建ExcelSheet对象,封装poi对excel的操作

    import lombok.Setter;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.usermodel.HSSFRichTextString;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.ss.util.CellRangeAddress;

    import java.util.List;
    import java.util.Objects;
    import java.util.function.Function;

    /**
     * @Date: 2019/12/15 17:01
     * @Author: swotXu
     */
    @Slf4j
    @SuppressWarnings("deprecation")
    public class ExcelSheet {
        /**开启序号列 默认开启*/
        public static final boolean USE_ORDER_NUMBER = true;
        /**关闭序号列*/
        public static final boolean DEL_ORDER_NUMBER = false;
        public static final String ORDER_NUMBER_NAME = "序号";

        // 是否开启序号列
        private boolean hasOrderNum;
        // 显示的导出表的标题
        private String title;
        // 导出表的列名
        private String[] rowNames;
        // 数据集
        private List<List<Object>> dataList;

        /** 列头单元格样式 */
        @Setter
        private Function<HSSFWorkbook, HSSFCellStyle> headColumnTopStyleFun;
        /** 列数据信息单元格样式 */
        @Setter
        private Function<HSSFWorkbook, HSSFCellStyle> bodyColumnTopStyleFun;

        //构造方法,传入要导出的数据
        public ExcelSheet(String title, String[] rowNames, List<List<Object>> dataList, boolean hasOrderNum){
            this.title = title;
            this.rowNames = rowNames;
            this.dataList = dataList;
            this.hasOrderNum = hasOrderNum;
            this.headColumnTopStyleFun = ExcelSheet::getHeadColumnTopStyle;
            this.bodyColumnTopStyleFun = ExcelSheet::getBodyColumnTopStyle;
        }

        /**
         * 生成excel数据
         * @return
         */
        public HSSFWorkbook createExcel(){
            return createExcel(new HSSFWorkbook());
        }

        /**
         * 生成excel数据
         * @param workbook  创建工作簿对象
         * @return
         */
        public HSSFWorkbook createExcel(HSSFWorkbook workbook){
            try{
                // sheet 单元格样式定义, 表头 和 表数据样式
                HSSFCellStyle headColumnTopStyle = this.headColumnTopStyleFun.apply(workbook);
                HSSFCellStyle bodyColumnTopStyle = this.bodyColumnTopStyleFun.apply(workbook);
                //单元格样式对象
                HSSFSheet sheet = workbook.createSheet(title);    // 创建工作表
                // 产生表格标题行
                setColumnHeadData(sheet, headColumnTopStyle, rowNames.length);
                //将查询出的数据设置到sheet对应的单元格中
                setColumnBodyData(sheet, bodyColumnTopStyle);
                //让列宽随着导出的列长自动适应
                setColumnAutoWidth(sheet, rowNames.length);

                return workbook;
            }catch(Exception e){
                log.warn("Create workbook failed!", e);
            }
            return null;
        }

        /**
         * 生成excel table 表头
         * @param sheet     sheet对象
         * @param headColumnTopStyle    表头样式
         * @param columnNum     列数量
         */
        private void setColumnHeadData(HSSFSheet sheet, HSSFCellStyle headColumnTopStyle, int columnNum){
            // 产生表格标题行
            HSSFRow rowm = sheet.createRow(0);
            HSSFCell cellTiltle = rowm.createCell(0);
            // 设置title
            sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, hasOrderNum?rowNames.length:rowNames.length-1));
            cellTiltle.setCellStyle(headColumnTopStyle);
            cellTiltle.setCellValue(title);

            HSSFRow rowRowName = sheet.createRow(2);  // 在索引2的位置创建行(最顶端的行开始的第二行)
            // 若开启序号,将列头设置到sheet的单元格中
            if(hasOrderNum){
                setSerialNumber(rowRowName, headColumnTopStyle);
            }
            HSSFCell cellRowName;
            for(int n=0; n<columnNum; n++){
                //  创建列头对应个数的单元格  -- 若开启序号列,则 n+1
                cellRowName = rowRowName.createCell(hasOrderNum? n + 1 : n);
                cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING);              //设置列头单元格的数据类型
                cellRowName.setCellValue(new HSSFRichTextString(rowNames[n]));   //设置列头单元格的值
                cellRowName.setCellStyle(headColumnTopStyle);                     //设置列头单元格样式
            }
        }
        /**
         * 将查询出的数据设置到sheet对应的单元格中
         *
         * @param sheet     sheet对象
         * @param bodyColumnTopStyle    数据列样式
         */
        private void setColumnBodyData(HSSFSheet sheet, HSSFCellStyle bodyColumnTopStyle){
            for(int i=0;i<dataList.size();i++){
                List<Object> objList = dataList.get(i);//遍历每个对象
                HSSFRow row = sheet.createRow(i+3);//创建所需的行数

                HSSFCell cell;   //设置单元格的数据类型
                if(hasOrderNum){
                    cell = row.createCell(0, HSSFCell.CELL_TYPE_NUMERIC);
                    cell.setCellValue(i+1);
                    cell.setCellStyle(bodyColumnTopStyle);
                }
                for(int j=0; j < objList.size(); j++){
                    cell = row.createCell(hasOrderNum? j + 1 : j,HSSFCell.CELL_TYPE_STRING);
                    if(!Objects.isNull(objList.get(j))){
                        cell.setCellValue(objList.get(j).toString());                        //设置单元格的值
                    }
                    cell.setCellStyle(bodyColumnTopStyle);                                    //设置单元格样式
                }
            }
        }

        /**
         * 让列宽随着导出的列长自动适应
         * @param sheet     sheet对象
         * @param columnNum 列数量
         */
        private void setColumnAutoWidth(HSSFSheet sheet, int columnNum){
            for (int colNum = 0; colNum < columnNum; colNum++) {
                int columnWidth = sheet.getColumnWidth(colNum) / 256;
                for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
                    HSSFRow currentRow;
                    //当前行未被使用过
                    if (sheet.getRow(rowNum) == null) {
                        currentRow = sheet.createRow(rowNum);
                    } else {
                        currentRow = sheet.getRow(rowNum);
                    }
                    if (currentRow.getCell(colNum) != null) {
                        HSSFCell currentCell = currentRow.getCell(colNum);
                        if (currentCell != null && currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING && currentCell.getStringCellValue() != null) {
                            int length = currentCell.getStringCellValue().getBytes().length;
                            if (columnWidth < length) {
                                columnWidth = length;
                            }
                        }
                    }
                }
                if(colNum == 0){
                    try{
                        columnWidth = (columnWidth-2) * 256;
                    }catch(Exception e){
                        columnWidth = 1024;
                        e.printStackTrace();
                    }
                    sheet.setColumnWidth(colNum, columnWidth);
                }else{
                    try{
                        columnWidth = (columnWidth+4) * 256;
                    }catch(Exception e){
                        columnWidth = 1024;
                        e.printStackTrace();
                    }
                    sheet.setColumnWidth(colNum, columnWidth);
                }
            }
        }

        /**
         * 设置序号列
         * @param rowRowName    行对象
         * @param columnTopStyle    单元格样式对象
         */
        private static void setSerialNumber(HSSFRow rowRowName, HSSFCellStyle columnTopStyle){
            HSSFCell cellRowName = rowRowName.createCell(0);
            cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING);                //设置列头单元格的数据类型
            HSSFRichTextString text = new HSSFRichTextString(ORDER_NUMBER_NAME);
            cellRowName.setCellValue(text);                                    //设置列头单元格的值
            cellRowName.setCellStyle(columnTopStyle);
        }

        /*
         * 默认列头单元格样式
         */
        private static HSSFCellStyle getHeadColumnTopStyle(HSSFWorkbook workbook) {
            // 设置字体
            HSSFFont font = workbook.createFont();
            //设置字体大小
            font.setFontHeightInPoints((short)11);
            //字体加粗
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            //设置字体名字
            font.setFontName("Courier New");
            //设置样式;
            HSSFCellStyle style = workbook.createCellStyle();
            //设置底边框;
            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            //设置底边框颜色;
            style.setBottomBorderColor(HSSFColor.BLACK.index);
            //设置左边框;
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            //设置左边框颜色;
            style.setLeftBorderColor(HSSFColor.BLACK.index);
            //设置右边框;
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            //设置右边框颜色;
            style.setRightBorderColor(HSSFColor.BLACK.index);
            //设置顶边框;
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            //设置顶边框颜色;
            style.setTopBorderColor(HSSFColor.BLACK.index);
            //在样式用应用设置的字体;
            style.setFont(font);
            //设置自动换行;
            style.setWrapText(false);
            //设置水平对齐的样式为居中对齐;
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            //设置垂直对齐的样式为居中对齐;
            style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

            return style;
        }
        /*
         * 默认列数据信息单元格样式
         */
        private static HSSFCellStyle getBodyColumnTopStyle(HSSFWorkbook workbook) {
            // 设置字体
            HSSFFont font = workbook.createFont();
            //设置字体大小
            //font.setFontHeightInPoints((short)10);
            //字体加粗
            //font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            //设置字体名字
            font.setFontName("Courier New");
            //设置样式;
            HSSFCellStyle style = workbook.createCellStyle();
            //设置底边框;
            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            //设置底边框颜色;
            style.setBottomBorderColor(HSSFColor.BLACK.index);
            //设置左边框;
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            //设置左边框颜色;
            style.setLeftBorderColor(HSSFColor.BLACK.index);
            //设置右边框;
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            //设置右边框颜色;
            style.setRightBorderColor(HSSFColor.BLACK.index);
            //设置顶边框;
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            //设置顶边框颜色;
            style.setTopBorderColor(HSSFColor.BLACK.index);
            //在样式用应用设置的字体;
            style.setFont(font);
            //设置自动换行;
            style.setWrapText(false);
            //设置水平对齐的样式为居中对齐;
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            //设置垂直对齐的样式为居中对齐;
            style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
            return style;
        }
    }

    4、ExcelParse2SheetAdapte
    接下来,创建ExcelParse2SheetAdapte,将实体对象集转换为 ExcelSheet对象

    package com.swotxu.verifyideas.demo02.utils;

    import lombok.extern.slf4j.Slf4j;

    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Objects;

    /**
     * @Date: 2019/12/15 23:03
     * @Author: swotXu
     */
    @Slf4j
    public class ExcelParse2SheetAdapte<T> {
        /**
         * excel表头
         */
        private String[] rowsName;
        /**
         * excel数据体
         */
        private List<List<Object>>  dataList;

        public ExcelParse2SheetAdapte(List<T> entityList, Class<T> aClass){
            entity2ExcelSheetAdapte(entityList, aClass);
        }
        /**
         * 实体对象与ExcelSheet适配 生成表头及表单数据
         * @param entityList
         * @param aClass
         */
        private void entity2ExcelSheetAdapte(List<T> entityList, Class<T> aClass){
            List<ExcelColunmParse.ParseResult> parseResults = ExcelColunmParse.parseExcelColunm(aClass);
            // Excel 表头
            String[] rowsName = parseResults.stream().<String>map(result -> result.getColunmName()).toArray(String[]::new);
            // Excel 数据集
            List<List<Object>> dataList = new ArrayList(entityList.size());
            List<Object> datas;
            // 解析数据实体集
            for (T entity : entityList) {
                datas = new ArrayList(rowsName.length);
                // 解析数据实体属性
                for (ExcelColunmParse.ParseResult parseResult : parseResults) {
                    try {
                        Field f = aClass.getDeclaredField(parseResult.getSourceKey());
                        f.setAccessible(true);
                        Object o = f.get(entity);
                        datas.add(Objects.isNull(o)? "" : o);
                    } catch (Exception e) {
                        log.warn("Failed to get entity properties!", e);
                    }
                }
                dataList.add(datas);
            }
            this.rowsName = rowsName;
            this.dataList = dataList;
        }
        /**
         * 获取ExcelSheel对象
         * @param title     生成标题名
         * @param hasOrderNum     是否生成排序号
         * @return
         */
        public ExcelSheet getExcelSheet(String title, boolean hasOrderNum){
            return new ExcelSheet(title, rowsName, dataList, hasOrderNum);
        }
    }

    5、ExcelHandle
    最后,通过工具类ExcelHandle,将 ExcelSheet对象生成excel,输出到指定目标

    package com.swotxu.verifyideas.demo02.utils;

    import com.swotxu.verifyideas.common.file.utils.FileStreamUtil;
    import lombok.Getter;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;

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

    /**
     * @Date: 2019/12/14 23:13
     * @Author: swotXu
     */
    @Slf4j
    public class ExcelHandle {
        @Getter
        private HSSFWorkbook workbook = new HSSFWorkbook();

        private ExcelHandle(){}

        public static ExcelHandle builder(){
            return new ExcelHandle();
        }

        /**
         * 设置 sheet 页
         * @param sheet
         * @return
         */
        public ExcelHandle setSheet(ExcelSheet sheet){
            sheet.createExcel(this.workbook);
            return this;
        }
        /**
         * 导出到指定路径
         * @param path
         */
        public boolean build(String path){
            try {
                FileOutputStream out = new FileOutputStream(new File(path));
                return build(out);
            } catch (FileNotFoundException e) {
                log.warn("Failed to get file stream!", e);
            }
           return false;
        }
        /**
         * 导出到指定输出流
         * @param out
         */
        public boolean build(OutputStream out){
            boolean isOk = false;
            try{
                workbook.write(out);
                out.flush();
                isOk = true;
            } catch (IOException e){
                log.warn("workbook write failure!", e);
            } finally {
                FileStreamUtil.close(out);
            }
            return isOk;
        }
        /**
         * 页面导出下载 Excel
         * @param response
         * @param fileName  无后缀文件名
         */
        public boolean build(HttpServletResponse response, String fileName) {
            boolean isOk = false;
            OutputStream out = null;
            try{
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/vnd.ms-excel");
                response.addHeader(
                        "Content-Disposition",
                        "attachment;filename=" + new String(fileName.getBytes("GBK"), "ISO-8859-1") + ".xls");
                out = response.getOutputStream();
                workbook.write(out);
                out.flush();
                isOk = true;
            } catch (IOException e){
                e.printStackTrace();
            } finally {
                FileStreamUtil.close(out);
            }
            return isOk;
        }
    }

    至此,通过自定义注解 @ExcelColunm 将实体集转为 excel 功能就完成了。
    大家如果有什么疑问,欢迎评论留言!别忘了收藏关注~


    ————————————————
    版权声明:本文为CSDN博主「swotXu」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_39870079/article/details/103754571

  • 相关阅读:
    jquery $(document).ready() 与window.onload的区别
    【Ionic+AngularJS 开发】之『个人日常管理』App(二)
    【Ionic+AngularJS 开发】之『个人日常管理』App(一)
    移动App服务端架构设计
    jQuery 事件用法详解
    CSS实现的几款不错的菜单栏
    css清除浮动的方法总结
    常见浏览器的兼容问题
    推荐两个界面原型设计工具--GUIDesignStudio 和 Mockups For Desktop
    如何用js获取浏览器URL中查询字符串的参数
  • 原文地址:https://www.cnblogs.com/grj001/p/12223038.html
Copyright © 2011-2022 走看看