Easy Excel生成复杂下Excel模板(下拉框)给用户下载

引言

文件的下载是一个非常常见的功能,也有一些非常好的框架可以使用,这里我们就介绍一种比较常见的场景,下载Excel模版,导入功能通常会配有一个模版下载的功能,根据下载的模版,填充数据然后再上传。

需求

如图所示用户下载如下模版,模版中的地区是从数据库中读出来的。

分析

如果模版都是固定的内容,这种比较简单,我们可以直接把模版上传到我们的文件服务器,用户下载的时候可以直接在文件服务器上下载,或者是把文件放到我们的工程里面,直接读取文件然后以流的方式返回给前端,用户直接下载。

这里比较麻烦点的就是这个模版的内容不是固定的,需要在库里查询出来,写到excel然后在返给前端。同时这个文件又有一定的样式,一般有样式的文件,我们可以根据模版填充,而不是把说有的样式都用程序代码写,程序代码写这种样式会很麻烦。所以我们这里用的方式就是填充模版

准备模版

把准备好的模版放到我们工程里面,创建文件夹template 并把文件夹设置为resource,设置为resoucre后该文件夹下面的文件在mvn打包的时候回合我们的java类打在同一个路径下,方便我们获取文件

编写下拉选项的handler

bash 复制代码
public class SelectSheetWriteHandler implements SheetWriteHandler {

    private String[] list;
    private int firstRow;
    private int lastRow;
    private int firstCol;
    private int lastCol;

    public SelectSheetWriteHandler(String[] list, int firstRow, int lastRow, int firstCol, int lastCol) {
        this.list = list;
        this.firstRow = firstRow;
        this.lastRow = lastRow;
        this.firstCol = firstCol;
        this.lastCol = lastCol;
    }

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        // 区间设置 第一列第一行和第二行的数据。由于第一行是头,所以第一、二行的数据实际上是第二三行
        CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();
        DataValidationConstraint constraint = helper.createExplicitListConstraint(list);
        DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
        dataValidation.setShowErrorBox(true);
        writeSheetHolder.getSheet().addValidationData(dataValidation);
    }
}

下载的方法

bash 复制代码
 public void export(HttpServletResponse response) throws IOException {
        //模板文件
        InputStream templateFile = TenantInsuranceFundServiceImpl.class.getResourceAsStream("/五险一金导入模板.xlsx");
        //导出后的文件名
        String fileName =  "五险一金导入模板";
        List<BaseDictionaryVO> baseDictionaryVOS = dictionaryService.queryDictionaryDetail(DictionaryEnum.AREA.getCode(), DictionaryEnum.AREA.getName());
        Set<String> areaNameList = new HashSet<>();
        if(!CollectionUtils.isEmpty(baseDictionaryVOS)){
            areaNameList = baseDictionaryVOS.stream().map(BaseDictionaryVO::getName).collect(Collectors.toSet());
        }
        SelectSheetWriteHandler selectSheetWriteHandler = new SelectSheetWriteHandler(areaNameList.toArray(new String[areaNameList.size()]), 2, 5000, 0, 0);
        //写入
        ExcelWriter excelWriter = null;
        try {
            //流输出
            excelWriter = EasyExcel.write(response.getOutputStream())
                    .withTemplate(templateFile)
                    .registerWriteHandler(selectSheetWriteHandler)
                    .build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            // 直接写入list数据 这里没有数据需要填写直接一个空集合
            excelWriter.fill(Arrays.asList(),  writeSheet);
            //浏览器下载操作
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码
            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            excelWriter.finish();
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("code", "1");
            map.put("message", "下载模板失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        } finally {
            // 千万别忘记关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }
相关推荐
bin915310 小时前
【EXCEL数据处理】000017 案例 Match和Index函数。
excel
shandianchengzi12 小时前
【记录】Excel|Excel 打印成 PDF 页数太多怎么办
pdf·excel
bin915315 小时前
【EXCEL数据处理】000010 案列 EXCEL文本型和常规型转换。使用的软件是微软的Excel操作的。处理数据的目的是让数据更直观的显示出来,方便查看。
大数据·数据库·信息可视化·数据挖掘·数据分析·excel·数据可视化
一个散步者的梦1 天前
Excel常用函数
excel
bin91531 天前
【EXCEL数据处理】000009 案列 EXCEL单元格数字格式。文本型数字格式和常规型数字格式的区别
大数据·前端·数据库·信息可视化·数据分析·excel·数据可视化
Eiceblue2 天前
Python保留数据删除Excel单元格的函数和公式
开发语言·python·excel
bin91532 天前
【EXCEL数据处理】000014 案例 EXCEL分类汇总、定位和创建组。附多个操作案例。
信息可视化·数据挖掘·数据分析·excel·数据可视化·数据图表·excel 数据分析
育种数据分析之放飞自我2 天前
GWAS分析中显著位点如何注释基因:excel???
linux·算法·excel
PowerBI学谦2 天前
Python in Excel 正式发布!
开发语言·python·excel
bin91532 天前
【EXCEL数据处理】000011 案列 EXCEL带有三角形图标的单元格转换,和文本日期格式转换。
大数据·数据库·信息可视化·数据挖掘·数据分析·excel·数据可视化