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

简介: 今天工作中又遇到了excel导出数据的功能,在这里我将自己自定义的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,然后里面放我们的模板。模板的定义如下:

20210412215151467.png

一定要注意红色标出来的花括号,否则显示不出来对应的数据值。

四、 打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目录下。

相关文章
|
20天前
|
数据采集 数据可视化 数据挖掘
利用Python自动化处理Excel数据:从基础到进阶####
本文旨在为读者提供一个全面的指南,通过Python编程语言实现Excel数据的自动化处理。无论你是初学者还是有经验的开发者,本文都将帮助你掌握Pandas和openpyxl这两个强大的库,从而提升数据处理的效率和准确性。我们将从环境设置开始,逐步深入到数据读取、清洗、分析和可视化等各个环节,最终实现一个实际的自动化项目案例。 ####
|
26天前
|
前端开发
实现Excel文件和其他文件导出为压缩包,并导入
实现Excel文件和其他文件导出为压缩包,并导入
27 1
|
29天前
|
数据格式 UED
记录一次NPOI库导出Excel遇到的小问题解决方案
【11月更文挑战第16天】本文记录了使用 NPOI 库导出 Excel 过程中遇到的三个主要问题及其解决方案:单元格数据格式错误、日期格式不正确以及合并单元格边框缺失。通过自定义单元格样式、设置数据格式和手动添加边框,有效解决了这些问题,提升了导出文件的质量和用户体验。
163 3
|
2月前
|
数据处理 Python
Python实用记录(十):获取excel数据并通过列表的形式保存为txt文档、xlsx文档、csv文档
这篇文章介绍了如何使用Python读取Excel文件中的数据,处理后将其保存为txt、xlsx和csv格式的文件。
86 3
Python实用记录(十):获取excel数据并通过列表的形式保存为txt文档、xlsx文档、csv文档
|
1月前
|
Java API Apache
|
1月前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
51 4
|
2月前
|
JavaScript 前端开发 数据处理
Vue导出el-table表格为Excel文件的两种方式
Vue导出el-table表格为Excel文件的两种方式
91 6
|
2月前
|
数据采集 存储 JavaScript
自动化数据处理:使用Selenium与Excel打造的数据爬取管道
本文介绍了一种使用Selenium和Excel结合代理IP技术从WIPO品牌数据库(branddb.wipo.int)自动化爬取专利信息的方法。通过Selenium模拟用户操作,处理JavaScript动态加载页面,利用代理IP避免IP封禁,确保数据爬取稳定性和隐私性。爬取的数据将存储在Excel中,便于后续分析。此外,文章还详细介绍了Selenium的基本设置、代理IP配置及使用技巧,并探讨了未来可能采用的更多防反爬策略,以提升爬虫效率和稳定性。
144 4
|
4月前
|
关系型数据库 MySQL Shell
不通过navicat工具怎么把查询数据导出到excel表中
不通过navicat工具怎么把查询数据导出到excel表中
51 0
|
2月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。