Java进行excel的导入导出操作
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进行excel的导入导出操作的更多相关文章
- c# .Net :Excel NPOI导入导出操作教程之读取Excel文件信息及输出
c# .Net :Excel NPOI导入导出操作教程之读取Excel文件信息及输出 using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using S ...
- java实现excel的导入导出(poi详解)[转]
java实现excel的导入导出(poi详解) 博客分类: java技术 excel导出poijava 经过两天的研究,现在对excel导出有点心得了.我们使用的excel导出的jar包是poi这个 ...
- java 中Excel的导入导出
部分转发原作者https://www.cnblogs.com/qdhxhz/p/8137282.html雨点的名字 的内容 java代码中的导入导出 首先在d盘创建一个xlsx文件,然后再进行一系列 ...
- JAVA对Excel的导入导出
今天需要对比2个excel表的内容找出相同:由于要学的还很多上手很慢所以在这做个分享希望对初学的有帮助: 先是pom的配置: <dependency> <groupId>org ...
- c# .Net :Excel NPOI导入导出操作教程之List集合的数据写到一个Excel文件并导出
将List集合的数据写到一个Excel文件并导出示例: using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using System;using Sys ...
- java实现excel的导入导出(poi详解)
经过两天的研究,现在对excel导出有点心得了.我们使用的excel导出的jar包是poi这个阿帕奇公司的一个项目,后来被扩充了.是比较好用的excel导出工具. 下面来认识一下这个它吧. 我们知道要 ...
- C# .Net :Excel NPOI导入导出操作教程之将Excel文件读取并写到数据库表,示例分享
using (FileStream fileReader = File.OpenRead(@"C:\Users\Administrator\Desktop\112.xls")) ...
- c# .Net :Excel NPOI导入导出操作教程之数据库表信息数据导出到一个Excel文件并写到磁盘示例分享
string sql = @"select * from T_Excel"; ----------------DataTable Star---------------- ...
- 循序渐进开发WinForm项目(5)--Excel数据的导入导出操作
随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...
- VB中Excel 2010的导入导出操作
VB中Excel 2010的导入导出操作 编写人:左丘文 2015-4-11 近来这已是第二篇在讨论VB的相关问题,今天在这里,我想与大家一起分享一下在VB中如何从Excel中导入数据和导出数据到Ex ...
随机推荐
- Redis系列:RDB内存快照提供持久化能力
★ Redis24篇集合 1 介绍 从上一篇的 <深刻理解高性能Redis的本质> 中可以知道, 我们经常在数据库层上加一层缓存(如Redis),来保证数据的访问效率. 这样性能确实也有了 ...
- [学习笔记] Linux 环境下搭建基于Ngnix的反向代理服务
之前为了方便同事测试微信小程序,搭建了基于CentOS的预发布环境,.Net5 程序也已经部署好在上面,在公网上可以通过http协议的临时域名(jevonsflash.xxx.net)访问到后台Ap ...
- 【风控算法】二、SQL->Python->PySpark计算KS,AUC及PSI
KS,AUC 和 PSI 是风控算法中最常计算的几个指标,本文记录了多种工具计算这些指标的方法. 生成本文的测试数据: import pandas as pd import numpy as np i ...
- 第143篇:手写vue-router,实现router-view
好家伙, 今天来手写我们的老伙计vue-router, 1.替换router 新开一个项目,并使用我们手写的router 2.大致结构 let Vue; // 保存vue的构造函数 cla ...
- favorite 单词学习 主要是发音 fa - vor - it 注意 ri不连读 是自然带出来的r的尾音
favorite 单词学习 主要注意发音 [ ˈfeɪ v(ə)r ɪt ] 主要是发音 fa - vor - it 注意 ri不连读 是自然带出来的r的尾音 favor : 来自拉丁语favere, ...
- http-server -S 开启 https 服务
下载 openssl Win64 OpenSSL v1.1.1k Light http://slproweb.com/download/Win64OpenSSL_Light-1_1_1k.exe 一路 ...
- WPF之命令
目录 命令系统的基本元素 基本元素之间的关系 小试命令 WPF的命令库 命令参数 命令与Binding的结合 近观命令 ICommand接口与RoutedCommand 自定义Command 定义命令 ...
- Android Material组件库(日期选择和时间选择器)基本使用
原文:Android Material组件库(日期选择和时间选择器)基本使用 - Stars-One的杂货小窝 简单的封装下Material组件里的日期选择器和时间选择器的使用方法 效果 代码 需要添 ...
- 记录:Openlayers6.5 实现轨迹回放
这篇分享我记录到的一个案例,废话不多说,上代码 import Feature from 'ol/Feature' import LineString from 'ol/geom/LineString' ...
- CDN 引入 axios 和 qs 及其使用方法
一些小项目,没必要搭建脚手架,直接以CDN的方式引入 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...