EasyExcel生成exl文档,某列有下拉框、坐标超链接

实现功能:EasyExcel生成exl文档,可根据自己需求 设置样式等(本文为:一列可以有下拉框,某个坐标点击可超链接)

一、引入jar包

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.1</version>
</dependency>

二、测试数据

1)对象类:

1、@ColumnWidth(20) 为导出表格的列宽度
2、@ExcelProperty(“日期标题”) 为导出表格的头

/**
 * @author: chenjiaxiang
 * @create: 2022/10/18 16:28
 **/
@Getter
@Setter
@EqualsAndHashCode
public class DemoData {

    @ExcelProperty("字符串标题")
    @ColumnWidth(20)
    private String string;

    @ExcelProperty("日期标题")
    @ColumnWidth(20)
    private String date;
    @ExcelProperty("数字标题")
    @ColumnWidth(20)
    private String doubleData;

    @ExcelProperty({"合并表头","秃驴1"})
    @ColumnWidth(20)
    private String hebing1;
    @ExcelProperty({"合并表头","秃驴2"})
    @ColumnWidth(20)
    private String hebing2;
    @ExcelProperty({"合并表头","秃驴3"})
    @ColumnWidth(20)
    private String hebing3;

    /**
     * 忽略这个字段
     */
    @ExcelIgnore
    private String ignore;
}

2)调用事例:

//main测试,直接导入到本地的
public class EasyExcelCon {

    private static final String PATH = "/Users/chenjx/Downloads/zipceshi/ceshiwenjian/";

    public static void main(String[] args) {
        String fileName = String.format("%s%s.xlsx", PATH, UUID.randomUUID());
        List<DemoData> list = new ArrayList<>();
        DemoData demoData = new DemoData();
        demoData.setString("测试1");
        demoData.setDoubleData("测试2");
        demoData.setDate("测试3");
        demoData.setHebing1("秃驴1");
        demoData.setHebing2("秃驴2");
        demoData.setHebing3("秃驴3");
        DemoData demoData1 = new DemoData();
        demoData1.setString("测试12");
        demoData1.setDoubleData("测试22");
        demoData1.setDate("测试32");
        demoData1.setHebing1("秃驴11");
        demoData1.setHebing2("秃驴21");
        demoData1.setHebing3("秃驴31");
        DemoData demoData2 = new DemoData();
        demoData2.setString("测试13");
        demoData2.setDoubleData("测试23");
        demoData2.setDate("测试33");
        demoData2.setHebing1("秃驴12");
        demoData2.setHebing2("秃驴22");
        demoData2.setHebing3("秃驴32");
        list.add(demoData);
        list.add(demoData1);
        list.add(demoData2);
        EasyExcelStyleUtils.customHandlerWrite(list, DemoData.class, fileName);
    }
}

三、实现工具类,工具类中有具体注释可理解

注意:createExl()方法 为自己设置的样式方法 并不固定

/**
 * @author: chenjiaxiang
 * @create: 2022/10/18 16:21
 **/
@Slf4j
public class EasyExcelStyleUtils {

    /**
     * 生成exl文档 保存至本地
     *
     * @param tList    数据集合
     * @param t        映射对象
     * @param fileName 文件保存路径及文件名称
     * @param <T>      范型
     */
    public static <T> void customHandlerWrite(List<T> tList, Class<T> t, String fileName) {
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        EasyExcelFactory.write(fileName, t)
                //文件样式
                .registerWriteHandler(new CustomSheetWriteHandler())
                .registerWriteHandler(new CustomSheetWriteHandler1())
                .registerWriteHandler(new CustomCellWriteHandler())
                .sheet("sheet").doWrite(tList);
    }


    /**
     * 直接get请求下载excel
     *
     * @param tClass  对象
     * @param tList   数据集合
     * @param name    文件名称-只是名称
     * @param integer 判断样式字符,可自己去设置样式在 chooseStyle() 方法中
     */
    public <T> void customHandlerWrite(Class<T> tClass, List<T> tList, String name, HttpServletResponse response, Integer integer) {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyExcel没有关系
        String fileName = null;
        try {
            fileName = URLEncoder.encode(name, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            //根据传输的integer选择自己需要的样式,样式按照自己需求来写
            chooseStyle(tClass, tList, response, integer);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 创建exl及获取exl的InputStream流 仅做事例
     *
     * @param tList   数据集合
     * @param t       对象
     * @param integer 判断样式字符,可按需求设置样式,在createExl()方法中
     * @return 流
     */
    public static <T> InputStream customHandlerWrite(List<T> tList, Class<T> t, Integer integer) {
        ExcelWriter exl;
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        OutputStream outputStream = new ByteArrayOutputStream();
        try {
            //模版方法,按需求创建exl格式及创建exl
            exl = createExl(tList, t, os, outputStream, integer);
            //将创建的exl转为输入流
            return downLoadStr(tList, exl, os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
                outputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    /**
     * 下载exl 可根据自己的需求样式来判断更改
     *
     * @param tClass  对象
     * @param tList   数据集合
     * @param integer 判断
     */
    private static <T> void chooseStyle(Class<T> tClass, List<T> tList, HttpServletResponse response, Integer integer) {
        try {
            if (integer == 0) {
                EasyExcel.write(response.getOutputStream(), tClass)
                        //文件样式
                        .registerWriteHandler(new CustomSheetWriteHandler())
                        .registerWriteHandler(new CustomSheetWriteHandler1())
                        .sheet("模板").doWrite(tList);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 生成的exl文件转为InputStream流
     *
     * @param list        数据集合
     * @param excelWriter exl
     * @param os          输出流
     * @return 流
     */
    public static <T> InputStream downLoadStr(List<T> list, ExcelWriter excelWriter, ByteArrayOutputStream os) {
        // 单个sheet的容量
        List<? extends List<?>> lists = splitList(list, 1000);
        //转换流
        ExcelWriterSheetBuilder excelWriterSheetBuilder;
        WriteSheet writeSheet;
        for (int i = 1; i <= lists.size(); ++i) {
            excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
            excelWriterSheetBuilder.sheetNo(i).sheetName("sheet" + i);
            writeSheet = excelWriterSheetBuilder.build();
            excelWriter.write(lists.get(i - 1), writeSheet);
        }
        // 必须要finish才会写入,不finish只会创建empty的文件
        excelWriter.finish();
        byte[] content = os.toByteArray();
        // 返回流文件
        return new ByteArrayInputStream(content);
    }


    /**
     * 创建exl文件,按照自己的需求创建exl格式
     *
     * @param list         数据集合
     * @param clazz        对象
     * @param os           字节流
     * @param outputStream 输出流
     * @param integer      判断样式
     * @return exl
     */
    private static <T> ExcelWriter createExl(List<T> list, Class<T> clazz, ByteArrayOutputStream os, OutputStream outputStream, Integer integer) {
        ExcelWriter excelWriter = null;
        if (integer == 0) {
            // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
            EasyExcelFactory.write(outputStream, clazz)
                    .registerWriteHandler(new CustomSheetWriteHandler())
                    .registerWriteHandler(new CustomSheetWriteHandler1())
                    .sheet("sheet").doWrite(list);
            //浏览器访问url直接下载文件的方式
            excelWriter = EasyExcelFactory.write(os, clazz)
                    .registerWriteHandler(new CustomSheetWriteHandler())
                    .registerWriteHandler(new CustomSheetWriteHandler1())
                    .build();
        }
        return excelWriter;
    }

    /**
     * 自定义拦截器.对第一列第一行和第二行的数据新增下拉框,显示 我试试 我试试啊
     */
    @Slf4j
    public static class CustomSheetWriteHandler implements SheetWriteHandler {
        @Override
        public void afterSheetCreate(SheetWriteHandlerContext context) {
            log.info("第{}个Sheet写入成功。", context.getWriteSheetHolder().getSheetNo());
            // 区间设置 给第一列的 第一行到第9行 加下拉框
            CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 9, 0, 0);
            DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper();
            DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[]{"我试试", "我试试啊"});
            DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
            context.getWriteSheetHolder().getSheet().addValidationData(dataValidation);
        }

    }

    /**
     * 自定义拦截器.对第一列第一行和第二行的数据新增下拉框,显示 我试试 我试试啊
     */
    @Slf4j
    public static class CustomSheetWriteHandler1 implements SheetWriteHandler {
        @Override
        public void afterSheetCreate(SheetWriteHandlerContext context) {
            log.info("第{}个Sheet写入成功。", context.getWriteSheetHolder().getSheetNo());
            // 区间设置 给第2、3列的 第2行到100行加下拉框
            CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(2, 100, 2, 3);
            DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper();
            DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[]{"我试试1111", "我试试2222啊"});
            DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
            context.getWriteSheetHolder().getSheet().addValidationData(dataValidation);
        }

    }

    /**
     * 自定义拦截器,给表头或者 规定的 坐标加超链接,双击进入
     */
    public static class CustomCellWriteHandler implements CellWriteHandler {
        @Override
        public void afterCellDispose(CellWriteHandlerContext context) {
            Cell cell = context.getCell();
            // 这里可以对cell进行任何操作
            log.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex());
            //BooleanUtils.isTrue(context.getHead()) &&  为 给请求头加超链接且 必须是第3行第2列
            if (BooleanUtils.isTrue(context.getHead()) && cell.getColumnIndex() == 2 && cell.getRowIndex() == 3) {
                CreationHelper createHelper = context.getWriteSheetHolder().getSheet().getWorkbook().getCreationHelper();
                Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL);
                hyperlink.setAddress("https://www.baidu.com");
                cell.setHyperlink(hyperlink);
            }
        }

    }

四、导出效果

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C__jx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值