利用esaypoi自定义Excel表格模板导入与导出表单数据

🎈个人公众号:🎈 :✨✨ 可为编程 ✨✨ 🍟🍟
🔑个人信条:🔑 知足知不足 有为有不为 为与不为皆为可为🌵
🍉本篇简介:🍉 本片详细说明了利用esaypoi自定义Excel表格模板导入与导出表单数据使用规则和注意要点,并给出具体操作实例,如有出入还望指正。

关注公众号【可为编程】回复【面试】领取最新面试题!!!

今天工作中又遇到了excel导出数据的功能,在这里我将自己自定义的Excel模板和相关的代码拿出来,解释一下如何进行操作,以便日后能够方便的进行功能开发,提高效率。

导出表单数据

一、引入maven依赖
  <!-- easypoi的支持 -->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.2.0</version>
        </dependency>
二、编写业务逻辑代码
package com.platform.modules.yc.service.impl;

import cn.afterturn.easypoi.cache.manager.FileLoaderImpl;
import cn.afterturn.easypoi.cache.manager.POICacheManager;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.view.EasypoiTemplateExcelView;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.platform.modules.yc.dao.Dao;
import com.platform.modules.yc.entity.Entity;
import com.platform.modules.yc.service.ExcelService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author :zjc
 * @ProjectName: platform-plus
 * @Package: com.platform.modules.yc.service.impl
 * @ClassName: ExcelServiceImpl
 * @date :Created in 2021/4/12 15:48
 * @description:excel导出
 * @modified By:
 * @version: 1.0.0$
 * **关注公众号【可为编程】回复【面试】领取最新面试题!!!**
 */
@Service("ExcelService")
public class ExcelServiceImpl implements ExcelService {

    private void setRegionStyle(Sheet sheet, CellRangeAddress region, CellStyle cs) {
        for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
            Row row = CellUtil.getRow(i, sheet);
            for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
                Cell cell = CellUtil.getCell(row, (short) j);
                cell.setCellStyle(cs);
            }
        }
    }

    private void addMergeRow(Sheet sheet, int rowIndex, String content, CellStyle cellStyle) {
        cellStyle.setLeftBorderColor((short) 8);
        cellStyle.setRightBorderColor((short) 8);
        cellStyle.setTopBorderColor((short) 8);
        cellStyle.setBottomBorderColor((short) 8);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        Row newRow = sheet.createRow(rowIndex);
        newRow.setHeight((short) 955);
        Cell cell = newRow.createCell(0);
        cell.setCellValue(content);
        cell.setCellStyle(cellStyle);
        int lastCellNum = 55;
        for (int i = 1; i < lastCellNum; i++) {
            newRow.createCell(i).setCellStyle(cellStyle);
        }
        // 合并单元格
        CellRangeAddress cellAddresses = new CellRangeAddress(rowIndex, rowIndex, 0, lastCellNum);
        sheet.addMergedRegion(cellAddresses);
        setRegionStyle(sheet, cellAddresses, cellStyle);
    }


    @Override
    public void remoteSensAmountExcel(List<Entity> params,HttpServletRequest request, HttpServletResponse response) {

//      String type = (String)params.getMap().getOrDefault("type", ExcelType.XSSF.name());
        String sheetName = "数量查询";// (String)params.getMap().getOrDefault("sheetName", "SheetName");
        String fileName = "数量查询.xls";
        Map<String, Object> excelValue = new HashMap<String, Object>();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        excelValue.put("title", "数量查询");
        excelValue.put("siteName", "监测系统");
        excelValue.put("date", LocalDate.parse(dtf.format(LocalDate.now()), dtf));

        List<Map<String, Object>> valList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> valListData = new ArrayList<>();
        Map<String, Object> mapv = new HashMap<>();
        Entity mapvalue = new Entity();
        int rowIndex = 5;
        for (int i = 0; i < params.size(); i++) {
            mapvalue = params.get(i);
            mapv = new HashMap<>();
            mapv.put("id", mapvalue.getId());
            mapv.put("tstime", simpleDateFormat.format(mapvalue.getTstime()));
            mapv.put("ycz", "xxx");
            mapv.put("cphm", mapvalue.getHphm());
            mapv.put("cdh", mapvalue.getCdxh());

            mapv.put("cpys", mapvalue.getCpys());
            mapv.put("rlzl", mapvalue.getRlzl());
            mapv.put("pdjg", mapvalue.getJudge());

            mapv.put("cojg", mapvalue.getCojg());
            mapv.put("co2jg", mapvalue.getCo2jg());
            mapv.put("hcjg", mapvalue.getHcjg());
            mapv.put("nojg", mapvalue.getNojg());
            valListData.add(mapv);
            rowIndex++;
        }
        excelValue.put("valList", valListData);
        //excelValue.put("valList", valList);
        // 模板路径
        String templateFile = ExcelServiceImpl.class.getClassLoader().getResource("doc/hour001.xls").getPath();
        TemplateExportParams exportTemplateParams = new TemplateExportParams(
                templateFile, sheetName);
        exportTemplateParams.setColForEach(true);
        POICacheManager.setFileLoader(new FileLoaderImpl());

   /*
	采用另一种导出方式  注意模板格式和导出的文件格式为xlsx
 Map<String, Object> map = new HashMap<>(5);
 //关注公众号【可为编程】回复【面试】领取最新面试题!!!
        map.put("map", excelValue);
        map.put(NormalExcelConstants.PARAMS, exportTemplateParams);
        map.put(NormalExcelConstants.FILE_NAME, fileName);
        PoiBaseView.render(map, request, response, "easypoiTemplateExcelView");*/
        
        Workbook book = ExcelExportUtil.exportExcel(exportTemplateParams, excelValue);
        Sheet sheet = book.getSheetAt(0);
        Row head = sheet.getRow(1);
        Cell headOne = head.getCell(0);
        CellStyle cellStyle = headOne.getCellStyle();
        //以下代码是自定义单元格所显示的样式设置
        String content="上传数据总数:15            缺失数据总数:2            数据完整率86.67%\t";
        addMergeRow(sheet, rowIndex, content, cellStyle);
        rowIndex++;
        content="制表人:                   审核人:                   审核时间:       ";
        addMergeRow( sheet, rowIndex, content, cellStyle);

        /*
        以下该部分代码将文件路径指定到了本地磁盘
        FileOutputStream fos = new FileOutputStream("D:\\down-info\\easypoi-test\\src\\test\\resources\\doc\\bb.xls");
        book.write(fos);
        fos.close();*/


        /*
         *以下该代码可以采用postman或者是直接在浏览器请求,直接以一个文件的形式下载下来
         * */
        EasypoiTemplateExcelView easypoiTemplateExcelView = new EasypoiTemplateExcelView();
        try {
            easypoiTemplateExcelView.out(
                    book, fileName, request, response
            );
        } catch (Exception ex) {

        }
    }
}

三、写适合自己的模板

因为指定的模板路径为实现类文件夹下,所以在实现类所对应模块的resources文件夹里新建了一个doc,然后里面放我们的模板。模板的定义如下:
在这里插入图片描述
一定要注意红色标出来的花括号,否则显示不出来对应的数据值。

四、 打jar包后找不到导出模板的解决方法

Jar包导出无法读取Excel模板,在本地运行可以,但是到了服务器就会报workbook的空指针异常。
主要原因有两点:

1.Linux和Window文件系统环境不一致。
2.springBoot项目打jar包后文件资源加载方式不同,打包后Spring试图访问文件系统路径,但无法访问jar中的路径。

解决方案如下:
关注公众号【可为编程】回复【面试】领取最新面试题!!!

采用 resource.getInputStream() 获取模板的文档流,重写到tomcat容器中并生成新的模板路径,按新的路径,导出excel即可。

 //Workbook book = ExcelExportUtil.exportExcel(exportTemplateParams, excelValue);
 //改成如下:
  String templateFile = ExcelExportUtils.convertTemplatePath("doc/hour001.xls");
//InputStream templateFile = EmergencyMaterialInputServiceImpl.class.getClassLoader().getResourceAsStream("doc/hour001.xls");
 TemplateExportParams exportTemplateParams = new TemplateExportParams(
                templateFile, sheetName);
 exportTemplateParams.setColForEach(true);
 POICacheManager.setFileLoader(new FileLoaderImpl());
 Workbook book = ExcelExportUtil.exportExcel(exportTemplateParams, excelValue);

附代码:


import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @Author zjc
 * @Description Excel导出方法
 */
@Component
public class ExcelExportUtils {
    /**
     * 模板路径处理,避免出现NPE
     * windows和linux系统不同,且SpringBoot的文件加载方式已有不同,不能简单的使用相对路径
     *
     * @param path excel模板的相对路径
     * @return 重写后的模板路径
     */
    public static String convertTemplatePath(String path) {
        // 如果是windows则直接返回
        if (System.getProperties().getProperty("os.name").contains("Windows")) {
            return path;
        }

        Resource resource = new ClassPathResource(path);
        FileOutputStream fileOutputStream = null;
        // 将模版文件写入到tomcat临时目录
        String folder = System.getProperty("catalina.home");
        File tempFile = new File(folder + File.separator + path);
        // 文件存在时不再写入
        if (tempFile.exists()) {
            return tempFile.getPath();
        }
        File parentFile = tempFile.getParentFile();
        // 判断父文件夹是否存在
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        try {
            BufferedInputStream inputStream = new BufferedInputStream(resource.getInputStream());
            fileOutputStream = new FileOutputStream(tempFile);
            byte[] buffer = new byte[10240];
            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return tempFile.getPath();
    }
**关注公众号【可为编程】回复【面试】领取最新面试题!!!**
}

导入表单数据

一、导入Controller

@ApiOperation(value = "批量导入应急物资数据")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    //    @PreAuth("hasPermit('{}view')")
    public R upload(@RequestParam("file") MultipartFile multipartFile,
                         @ApiIgnore @LoginUser SysUser user) throws Exception {
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setTitleRows(2);
        List<EmergencyMaterialInputEntity> factors = ExcelImportUtil.importExcel(multipartFile.getInputStream(),
                EmergencyMaterialInputEntity.class, params);
        EmergencyMaterialInputSaveDTO dto = new EmergencyMaterialInputSaveDTO();
//        this.setDTO(dto, user);
        emergencyMaterialInputService.upload(factors, dto);
        return R.success();
    }
二、ServiceImpl层
  public void upload(List<EmergencyMaterialInputEntity> factors, EmergencyMaterialInputSaveDTO dto) {
        List<EmergencyMaterialInput> emergencyMaterialInputs = new ArrayList<>();
        List<Map<String, Object>> stringList = baseMapper.selectManagerCode();
        for (EmergencyMaterialInputEntity factor : factors) {
            if (factor.getMaterialName() != null && !"".equals(factor.getMaterialName()) && factor.getMaterialType() != null && !"".equals(factor.getMaterialType())) {
                dto.setMaterialName(factor.getMaterialName() != null ? factor.getMaterialName() : "");
                dto.setMaterialType(factor.getMaterialType() != null ? factor.getMaterialType() : "");
                dto.setMaterialCount(factor.getMaterialCount() != null ? factor.getMaterialCount() : 0);
                dto.setMaterialUnit(factor.getMaterialUnit() != null ? factor.getMaterialUnit() : "");
                //根据用户名查询对应负责人编号
                for (Map<String, Object> map : stringList) {
                    if (factor.getManager() != null) {
                        if (factor.getManager().equals(map.get("manager"))) {
                            dto.setManagerCode(map.get("manager_code").toString());
                        }
                    }
                }
                dto.setInputTime(factor.getInputTime() != null ? factor.getInputTime() : LocalDateTime.now());
                dto.setValidityDate(factor.getValidityDate() != null ? factor.getValidityDate() : LocalDate.now());
                EmergencyMaterialInput model = BeanUtil.toBean(dto, getEntityClass());
                emergencyMaterialInputs.add(model);
            }
        }
        this.saveBatch(emergencyMaterialInputs);
    }

下载模板

    public void downloadModel(Map params, HttpServletRequest request, HttpServletResponse response) {
        String model = params.get("model").toString();
//        String templateFile = EnvironmentJsonServiceImpl.class.getClassLoader().getResource("doc/"+model+".xlsx")
//                .getPath();
        try {
            Resource resource = new ClassPathResource("doc/" + model + ".xls");
//            File file = resource.getFile();
            String filename = resource.getFilename();
            InputStream inputStream = resource.getInputStream();
            response.setHeader("content-type", "application/octet-stream;charset=UTF-8");
            response.setContentType("application/octet-stream;charset=UTF-8");
//            response.addHeader("Content-Length", String.valueOf(file.length()));
            OutputStream out = response.getOutputStream();
            //使用URLEncoder来防止文件名乱码或者读取错误
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            int b = 0;
            byte[] buffer = new byte[1000000];
            while (b != -1) {
                b = inputStream.read(buffer);
                if (b != -1) {
                    out.write(buffer, 0, b);
                }
            }
            inputStream.close();
            out.close();
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

传入的map为json形式的模板名称,对应的doc地址在项目的resource/doc目录下。

欢迎感兴趣的小伙伴一起探讨学习知识,以上是个人的一些总结分享,如有错误的地方望各位留言指出,十分感谢。觉得有用的话别忘点赞、收藏、关注,手留余香! 😗 😗 😗

这里是一个真诚的***青年技术交流QQ群:761374713***,不管你是大学生、社畜、想学习变成的其他人员,欢迎大家加入我们,一起成长,一起进步,真诚的欢迎你,不管是技术,还是人生,还是学习方法。有道无术,术亦可求,有术无道,止于术。在这里插入图片描述

欢迎大家关注【可为编程】,成长,进步,编程,技术、掌握更多知识!
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
出现乱码的原因可能是导出Excel文件编码格式和浏览器的编码格式不一致。可以尝试在设置response的header时,指定编码格式为UTF-8,如下所示: ``` response.setCharacterEncoding("UTF-8"); response.setContentType("application/vnd.ms-excel;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=\"" + exportReq.getFileName() + ".xlsx\""); ``` 另外,ExcelExportUtil.exportExcel()方法有多个重载,可以尝试使用重载方法,设置导出Excel文件的编码格式,例如: ``` Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(exportReq.getFileName(), "sheet1", ExcelType.XSSF), TagDetail.class, exportReq.getTagDetails()); workbook.setSheetName(0, "sheet1"); workbook.setSheetName(1, "sheet2"); workbook.setSheetName(2, "sheet3"); workbook.setSheetName(3, "sheet4"); workbook.setSheetName(4, "sheet5"); workbook.setSheetName(5, "sheet6"); workbook.setSheetName(6, "sheet7"); workbook.setSheetName(7, "sheet8"); workbook.setSheetName(8, "sheet9"); workbook.setSheetName(9, "sheet10"); workbook.setSheetName(10, "sheet11"); workbook.setSheetName(11, "sheet12"); workbook.setSheetName(12, "sheet13"); workbook.setSheetName(13, "sheet14"); workbook.setSheetName(14, "sheet15"); workbook.setSheetName(15, "sheet16"); workbook.setSheetName(16, "sheet17"); workbook.setSheetName(17, "sheet18"); workbook.setSheetName(18, "sheet19"); workbook.setSheetName(19, "sheet20"); workbook.setCharset("UTF-8"); ``` 需要注意的是,设置编码格式需要在导出Excel文件之前进行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

可为编程

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

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

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

打赏作者

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

抵扣说明:

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

余额充值