Java-Excel导入导出

具体代码实现如下:

Service:

public interface ExcelService {
    /**
     * excel导出
     * @param lists 需要写入的list
     * @param response response
     * @param paramsMap 表头和字段对应map   key:字段   value:表头
     * @param outFileName 导出的文件名 xxx.xlsx
     */
    void downLoadFile(List<?> lists, HttpServletResponse response, Map<String, String> paramsMap, String outFileName);
    /**
     * excel导入
     * @param file 文件
     * @param paramsMap 表头和字段对应map  key:表头   value:字段
     * @param tClass 实体的class
     * @param <T> 泛型
     * @return
     * @throws IOException
     */
    <T> List<T> importFile(MultipartFile file, Map<String, String> paramsMap, Class<T> tClass) throws IOException;
}

Service-Impl:

//此处import有删减,代码中对应修改为自己的即可
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ExcelServiceImpl implements ExcelService {

    @Override
    public void downLoadFile(List<?> lists, HttpServletResponse response, Map<String, String> paramsMap, String outFileName) {
        String ENCODING = "UTF-8";
        if (lists == null || lists.isEmpty()) {
            return;
        }
        try (ExcelWriter writer = ExcelUtil.getWriter(true);
             final OutputStream output = response.getOutputStream()) {
            // 通过工具类创建writer并且进行别名
            assembleWriter(writer, paramsMap);
            //只输出有别名的字段
            writer.setOnlyAlias(true);
            // 准备将对象写入我们的 List
            writer.write(lists, true);
            // 获取我们的输出流
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + outFileName + ";filename*=utf-8''"
                    + URLEncoder.encode(outFileName, ENCODING));
            writer.flush(output, true);
        } catch (Exception e) {
            log.error("用户导出失败:", e);
        }
    }
    /**
     * 导出时表头工具类
     * @param writer
     * @param paramsMap
     */
    private void assembleWriter(ExcelWriter writer, Map<String, String> paramsMap) {
        /**
         * 例子:writer.addHeaderAlias("username", "用户名");
         * key:字段   value:表头
         */
        for(Map.Entry<String, String> entry : paramsMap.entrySet()){
            writer.addHeaderAlias(entry.getKey(), entry.getValue());
        }
    }
    @Override
    public <T> List<T> importFile(MultipartFile file, Map<String, String> paramsMap, Class<T> tClass) throws IOException {
        String fileName = file.getOriginalFilename();
        // 上传文件为空
        if (StringUtils.isEmpty(fileName)) {
            log.error( "没有导入文件");
        }
        //上传文件大小上限为10M
        if (file.getSize() > ImportFileConstants.FILE_SIZE) {
            log.error("文件大小超过10M");
            throw new CrmException(CrmExceptionCode.FILE_SIZE_ERROR);
        }
        // 上传文件名格式不正确
        if (fileName.lastIndexOf(".") != -1 && !".xlsx".equals(fileName.substring(fileName.lastIndexOf(".")))) {
            log.error( "文件名格式不正确, 请使用后缀名为.xlsx的文件");
        }
        try(InputStream inputStream = file.getInputStream();
            ExcelReader excelReader = ExcelUtil.getReader(inputStream, "sheet1")) {
            assembleReader(excelReader, paramsMap);
            List<T> t = excelReader.readAll(tClass);
            if (t.size() < 1 || t.size() > ImportFileConstants.FILE_NUM){
                throw new CrmException(CrmExceptionCode.FILE_NUM_ERROR);
            }
            return t;
        }catch (Exception e){
            log.error("上传文件出错"+e);
            throw new CrmException(CrmExceptionCode.FILE_NUM_ERROR);
        }
    }

    /**
     * 导入时表头工具类
     * @param reader
     */
    private void assembleReader(ExcelReader reader, Map<String, String> paramsMap) {
        /**
         * 例子:reader.addHeaderAlias("用户名", "username");
         * key:表头   value:字段
         */
        for(Map.Entry<String, String> entry : paramsMap.entrySet()){
            reader.addHeaderAlias(entry.getKey(), entry.getValue());
        }
    }
}

扩展:

  • T 泛型和 ? 通配符的区别?
  1. 泛型代表了所有Java类型中的一个(一旦声明成一种类型,则完全受这种类型约束,也就是说在运行时会将T替换成一种具体的数据类型);而通配符代表的是所有的Java类型(通配符不是代表具体某种数据类型,而是通用于所有的数据类型)
  2. 泛型可以进行写操作,但是通配符不行(因为通配符可代表任何的数据类型,所以在写时会因为不知道是什么类型而无法写入)
  3. 泛型在获取泛指值时可以使用Object或者T来承接;通配符则只可以使用Object来承接
  4. 使用extends限定类型子集的时候,泛型可以多继承,通配符则不行
  5. 使用super限定父集的时候,通配符是可以限定父集的,但是泛型是不可以的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值