java实现Excel的导入与导出

导入:将文档中数据导入到内存中,后续可以添加到数据库

导出:将内存中的数据或数据库中查询的数据导出到文档中

注意:这里指的文档通常指的是基本的办公软件:word,excel,ppt

绝大多数公司都在使用word和excel,如果我们开发的系统支持导入导出,我们开发的软件就相对会有优势

1.业务场景

案例1:
    公司举行会议时的签到表
        由系统运营人员将公司所有在职员工的信息导出为excel
        由公司后勤或行政人员对excel表进行修改,然后打印进行签到
    腾讯会议签到导出
案例2:
    采购清单
        后勤人员录入信息到excel
        系统维护人员将excel导入到数据库
    业务员线下推广收集用户数据,后面集中批量添加到数据库

2. Java操作办公软件

在开发中,我们经常需要写程序操作办公软件【其中操作得最多的就是Word与Excel】!因此我们使用代码生成,读取这些文件的数据也是很重要的一个功能

Java中提供了相应的操作办公软件的框架,其中,最常用的是下面两种:

jxl:只能对Excel进行操作,属于比较老的框架。

POI:是apache的项目,可对ms的word,Excel,PPT进行操作,包括office2003和2007。对两种版本的处理都比较好。具体操作请看官方的文档

3. POI的使用

咱们这里直接学习poi的使用,poi针对offices03(xls)07(xlsx)是单独写了相应的实现api,我们这里直接使用07版的处理方案(注:网上是有相应的兼容方案,可判断)

4. EasyPOI导出数据

为了提高开发效率,我们这里使用easyPOI进行数据的导入导出

easypoi导入/导出excel其实就是domain对象属性和excel列的映射,而easypoi是通过注解的方式来做映射的,我们学习easypoi其实就是学会使用工具类和掌握它的常用注解

常见的注解有:

@Excel 作用到filed上面,是对Excel一列的一个描述
@ExcelCollection 表示一个集合,主要针对一对多的导出,比如一个老师对应多个科目,科目就可以用集合表示
@ExcelEntity 表示一个继续深入导出的实体,但他没有太多的实际意义,只是告诉系统这个对象里面同样有导出的字段

@ExcelIgnore 和名字一样表示这个字段被忽略跳过这个导导出
@ExcelTarget 这个是作用于最外层的对象,描述这个对象的id,以便支持一个对象可以针对不同导出做出不同处理

注意:hutools中也有导入导出的工具类,用法不太一样

4.1引入pom依赖
<!--poi依赖(生成Excel时需要用到此依赖包)-->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>4.1.2</version>
    </dependency>
4.2. 添加工具类
package com.zt.basic.config;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * Excel导入导出工具类
 * @author hm
 */
public class ExcelUtils{

    /**
     * 导出工具类
     * @param list
     * @param title
     * @param sheetName
     * @param pojoClass
     * @param fileName
     * @param isCreateHeader
     * @param response
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass,
                                   String fileName, boolean isCreateHeader, HttpServletResponse response){
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setCreateHeadRows(isCreateHeader);
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    /**
     * 导出工具类
     * @param list
     * @param title
     * @param sheetName
     * @param pojoClass
     * @param fileName
     * @param response
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass,String fileName,
                                   HttpServletResponse response){
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
    }

    public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response){
        defaultExport(list, fileName, response);
    }

    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName,
                                      HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams,pojoClass,list);
        if (workbook != null); downLoadExcel(fileName, response, workbook);
    }

    private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            //throw new NormalException(e.getMessage());
        }
    }

    private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        if (workbook != null);
        downLoadExcel(fileName, response, workbook);
    }

    public static <T> List<T> importExcel(String filePath,Integer titleRows,Integer headerRows, Class<T> pojoClass){
        if (StringUtils.isBlank(filePath)){
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        }catch (NoSuchElementException e){
            //throw new NormalException("模板不能为空");
        } catch (Exception e) {
            e.printStackTrace();
            //throw new NormalException(e.getMessage());
        } return list;
    }

    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass){
        if (file == null){ return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        }catch (NoSuchElementException e){
            // throw new NormalException("excel文件不能为空");
        } catch (Exception e) {
            //throw new NormalException(e.getMessage());
            System.out.println(e.getMessage());
        }
        return list;
    }
}

4.3 需求:前端请求导出

 点击导出,导出前端按钮(作者用到的前端技术栈是vue)

导出按钮:

<el-form-item>
          <!-- 默认name="file" -->
          <el-upload class="upload-demo"
                     action="http://localhost:8080/shop/importExcel"
                     list-type="text">
            <el-button type="warning">点击导入</el-button>
          </el-upload>
        </el-form-item>

 导出方法:

// 导出方法
exportData(){
        //this.$router.push({ path: '/register' });
        location.href="http://localhost:8080/shop/export";
      }

4.4 后端接口

   /**
     * 导出
     * @param
     * @return
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response) {
        List<Shop> shops = shopService.findAll();
        ExcelUtils.exportExcel(shops, "店铺信息", "店铺数据", Shop.class, "店铺信息.xlsx", true, response);
    }

4.5 domain层加注解

package com.zt.org.domain;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zt.basic.domain.BaseDomain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Shop extends BaseDomain {
    @Excel(name = "店铺名称",orderNum = "1",width = 30)
    @NotNull(message = "店铺名字不能为空")
    private String name;
    @Excel(name = "店铺电话",orderNum = "2",width = 30)
    @NotNull(message = "店铺电话不能为空")
    private String tel;
    @Excel(name = "店铺入驻时间", orderNum = "3", width = 50, format = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    private Date registerTime = new Date();
    @Excel(name = "店铺状态", orderNum = "4", width = 30, replace = {"待审核_1", "待激活_2","已激活_3","驳回_4"})
    private Integer state;
    @Excel(name = "店铺地址", orderNum = "5", width = 50)
    private String address;
    private String logo;
    private Long adminId;
    @Valid
    private Employee admin;
}

5. EasyPOI导入数据

5.1. 前端代码准备

对于excel导入,其实就是上传文件并解析内容,将excel里面的每一行数据解析为一个Shop对象再保存数据就行

<el-form-item>
          <!-- 默认name="file" -->
          <el-upload class="upload-demo"
                     action="http://localhost:8080/shop/importExcel"
                     list-type="text">
            <el-button type="warning">点击导入</el-button>
          </el-upload>
        </el-form-item>

5.2 后端接口代码

   /**
     * 导入
     * */
    @PostMapping("/importExcel")
    public void importExcel(@RequestPart MultipartFile file) {
        // titleRows:占用了多少行
        List<Shop> shops = ExcelUtils.importExcel(file, 1, 1, Shop.class);
        shopService.batchAdd(shops);
    }

注意:导入时需要注意格式

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值