首页 > 编程语言 >Java进行excel的导入导出操作

Java进行excel的导入导出操作

时间:2024-04-15 19:55:39浏览次数:30  
标签:Java java demo excel public 导入 import com example

excel表格的导出导入在业务中经常会遇到,下面介绍hutool和easyExcel两种操作excel的工具

测试的实体类

通过mybatis-plus生成的,用于导出数据的实体类


@Getter
@Setter
@TableName("device_info")
@ApiModel(value = "DeviceInfo对象", description = "")
public class DeviceInfo implements Serializable {

    @ApiModelProperty("设备ID")
    @TableId(value = "device_id",type = IdType.ASSIGN_UUID)
    private String deviceId;

    @ApiModelProperty("设备名称")
    @TableField("device_name")
    private String deviceName;

    @ApiModelProperty("设备编号")
    @TableField("device_no")
    private String deviceNo;

    @ApiModelProperty("设备型号")
    @TableField("device_model")
    private String deviceModel;

    @ApiModelProperty("新建时间")
    @TableField("create_time")
    private LocalDateTime createTime;

    @ApiModelProperty("更新时间")
    @TableField("update_time")
    private LocalDateTime updateTime;

    @ApiModelProperty("创建人")
    @TableField("created_by")
    private String createdBy;

    @ApiModelProperty("更新人")
    @TableField("updated_by")
    private String updatedBy;

    @ApiModelProperty("版本")
    @TableField("version")
    private Long version;

}

Mapper文件

package com.example.demo.mapper;

import com.example.demo.entity.DeviceInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;


@Mapper
public interface DeviceInfoMapper extends BaseMapper<DeviceInfo> {

}

Mapper的xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.DeviceInfoMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.example.demo.entity.DeviceInfo">
        <id column="device_id" property="deviceId" />
        <result column="device_name" property="deviceName" />
        <result column="device_no" property="deviceNo" />
        <result column="device_model" property="deviceModel" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="created_by" property="createdBy" />
        <result column="updated_by" property="updatedBy" />
        <result column="version" property="version" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        device_id, device_name, device_no, device_model, create_time, update_time, created_by, updated_by, version
    </sql>

</mapper>

IService接口

package com.example.demo.service;

import com.example.demo.entity.DeviceInfo;
import com.baomidou.mybatisplus.extension.service.IService;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

public interface IDeviceInfoService extends IService<DeviceInfo> {

    void exportExcel(HttpServletResponse response) throws IOException;

    boolean importExcel(InputStream inputStream);
}

1、使用hutool导出

优点:hutool有很多工具类,包括ExcelWrite和ExcelReader工具类,写代码也很简洁,我觉得简单的导入导出优先可以使用
缺点:导出不支持excel模板,很难将一些特定数据放在特定的单元格中,导入不好读表格的特殊信息,如批注信息等

增加依赖

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.22</version>
</dependency>

导入的表格

导出的表格

如果要好看的格式、列宽、行距,可以通过以下代码设置单元格的格式,

StyleSet style = writer.getStyleSet();
style.getHeadCellStyle().setFillBackgroundColor(IndexedColors.WHITE.getIndex());
writer.getCell(0,0).getCellStyle().setFillForegroundColor(IndexedColors.WHITE.getIndex());

代码实现

以下是controller类

package com.example.demo.controller;


import com.example.demo.service.IDeviceInfoService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@RestController
@RequestMapping("/device-info")
public class DeviceInfoController {

    @Resource
    private IDeviceInfoService deviceInfoService;

    @GetMapping("/exportExcel")
    @ApiOperation(value = "导出模板表格测试")
    public void exportExcel(HttpServletResponse response) throws IOException {
        deviceInfoService.exportExcel(response);
    }

    @PostMapping("importExcel")
    @ApiOperation(value = "导入表格测试")
    public boolean importExcel(MultipartFile file) throws IOException {
        return deviceInfoService.importExcel(file.getInputStream());
        }
}

以下是进行简单导入导出操作的Service

package com.example.demo.service.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.DeviceInfo;
import com.example.demo.mapper.DeviceInfoMapper;
import com.example.demo.service.IDeviceInfoService;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.List;


@Service
public class DeviceInfoServiceImpl extends ServiceImpl<DeviceInfoMapper, DeviceInfo> implements IDeviceInfoService {


    @Override
    public void exportExcel(HttpServletResponse response) throws IOException {

        //导出的表格名称
        String targetFileName = "测试导出表格" + LocalDate.now();
        String suffix = ".xlsx";

        //设置接口响应结果格式
        response.reset();
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(targetFileName + suffix, "UTF-8"));

        List<DeviceInfo> deviceInfoList = this.list();

        // 通过工具类创建writer,默认创建xls格式
        ExcelWriter writer = ExcelUtil.getWriter();

        //获取注解的值,跟excel表的表头对应
        Field[] fields = DeviceInfo.class.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            String header = fields[i].getDeclaredAnnotation(ApiModelProperty.class).value();
            writer.addHeaderAlias( fields[i].getName(),header);
        }
        //可以新建sheet,将数据导出成多个sheet
        writer.setSheet("设备信息");
// 一次性写出内容,使用默认样式
        writer.write(deviceInfoList);

        //根据单元格内容自动调整列宽
        writer.autoSizeColumnAll();
//out为OutputStream,需要写出到的目标流
        writer.flush(response.getOutputStream());
// 关闭writer,释放内存
        writer.close();

    }

    @Override
    public boolean importExcel(InputStream inputStream) {
        ExcelReader reader = ExcelUtil.getReader(inputStream, 0);
        //获取注解的值,跟excel表的表头对应
        Field[] fields = DeviceInfo.class.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            String header = fields[i].getDeclaredAnnotation(ApiModelProperty.class).value();
            reader.addHeaderAlias(header, fields[i].getName());
        }

        List<DeviceInfo> deviceInfoList = reader.read(0, 1, DeviceInfo.class);

        return this.saveOrUpdateBatch(deviceInfoList);
    }
}

2、使用easyExcel导出

增加依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.2.1</version>
</dependency>

导入的表格

导出的表格

预先做好的导出模板


这是进行导出的模板,需要在每一个单元格写上实体的字段名称,程序才能精确将数据填到相应的位置
如{.deviceId}在字段名称前有个 . 表示数据是一个List,如{listSize}表示数据只是一个单元格的值

导出的模板文件放在资源下面

导出的表格结果


代码实现

Controller类

package com.example.demo.controller;


import com.alibaba.excel.EasyExcel;
import com.example.demo.entity.DeviceInfo;
import com.example.demo.listener.DeviceInfoListener;
import com.example.demo.service.IDeviceInfoService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@RestController
@RequestMapping("/device-info")
public class DeviceInfoController {

    @Resource
    private IDeviceInfoService deviceInfoService;

    @GetMapping("/exportExcel")
    @ApiOperation(value = "导出模板表格测试")
    public void exportExcel(HttpServletResponse response) throws IOException {
        deviceInfoService.exportExcel(response);
    }

    @PostMapping("importExcel")
    @ApiOperation(value = "导入表格测试")
    public boolean importExcel(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(),DeviceInfo.class,new DeviceInfoListener(deviceInfoService)).sheet().doRead();
        return true;
    }
}

实现导出逻辑的Service类

package com.example.demo.service.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.DeviceInfo;
import com.example.demo.mapper.DeviceInfoMapper;
import com.example.demo.service.IDeviceInfoService;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DeviceInfoServiceImpl extends ServiceImpl<DeviceInfoMapper, DeviceInfo> implements IDeviceInfoService {


    @Override
    public void exportExcel(HttpServletResponse response) throws IOException {
        //导出的表格名称
        String targetFileName = "测试导出表格" + LocalDate.now();
        String suffix = ".xlsx";
        //根据相对路径获取模板表格的内容
        ClassPathResource resource = new ClassPathResource("template/测试导出模板表格.xlsx");
        File bathFile = resource.getFile();
        //设置接口响应结果格式
        response.reset();
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(targetFileName + suffix, "UTF-8"));

        List<DeviceInfo> deviceInfoList = this.list();

        Map<String,Object> map = new HashMap<>();
        map.put("listSize",deviceInfoList.size() );
        map.put("nowDate",LocalDate.now() );

        //将模板复制到目标表格中
        ExcelWriter excelWriter = EasyExcelFactory.write(response.getOutputStream()).withTemplate(bathFile).build();
        //将列表的值写入表格中,要求实体类的字段名称与模板中的名称一致
        WriteSheet sheet = EasyExcelFactory.writerSheet().build();
        excelWriter.fill(map,sheet);
        excelWriter.fill(deviceInfoList, sheet);
        excelWriter.finish();
    }
    
}

导入需要写一个数据监听类,实现readListener接口

package com.example.demo.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.example.demo.entity.DeviceInfo;
import com.example.demo.service.IDeviceInfoService;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
public class DeviceInfoListener implements ReadListener<DeviceInfo> {

    /**
     * 每隔100条存储数据库,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 100;
    /**
     * 缓存的数据
     */
    private List<DeviceInfo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    private IDeviceInfoService deviceInfoService;

    public DeviceInfoListener( ) {
    }

    public DeviceInfoListener(IDeviceInfoService deviceInfoService) {
        this.deviceInfoService = deviceInfoService;
    }
    @Override
    public void invoke(DeviceInfo data, AnalysisContext context) {
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        cachedDataList.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", cachedDataList.size());
        deviceInfoService.saveOrUpdateBatch(cachedDataList);
        log.info("存储数据库成功!");
    }
}

标签:Java,java,demo,excel,public,导入,import,com,example
From: https://www.cnblogs.com/davidFB/p/18136806

相关文章

  • java连接ssmsSqlserver数据库 报错信息:com.microsoft.sqlserver.jdbc.SQLServerExce
    解决办法:将官网下载的驱动文件打开,找到如下路径,并复制,粘贴放到jdk的bin目录下......
  • java基础_05_流程控制
    1、用户交互Scanner(译:扫描器) 1\使用next方法接收,只接收空格以前的packageliuchengkongzhi;importjava.util.Scanner;publicclassScanner01{publicstaticvoidmain(String[]args){//创建一个扫描器对象,用于接收键盘数据ScannerSca......
  • Java使用javacv处理视频文件过程记录
    最近接到一个需求是将.mp4/.m4v文件体积进行压缩,我使用javacv中的FFmpegFrameGrabber、FFmpegFrameFilter、FFmpegFrameRecorder简单的实现视频帧的抓取、过滤、录制与输出。性能暂未验证。文章对这次的过程进行记录。1.jdk的选择mcr.microsoft.com/java/jdk:8u222-zulu-cento......
  • java中接口多个实现类,如何指定实现类,根据子类类型选择实现方法
    问题背景在Java代码中,经常会遇到一个接口有多个实现的情况。而这些实现类的参数又是不同的子类,这时候我们该如何选择正确的实现方法呢?解决方案我们可以通过判断参数的子类类型来选择正确的实现方法。具体实现可以使用Java中的instanceof关键字,它可以判断一个对象是否是某个类的......
  • 导入自定义板块的方法
         ......
  • Java并发编程实战读书笔记
    1.线程池模型    netty实战中讲到的线程池模型可以描述为:1.从线程池中选择一个空间的线程去执行任务,2.任务完成时,把线程归还给线程池。这个模型与连接池类似。    根据jdk源码的研究,具体的实现模型是,线程池ThreadPoolExecutor中有一个静态内部类Worker,使用装饰器模式扩......
  • EasyExcel 自定义宽高
    packagecom.cloud.module.management.common.handler;importcn.hutool.core.util.ObjectUtil;importcom.alibaba.excel.enums.CellDataTypeEnum;importcom.alibaba.excel.metadata.Head;importcom.alibaba.excel.metadata.data.CellData;importcom.alibaba.excel.......
  • C# 冻结Excel窗口以锁定行列、或解除冻结
    在处理大型Excel工作簿时,有时候我们需要在工作表中冻结窗格,这样可以在滚动查看数据的同时保持某些行或列固定不动。冻结窗格可以帮助我们更容易地导航和理解复杂的数据集。相反,当你不需要冻结窗格时,你可能需要解冻它们以获得完整的视野。下面将介绍如何使用免费.NET库通过C#实现......
  • Fluent Meshing:导入几何报错(Error in CAD Import)
    问题具体描述在使用Fluent自带的划分网格工具时,需要导入几何,在spaceclaim中做好几何处理以后,导入几何却报错:ErrorinCADImport解决方案采用下面的该方法逐一排除路径是否含有中文或者不合规字符等以管理员身份启动软件尝试几何文件和划网格软件版本是否一致Fluent是否安......
  • java基础_03_包机制
    1、包的本质,就是文件夹 2、建包方法: packagecom.baidu.hhb;//这就是包,必须加在整个类的最上边,不能删,删除后下面的类就找不到包importxiaodi_java_base.*;//*通配符,可以导入该目录下所有的类。importxiaodi_java_base.khhhk;//导入类importjava.util.Date;......