美文网首页
2022通用poi导出excel,5.x版本

2022通用poi导出excel,5.x版本

作者: 木木呦 | 来源:发表于2021-06-29 12:40 被阅读0次

    功能描述

    数据集即查询出来的List<T>,泛型必须是对象List<对象类>,而不是List<Map<k,v>>
    ①支持多级标题,支持相邻标题名称相同自动合并。
    ②支持导出Excel自定义顺序
    ③支持字段类型为日期,大字段,BigDecimal自定义处理,例如日期格式化等。
    ④支持数据与枚举映射,场景:数据库存储值为数字,展示需要中文
    ⑤支持多个不同数据集导出到同一excel文件中
    ⑥支持若干自定义单元格宽度,序号等,详情实现见注解类【ExportField.java】

    1.效果截图

    普通导出
    普通多级标题String[][] title1 = {{"用户导出"}, {"测试", "测试","数据", "0000", "0000"}, {"分隔符"},{"用户名", "昵称","性别", "价格", "数字"}}; 增强导出
    增强导出

    2.实现思路设计

    常见的导出,有含有标题的,不含有标题的,多级标题的,标题希望合并的
    因此采用二维数组进行标题设计,并且对内容进行计算合并
    作者太懒,暂不想写,先即粘即用。
    

    3.引入依赖

                <dependency>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi</artifactId>
                    <version>5.1.0</version>
                </dependency>
    
                <dependency>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi-ooxml</artifactId>
                    <version>5.1.0</version>
                </dependency>
    
    工程路径自行调整

    4.核心代码

    ①接口:对于外部调用,只需要数据集和对应的字段名

    package com.erhya.admin.service.poi;
    
    import java.util.List;
    
    /**
     * 抽象接口,为扩展poi和jxl等其他导出技术
     */
    public interface ExcelTemplate<T> {
    
        /**
         * 抽象模板方法
         * @param exportList 导出的数据集合
         * @param showFiles 导出字段属性名
         */
        void execute(List<T> exportList, String... showFiles);
    
    }
    
    

    ②接口:数据集中的数字转换为字典值(例如:1对应展示男,0对应展示女)

    package com.erhya.admin.service.poi;
    
    /**
     * 导出功能的枚举字典
     */
    public interface ExportDict {
    
        /**
         * 根据key找到值
         * @param key key==字段值
         */
        String getVal(String key);
    
    }
    
    

    注解类

    package com.erhya.admin.service.poi.annotation;
    
    import com.erhya.admin.service.poi.ExportDict;
    
    import java.lang.annotation.*;
    
    
    /**
     * 导出信息配置注解
     * @author 李林
     * @date 2022-01-22
     */
    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface ExportField {
    
        /**
         * 是否为序号字段
         * 为了应对导出需要从1开始计数,默认不需要
         */
        boolean isNo() default false;
    
        /**
         * 暂时没用,作为标记
         * 单元格顶部标题,当只需要一层标题的时候,仅加入此项配置即可,就不需要传二维数组的标题了
         */
        String fieldName() default "";
    
        /**
         * 默认单元格宽度,256为一个字节宽度
         */
        int width() default 18;
    
        /**
         * 当字段为日期类型时,希望的转换格式
         */
        String dateFormat() default "yyyy-MM-dd HH:mm:ss";
    
        /** 数据字典 */
        Class<? extends ExportDict>[] dict() default {};
    
        int scale() default 2;
    
    }
    
    

    抽象类(反射获取属性值)

    package com.erhya.admin.service.poi;
    
    import com.erhya.admin.service.poi.annotation.ExportField;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.commons.lang3.time.DateFormatUtils;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.math.BigDecimal;
    import java.util.Date;
    
    /**
     * 抽象层-公共方法区
     *
     * @param <T> 数据泛型
     */
    public abstract class AbstractExcelTemplate<T> implements ExcelTemplate<T> {
    
        private Integer scale = 2;
    
        /**
         * 接口默认实现方法,获取反射类字段
         *
         * @param fieldName 字段名
         * @param clazz     反射类
         * @return 字段信息
         */
        protected final Field getField(String fieldName, Class<?> clazz) {
            Field field = null;
            try {
                field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
            return field;
        }
    
        /**
         * 接口默认实现方法,获取反射类字段值
         * @return 字段值
         */
        protected final String getFieldVal(Field field, Object obj, Integer counter) {
            String fieldType = field.getGenericType().getTypeName();
            ExportField fieldAnnotation = field.getAnnotation(ExportField.class);
            if (fieldAnnotation != null) {
                if (fieldAnnotation.isNo()) {
                    return String.valueOf(counter);
                }
            }
    
            String fieldVal = null;
            try {
                Object o = field.get(obj);
                if (o != null) {
                    if (StringUtils.isNotEmpty(fieldType)) {
                      // 预留特殊字段处理,从注解类中获取属性
                        switch (fieldType) {
                            case "java.util.Date":
                                fieldVal = DateFormatUtils.format((Date) o, fieldAnnotation == null ? "yyyy-MM-dd HH:mm:ss" : fieldAnnotation.dateFormat());
                                break;
                            case "java.sql.Clob":
    
                                break;
                            case "java.math.BigDecimal":
                                fieldVal = ((BigDecimal) o).setScale(fieldAnnotation == null ? 2 : fieldAnnotation.scale(), BigDecimal.ROUND_CEILING).toPlainString();
                                break;
                            default:
                                fieldVal = String.valueOf(o);
                        }
                    }
                }
    
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            Class<? extends ExportDict>[] dict = fieldAnnotation.dict();
            if (dict.length > 0) {
                fieldVal = getDictVal(dict[0], fieldVal);
            }
    
            if (StringUtils.isEmpty(fieldVal)) {
                fieldVal = "";
            }
            return fieldVal;
        }
    
        /**
         * 反射-从枚举类中获取对应的字典值
         *
         * @param emum 枚举类
         * @param key  字典(字段)值
         * @return val
         */
        public static <T extends ExportDict> String getDictVal(Class<T> emum, String key) {
            String invoke = null;
            try {
                // getVal为接口类:InterfaceEnum中的方法
                Method method = emum.getDeclaredMethod("getVal", String.class);
                T[] enumConstants = emum.getEnumConstants();
                Object mevoke = method.invoke(enumConstants[0], key);
                if (method != null) {
                    invoke = mevoke.toString();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return invoke;
        }
    }
    
    

    POI实现

    package com.erhya.admin.service.poi;
    
    import com.erhya.admin.service.poi.annotation.ExportField;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.hssf.usermodel.*;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedOutputStream;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * 基于POI实现的模板方法
     * 使用方法: PoiExcelTemplate<对象> poi = PoiExcelTemplate<对象>(若干参数);
     *           poi.execute(参数);
     * @param <T> 数据泛型
     * @author lilin  模板模式 + 泛型 + 反射
     */
    public class PoiExcelTemplate<T> extends AbstractExcelTemplate<T> implements ExecuteChain<T> {
    
        /** excel的文档对象 */
        private HSSFWorkbook workbook;
        /** excel的表单 */
        private HSSFSheet sheet;
        /** excel的表单名称 */
        private String sheetName;
    
        /** 标题 */
        private String[][] title;
        /** 标题中最长的一行 */
        private Integer titleMaxLen;
        /** 标题栏的合并列 */
        private List<CellRangeAddress> shellMerge;
        /** 默认单元格宽度 */
        private static final Integer DEFAULT_WIDTH = 18;
    
        /** 导出文件名 */
        private String fileName;
        /** 标题栏 样式 */
        private CellStyle titleStyle;
        /** 数据栏 样式 */
        private CellStyle dataStyle;
    
        /** 列表数据 */
        private List<T> data;
        /** 列表数据展示字段 */
        private String[] showFiles;
        /** 当前数据行(标题行数+已写入数据行) */
        private Integer startIndex;
        /** 序号计数器 */
        private AtomicInteger center;
    
        private HttpServletResponse response;
    
        public PoiExcelTemplate(String fileName, String[][] title, String sheetName, HttpServletResponse response) {
            this.fileName = fileName;
            this.title = title;
            this.sheetName = sheetName;
            this.response = response;
        }
    
        /**
         * 初始化方法
         * @param workbook 工作簿对象
         */
        private void init(HSSFWorkbook workbook){
    
            if (workbook == null){
                workbook = new HSSFWorkbook();
            }
    
            this.workbook = workbook;
            this.titleStyle = buildTitleStyle();
    
            if (StringUtils.isEmpty(sheetName)){
                sheetName = "Sheet";
            }
    
            this.sheet = workbook.createSheet(sheetName);
    
            this.shellMerge = new ArrayList<>();
            this.center = new AtomicInteger(0);
            this.startIndex = this.title == null ? 0 : this.title.length;
            this.dataStyle = buildColumStyle();
        }
    
        @Override
        public void execute(List<T> list, String... showFiles){
            init(workbook);
            titleInit();
            this.dataStyle = buildColumStyle();
            buildList(list, showFiles);
            exportList();
        }
    
        @Override
        public void unExecute(List<T> list, String... showFiles){
            this.data = list;
            this.showFiles = showFiles;
        }
    
        @Override
        public void china(String fileName, Boolean flag){
            if (StringUtils.isNotEmpty(fileName)){
                this.fileName = fileName;
            }
            init(workbook);
            titleInit();
            this.dataStyle = buildColumStyle();
            buildList(data, showFiles);
            if (!flag){
                exportList();
            }
        }
    
        private void titleInit(){
            if (this.title == null || this.title.length == 0){
                return;
            }
    
            if (titleMaxLen == null){
                titleMaxLen = 0;
            }
    
            // 计算最长的一行
            for (String[] t1 : title) {
                int length = t1.length;
                titleMaxLen = Math.max(length, titleMaxLen);
            }
    
            initMergeTitle();
    
            for (CellRangeAddress cellAddresses : shellMerge) {
                sheet.addMergedRegion(cellAddresses);
            }
    
        }
    
        private void initMergeTitle(){
            String tag = null;
            for (int i = 0; i < title.length; i++) {
                HSSFRow row = sheet.createRow(i);
                String[] t2 = title[i];
                if (t2.length == 1){
                    HSSFCell cell = row.createCell(0);
                    cell.setCellStyle(this.titleStyle);
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(t2[0]);
                    shellMerge.add(new CellRangeAddress(i, i, 0, titleMaxLen-1));
                } else {
                    Integer mergeCell = 0;
                    for (int j = 0; j < t2.length; j++) {
                        HSSFCell cell = row.createCell(j);
                        String cell2 = t2[j];
                        if (tag == null || j == 0){
                            tag = cell2;
                        }
    
                        cell.setCellStyle(this.titleStyle);
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(cell2);
    
                        if (tag.equals(cell2)){
                            mergeCell++;
                        } else {
                            if (mergeCell > 1){
                                shellMerge.add(new CellRangeAddress(i, i, j-mergeCell, j-1));
                            }
                            tag = cell2;
                            mergeCell = 1;
                        }
    
                        // 最后一行合并方式和其他不一样
                        if (j == t2.length-1 && tag.equals(cell2)){
                            if (mergeCell > 1){
                                shellMerge.add(new CellRangeAddress(i, i, j-mergeCell+1, j));
                            }
                        }
                    }
                }
            }
        }
    
        protected void buildList(List<T> list, String... showFiles){
            for (T t : list) {
                Class<?> clazz = t.getClass();
                HSSFRow row = this.sheet.createRow(startIndex);
                int i = 0;
                int num =  this.center.addAndGet(1);
    
                for (String showFile : showFiles) {
                    int width = DEFAULT_WIDTH;
                    Field field = getField(showFile, clazz);
                    String fieldVal = getFieldVal(field, t, num);
    
                    ExportField fieldAnnotation = field.getAnnotation(ExportField.class);
                    if (fieldAnnotation != null){
                        width = fieldAnnotation.width();
                    }
    
                    HSSFCell cell = row.createCell(i);
                    this.sheet.setColumnWidth(i, width * 256);
                    cell.setCellStyle(dataStyle);
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(fieldVal);
                    i++;
                }
                startIndex++;
            }
        }
    
        /**
         * 可重写的标题样式
         */
        protected HSSFCellStyle buildTitleStyle(){
            HSSFCellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直对齐
            cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle.setBorderLeft(BorderStyle.THIN); //左边框
            cellStyle.setBorderRight(BorderStyle.THIN); //右边框
            cellStyle.setBorderTop(BorderStyle.THIN); //上边
            cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); //背景色
            cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            HSSFFont headerFont = (HSSFFont) workbook.createFont(); // 创建字体样式
            headerFont.setBold(true); //字体加粗
            headerFont.setFontName("仿宋"); // 设置字体类型
            headerFont.setFontHeightInPoints((short) 12); // 设置字体大小
            cellStyle.setFont(headerFont); // 为标题样式设置字体样式
            return cellStyle;
        }
    
        /**
         * 可重写的单元格样式
         */
        protected HSSFCellStyle buildColumStyle(){
            HSSFCellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(HorizontalAlignment.LEFT);//水平居中
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直对齐
            cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle.setBorderLeft(BorderStyle.THIN); //左边框
            cellStyle.setBorderRight(BorderStyle.THIN); //右边框
            cellStyle.setBorderTop(BorderStyle.THIN); //上边
            HSSFFont headerFont = (HSSFFont) workbook.createFont(); // 创建字体样式
            headerFont.setBold(false); //字体加粗
            headerFont.setFontName("仿宋"); // 设置字体类型
            headerFont.setFontHeightInPoints((short) 11); // 设置字体大小
            cellStyle.setFont(headerFont); // 为标题样式设置字体样式
            return cellStyle;
        }
    
        private void exportList(){
            response.reset();
            response.setContentType("text/html;charset=utf-8");
            try {
                response.setHeader("Content-disposition", "attachment; filename="+ new String((fileName).getBytes("gbk"),"iso8859-1") +".xls");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            BufferedOutputStream bufferedOutPut = null;
            ServletOutputStream output = null;
            try {
                output = response.getOutputStream();
                bufferedOutPut = new BufferedOutputStream(output);
                bufferedOutPut.flush();
                workbook.write(bufferedOutPut);
            } catch (IOException e){
                e.printStackTrace();
            } finally{
                if (bufferedOutPut != null){
                    try {
                        bufferedOutPut.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                if (output != null){
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        public HSSFWorkbook getWorkbook() {
            return workbook;
        }
    
        public void setWorkbook(HSSFWorkbook workbook) {
            this.workbook = workbook;
        }
    }
    
    

    以下为增强处理,可不引入(多个数据集导出到同一Excel文件中)

    ③接口:导出增强

    package com.erhya.admin.service.poi;
    
    import java.util.List;
    
    /**
     * Excel增强处理-链式处理
     * 责任链模式
     * @param <T> 泛型
     */
    public interface ExecuteChain<T> {
    
        /**
         * 设置数据集和展示字段
         * @param list 数据集
         * @param showFiles 展示字段
         */
        void unExecute(List<T> list, String... showFiles);
    
        /**
         * 执行链方法
         * @param fileName 文件名
         * @param flag 标识:是否含有下一个链
         */
        void china(String fileName, Boolean flag);
    
    }
    
    
    package com.erhya.admin.service.poi.chain;
    
    /**
     * 导出链
     */
    public class ExcelExecuteChain {
    
        /** 文件名 */
        private String fileName;
        /** 头节点 */
        private ExcelChina head;
        /** 下一节点 */
        private ExcelChina next;
    
        public ExcelExecuteChain(String fileName) {
            this.fileName = fileName;
        }
    
        /**
         * 添加链条
         * @param excelChain 链条对象
         */
        public void addChain(ExcelChina excelChain){
    
            excelChain.setSuccessor(null);
    
            // 首次设置头节点
            if (head == null){
                this.head = excelChain;
                this.next = excelChain;
                return;
            }
    
            this.next.setSuccessor(excelChain);
            this.next = excelChain;
        }
    
        /**
         * 执行链条
         */
        public void executeChain(){
            if (this.head != null){
                try {
                    this.head.execute(fileName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    
    package com.erhya.admin.service.poi.chain;
    
    import lombok.Data;
    
    @Data
    public abstract class ExcelChina<T> {
    
        protected ExcelChina successor;
        protected Object workBook;
    
        public abstract void execute(String fileName) throws Exception;
    }
    
    package com.erhya.admin.service.poi.chain.poi;
    
    import com.erhya.admin.service.poi.PoiExcelTemplate;
    import com.erhya.admin.service.poi.chain.ExcelChina;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    
    public class PoiNewSheetExcelExecute<T> extends ExcelChina<T> {
    
        private PoiExcelTemplate<T> excelTemplate;
    
        public PoiNewSheetExcelExecute(PoiExcelTemplate<T> excelTemplate) {
            this.excelTemplate = excelTemplate;
        }
    
        @Override
        public void execute(String fileName) throws Exception{
            HSSFWorkbook workbook = excelTemplate.getWorkbook();
            if (workbook == null && super.workBook == null){
                workbook = new HSSFWorkbook();
                super.workBook = workbook;
            }
    
            excelTemplate.setWorkbook((HSSFWorkbook) workBook);
    
            if (successor != null ){
    
                excelTemplate.setWorkbook((HSSFWorkbook) workBook);
                excelTemplate.china(fileName, true);
    
                successor.setWorkBook(super.workBook);
                successor.execute(fileName);
                return;
            }
    
            excelTemplate.china(fileName, false);
    
        }
    
    }
    
    

    使用方法

    普通导出
    1.返回数据集合List
    2. PoiExcelTemplate<User> template = new PoiExcelTemplate<>("文件名", 二维数据标题, "sheet名", response);
    3.调用方法;template.execute(users, "展示属性1", "展示属性2", "展示属性3"...);
    
    

    示例

    新建测试类

    package com.erhya.admin.dto;
    
    import com.erhya.admin.service.poi.annotation.ExportField;
    import com.erhya.admin.service.poi.enums.ExportEnum;
    import lombok.Data;
    
    import java.math.BigDecimal;
    
    /**
     * @Author: lilin
     * @Date: 2022/4/16
     */
    @Data
    public class User {
    
        @ExportField(width = 18)
        private String userName;
    
        @ExportField(width = 18)
        private String nick;
    
        @ExportField(width = 18, dict = ExportEnum.class)
        private String sex;
    
        @ExportField(width = 18)
        private BigDecimal doub;
    
        @ExportField(width = 22)
        private BigDecimal font;
    }
    
    
    package com.erhya.admin.dto;
    
    import com.erhya.admin.service.poi.annotation.ExportField;
    import lombok.Data;
    
    /**
     * @Author: lilin
     * @Date: 2022/4/16
     */
    @Data
    public class Car {
    
        @ExportField(isNo = true, width = 60)
        private String no;
    
        @ExportField(width = 18)
        private String name;
    
        @ExportField(width = 30)
        private String price;
    
    }
    
    package com.erhya.admin.service.poi.enums;
    
    import com.erhya.admin.service.poi.ExportDict;
    
    public enum ExportEnum implements ExportDict {
        A("1", "男的"),
        C("0", "女的");
    
        private String key;
        private String value;
    
        ExportEnum(String key, String value) {
            this.key = key;
            this.value = value;
        }
    
        @Override
        public String getVal(String key) {
            ExportEnum[] values = ExportEnum.values();
            for (ExportEnum value : values) {
                if (value.key.equals(key)) {
                    return value.value;
                }
            }
            return "其他";
        }
    }
    
    

    ①常用版(查询数据,导出)

    @GetMapping("/poi2")
        public void poi(HttpServletResponse response) {
            List<User> users = new ArrayList<>(3);
            User user1 = new User();
            User user2 = new User();
            User user3 = new User();
    
            user1.setUserName("小明");
            user2.setUserName("小红");
            user3.setUserName("小华");
    
            user1.setSex("1");
            user2.setSex("0");
            user3.setSex("奥利给");
    
            user1.setNick("小明");
            user2.setNick("小红");
            user3.setNick("小华");
    
            user1.setDoub(new BigDecimal("999999999.25"));
            user2.setDoub(new BigDecimal("5566998899.55"));
            user3.setDoub(new BigDecimal("100.10"));
    
            users.add(user1);
            users.add(user2);
            users.add(user3);
    
            String[][] title1 = {{"用户导出"}, {"用户名", "昵称","性别", "价格", "数字"}};
    
            PoiExcelTemplate<User> template = new PoiExcelTemplate<>("文件名", title1, "shell", response);
            template.execute(users, "userName", "nick", "sex", "doub", "font");
    
        }
    

    ②增强版(多数据集导出到同一Excel)

    @GetMapping("/poi")
        public void poi(HttpServletResponse response) {
            List<User> users = new ArrayList<>(3);
            User user1 = new User();
            User user2 = new User();
            User user3 = new User();
    
            user1.setUserName("小明");
            user2.setUserName("小红");
            user3.setUserName("小华");
    
            user1.setSex("男");
            user2.setSex("女");
            user3.setSex("女3");
    
            user1.setNick("小明");
            user2.setNick("小红");
            user3.setNick("小华");
    
            user1.setDoub(new BigDecimal(999999999.25));
            user2.setDoub(new BigDecimal(5566998899.55));
            user3.setDoub(new BigDecimal(100.10));
    //        user3.setFont(new BigDecimal(987654321000L));
    
            users.add(user1);
            users.add(user2);
            users.add(user3);
    
            List<Car> cars = new ArrayList<>();
    
            Car car1 = new Car();
            Car car2 = new Car();
            Car car3 = new Car();
            Car car4 = new Car();
    
            car1.setName("兰博基尼");
            car2.setName("奥迪");
            car3.setName("宇通客车");
            car4.setName("玛莎拉蒂");
    
            car1.setPrice("5000");
            car2.setPrice("6000");
            car3.setPrice("1000");
            car4.setPrice("2000");
    
            cars.add(car1);
            cars.add(car2);
            cars.add(car3);
            cars.add(car4);
    
            ExcelExecuteChain chain = new ExcelExecuteChain("小米");
    
            String[][] title1 = {{"用户导出"}, {"用户名", "昵称","性别", "价格", "数字"}};
            String[][] title2 = {{"小汽车导出"}, {"名称", "价格"}};
    
            PoiExcelTemplate<User> template = new PoiExcelTemplate<>("文件名", title1, "shell", response);
            template.unExecute(users, "userName", "nick", "sex", "doub", "font");
    
            PoiExcelTemplate<Car> template2 = new PoiExcelTemplate<>("文件名", title2, "shell2", response);
            template2.unExecute(cars,"price","price");
    
            PoiExcelTemplate<Car> template3 = new PoiExcelTemplate<>("文件名", title2, "shell3", response);
            template3.unExecute(cars,"name","price");
    
            PoiNewSheetExcelExecute<User> chainA = new PoiNewSheetExcelExecute<>(template);
            chain.addChain(chainA);
    
            PoiNewSheetExcelExecute<Car> chainB = new PoiNewSheetExcelExecute<>(template2);
            chain.addChain(chainB);
    
            PoiNewSheetExcelExecute<Car> chainC = new PoiNewSheetExcelExecute<>(template3);
            chain.addChain(chainC);
    
            chain.executeChain();
    
        }
    

    PS:由于有些类或抽象结构是后加的,所以结构上可能有不合理之处,勿喷。

    嫌复制粘贴麻烦的,联系作者提供完整版压缩包,希望实现JXL的,也可联系。本文没有放JXL的实现。

    相关文章

      网友评论

          本文标题:2022通用poi导出excel,5.x版本

          本文链接:https://www.haomeiwen.com/subject/cknhultx.html