参考网址:http://www.wupaas.com/

1.Excel文件的导入导出

项目源码:后台:https://github.com/zhongyushi-git/easypoi-demo-admin.git。

     前端:https://github.com/zhongyushi-git/easypoi-demo.git

!!!说明:源码中可能与下面的介绍的代码稍有差异,请以源码为准。

1.1准备工作

1)首先新建一个SpringBoot的项目,搭建基本的环境访问数据,详见源码。

2)导入easypoi依赖

定义版本

<easypoi.version>4.1.0</easypoi.version>

坐标:这里是以springmvc的坐标导入的,适用大部分功能。如果需求不多,可以直接导入springboot对应的坐标,二者选一。选择依据就是如果报错,就换另一种坐标即可。

 <!--easypoi-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>${easypoi.version}</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>${easypoi.version}</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>${easypoi.version}</version>
</dependency>

springboot的坐标

<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>

3)创建Excel操作的工具类ExcelUtils

package com.example.easypoidemoadmin.utils;

import cn.afterturn.easypoi.cache.manager.POICacheManager;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.ExcelXorHtmlUtil;
import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.word.WordExportUtil;
import cn.afterturn.easypoi.word.parse.ParseWord07;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException; /**
* Excel导入导出工具类
*/ public class ExcelUtils { /**
* excel 导出
*
* @param list 数据列表
* @param fileName 导出时的excel名称
* @param response
*/
public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws IOException {
defaultExport(list, fileName, response);
} /**
* 默认的 excel 导出
*
* @param list 数据列表
* @param fileName 导出时的excel名称
* @param response
*/
private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws IOException {
//把数据添加到excel表格中
Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
downLoadExcel(fileName, response, workbook);
} /**
* excel 导出
*
* @param list 数据列表
* @param pojoClass pojo类型
* @param fileName 导出时的excel名称
* @param response
* @param exportParams 导出参数(标题、sheet名称、是否创建表头,表格类型)
*/
private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) throws IOException {
//把数据添加到excel表格中
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
downLoadExcel(fileName, response, workbook);
} /**
* excel 导出
*
* @param list 数据列表
* @param pojoClass pojo类型
* @param fileName 导出时的excel名称
* @param exportParams 导出参数(标题、sheet名称、是否创建表头,表格类型)
* @param response
*/
public static void exportExcel(List<?> list, Class<?> pojoClass, String fileName, ExportParams exportParams, HttpServletResponse response) throws IOException {
defaultExport(list, pojoClass, fileName, response, exportParams);
} /**
* excel 导出
*
* @param list 数据列表
* @param title 表格内数据标题
* @param sheetName sheet名称
* @param pojoClass pojo类型
* @param fileName 导出时的excel名称
* @param response
*/
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) throws IOException {
defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName, ExcelType.XSSF));
} /**
* excel 导出
*
* @param list 数据列表
* @param title 表格内数据标题
* @param sheetName sheet名称
* @param pojoClass pojo类型
* @param fileName 导出时的excel名称
* @param isCreateHeader 是否创建表头
* @param response
*/
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) throws IOException {
ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF);
exportParams.setCreateHeadRows(isCreateHeader);
defaultExport(list, pojoClass, fileName, response, exportParams);
} /**
* excel下载
*
* @param fileName 下载时的文件名称
* @param response
* @param workbook excel数据
*/
private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException {
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
workbook.write(response.getOutputStream());
} catch (Exception e) {
throw new IOException(e.getMessage());
}
} /**
* excel 导入
*
* @param file excel文件
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> List<T> importExcel(MultipartFile file, Class<T> pojoClass) throws IOException {
return importExcel(file, 1, 1, pojoClass);
} /**
* excel 导入
*
* @param filePath excel文件路径
* @param titleRows 表格内数据标题行
* @param headerRows 表头行
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
if (StringUtils.isBlank(filePath)) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
params.setNeedSave(true);
params.setSaveUrl("/excel/");
try {
return ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
} catch (NoSuchElementException e) {
throw new IOException("模板不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
} /**
* excel 导入
*
* @param file 上传的文件
* @param titleRows 表格内数据标题行
* @param headerRows 表头行
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
if (file == null) {
return null;
}
try {
return importExcel(file.getInputStream(), titleRows, headerRows, pojoClass);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
} /**
* excel 导入
*
* @param inputStream 文件输入流
* @param titleRows 表格内数据标题行
* @param headerRows 表头行
* @param pojoClass pojo类型
* @param <T>
* @return
*/
public static <T> List<T> importExcel(InputStream inputStream, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
if (inputStream == null) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
params.setSaveUrl("/excel/");
params.setNeedSave(true);
try {
return ExcelImportUtil.importExcel(inputStream, pojoClass, params);
} catch (NoSuchElementException e) {
throw new IOException("excel文件不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
}

4)创建数据库db2020及表user,执行脚本在根目录下。

5)excel表格要导入的数据文件在项目根路径的template文件夹下

6)使用vue-cli新建一个vue的项目,并安装需要的插件。项目对axios进行了封装,调用的时候,直接在js中使用即可,详见源码。

7)最后一点,要配置文件中加一行配置

#easypoi启用覆盖
spring
main:
allow-bean-definition-overriding: true

1.2导入

excel文件的导入,主要就是把文件上传之后把内容读取出来进行相应的操作。

1)编写controller导入接口,service及dao详见源码。需要注意的是,上述的导入的excel内容必须包含表头和标题,否则读取不到内容。

 /**
* 导入数据
* @param file
* @return
* @throws IOException
*/
@RequestMapping(value = "/import", method = RequestMethod.POST)
public CommonResult importExcel(@RequestParam("file") MultipartFile file) throws IOException {
List<User> list = ExcelUtils.importExcel(file, User.class);
int i = userService.insertByBatch(list);
if (i != 0) {
return new CommonResult(200, "导入成功");
} else {
return new CommonResult(444, "导入失败");
}
}

2)页面导入的组件

  <el-upload class="upload-demo" action="" :limit="1" :http-request="importExcel" :show-file-list="false" :file-list="fileList">
<el-button size="small" type="primary" icon="el-icon-upload">导入</el-button>
</el-upload>

3)页面导入的方法

  //导入
importExcel(param) {
const formData = new FormData()
formData.append('file', param.file)
home.upload(formData).then(res => {
if (res.code == 200) {
this.fileList = []
this.$message.success("导入成功")
this.getList()
} else {
this.$message.error("导入失败")
}
}).catch(err =>{
console.log(err)
this.$message.error("导入失败")
})
} 

1.3导出

导入就是根据查询的条件把查询结果先写到excel表格中,然后下载这个excel即可。

1)编写controller导出接口,service及dao详见源码。

/**
* 导出数据,使用map接收
*
* @param map
* @param response
* @throws IOException
*/
@PostMapping("/exportExcel")
public void exportExcel(@RequestBody Map<String, Object> map, HttpServletResponse response) throws IOException {
IPage<User> iPage = userService.getList((String) map.get("name"), (Integer) map.get("page"), (Integer) map.get("limit"));
ExcelUtils.exportExcel(iPage.getRecords(), (String) map.get("title"), (String) map.get("sheetName"), User.class, (String) map.get("fileName"), response);
}

2)给实体类加注解

package com.example.easypoidemoadmin.entity;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; /**
* @author zhongyushi
* @date 2020/6/24 0024
* @dec 用户实体
*/
@Data
@TableName(value = "User")
public class User { /**
* 用户名
*/
@TableId(value = "username")
@Excel(name = "用户名", orderNum = "0", width = 30)
private String username; /**
* 姓名
*/
@TableField(value = "name")
@Excel(name = "姓名", orderNum = "1", width = 30)
private String name; /**
* 年龄
*/
@TableField(value = "age")
@Excel(name = "年龄", orderNum = "2", width = 30)
private Integer age; /**
* 性别,0表示男,1表示女
*/
@TableField(value = "sex")
@Excel(name = "性别", orderNum = "3", width = 30,replace = {"男_0", "女_1"})
private String sex; /**
* 籍贯
*/
@TableField(value = "address")
@Excel(name = "籍贯", orderNum = "4", width = 30)
private String address;
//对于时间,需要指定导出的格式:exportFormat="yyyy-MM-dd HH:mm:ss"
}

3)页面导出的方法

 //导出
exportExcel() {
this.downloadLoading = true
home.exportExcel({
title: '用户基本信息',
sheetName: '用户信息',
fileName: '用户信息表',
name: this.pageData.name,
page: this.pageData.page,
limit: this.pageData.limit,
}).then(res => {
//使用js下载文件
fileDownload(res, '用户信息表.xlsx')
}).finally(() => {
this.downloadLoading = false;
});
},

这里使用到了js-file-download插件,它是用来帮助下载文件的。当下载文件时,很多时候都是在地址栏输入url后浏览器自动帮忙下载,但是要统一请求方式,就把返回的二进制文件交给js-file-download进行处理后再下载。需要注意的是,这个导出的请求,我封装了一个单独的方法,需要指定响应的方式,否则无法下载后的文件是空的,方法截图如下:

1.4图片的导出

有了上面的导出基础,图片的导出就很简单了。

1)新建一个实体类,用于和上面的实体类区分

package com.example.easypoidemoadmin.entity;

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data; /**
* @author zhongyushi
* @date 2020/6/26 0026
* @dec 描述
*/
@Data
public class Company {
@Excel(name = "公司名称",width =20)
private String name; /**
* type为 2 表示字段类型为图片
* imageType为 1 表示从file读取
*/
@Excel(name = "公司logo",width =20,type = 2,imageType = 1)
private String logo; @Excel(name = "公司介绍",width =100)
private String dec; public Company(String name,String logo,String dec){
this.name=name;
this.logo=logo;
this.dec=dec;
}
}

2)创建接口,图片请自行下载。

/**
* 图片的导出
*
* @param response
* @throws IOException
*/
@PostMapping("/imgexport")
public void imgExport(HttpServletResponse response,@RequestBody Map<String, Object> map) throws IOException {
List<Company> list = new ArrayList<>();
//图片的路径自定义,但必须要正确
list.add(new Company("百度", "E:/img/1.jpg", "百度一下你就知道"));
list.add(new Company("腾讯", "E:/img/3.jpg", "腾讯qq,交流的世界"));
list.add(new Company("阿里巴巴", "E:/img/2.jpg", "阿里巴巴,马云的骄傲"));
String fileName = map.get("fileName").toString();
ExcelUtils.exportExcel(list, fileName, fileName, Company.class, fileName, response);
}

3)在页面添加导出的按钮,点击按钮即可进行下载,下载的文件如图

1.5图片的导入

1)给Company对象加上无参构造,否则会出现异常

  public Company(){}

2)导入接口

 /**
* 导入图片
* @param file
* @return
* @throws IOException
*/
@PostMapping("/imgimport")
public CommonResult imgImport(@RequestParam("file") MultipartFile file) throws IOException {
List<Company> list = ExcelUtils.importExcel(file, Company.class);
return new CommonResult(200,"导入成功",list);
}

3)参考excel的导入,添加一个导入的按钮和请求的方法,详见源码

4)点击excel图片上传,把上一步导出的文件进行导入,看到浏览器返回的数据如图

1.6excel模板导出文件

也可以使用固定的模板来导出excel。

1)在工具类添加方法

    /**
* 根据模板生成excel后导出
* @param templatePath 模板路径
* @param map 数据集合
* @param fileName 文件名
* @param response
* @throws IOException
*/
public static void exportExcel(TemplateExportParams templatePath, Map<String, Object> map,String fileName, HttpServletResponse response) throws IOException {
Workbook workbook = ExcelExportUtil.exportExcel(templatePath, map);
downLoadExcel(fileName, response, workbook);
}

2)编写模板excel。截图如下,模板文件在项目根路径的template文件夹下:

在两个大括号里写对应的数据名称。$fe用来遍历数据,fe的写法 fe标志 : list数据 单个元素数据(默认t,不需要写) {{$fe: maplist t.id }}

3)接口

/**
* 使用模板excel导出
*
* @param response
* @throws Exception
*/
@PostMapping("/excelTemplate")
public void makeExcelTemplate(HttpServletResponse response, @RequestBody Map<String, Object> param) throws Exception {
TemplateExportParams templatePath = new TemplateExportParams("E:/excel/用户信息文件模板.xls");
Map<String, Object> map = new HashMap<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
map.put("date", sdf.format(new Date()));
map.put("user", "admin");
IPage<User> ipages = userService.getList("", 1, 10);
map.put("userList", ipages.getRecords());
ExcelUtils.exportExcel(templatePath, map, param.get("fileName").toString(), response);
}

在接口中,指定模板文件的路径,然后给定数据,map的key值要和模板的值保持一致。

4)页面添加按钮和请求方法,见源码。点击即可下载。

1.7excel转html

1)在工具类添加方法

    /**
* excel转html预览
* @param filePath 文件路径
* @param response
* @throws Exception
*/
public static void excelToHtml(String filePath,HttpServletResponse response) throws Exception{
ExcelToHtmlParams params = new ExcelToHtmlParams(WorkbookFactory.create(POICacheManager.getFile(filePath)),true);
response.getOutputStream().write(ExcelXorHtmlUtil.excelToHtml(params).getBytes());
}

2)编写接口

/**
* EXCEL转html预览
*/
@GetMapping("previewExcel")
public void excelToHtml(HttpServletResponse response) throws Exception {
ExcelUtils.excelToHtml("E:/excel/用户信息导入模板.xlsx",response);
}

3)页面添加按钮和请求方法,见源码。点击即可在弹框中显示。

2.Word文件导出

2.1使用word模板导出

1)在工具类加两个方法

/**
* word下载
*
* @param fileName 下载时的文件名称
* @param response
* @param doc
*/
private static void downLoadWord(String fileName, HttpServletResponse response, XWPFDocument doc) throws IOException {
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/msword");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".docx" , "UTF-8"));
doc.write(response.getOutputStream());
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
/**
* word模板导出
* @param map
* @param templatePath
* @param fileName
* @param response
* @throws Exception
*/
public static void WordTemplateExport(Map<String, Object> map,String templatePath,String fileName,HttpServletResponse response) throws Exception {
XWPFDocument doc = WordExportUtil.exportWord07(templatePath, map);
downLoadWord(fileName,response,doc);
}

2)接口,模板文件在项目根路径的template文件夹下,图片自定义下载(注意:如果要设置图片,必须把导入的jar的版本改为3.3.0,否则会报错,原因是新版本没有这个实体类):

    /**
* 使用模板word导出数据
* @param param
* @param response
*/
@PostMapping("/wordTemplate")
public void makeWordTemplate(@RequestBody Map<String, Object> param,HttpServletResponse response) {
Map<String, Object> map = new HashMap<>();
map.put("name", "张三");
map.put("nativePlace", "湖北武汉");
map.put("age", "20");
map.put("nation", "汉族");
map.put("phone", "15685654524");
map.put("experience", "湖北武汉,工作三年,java工程师");
map.put("evaluate", "优秀,善良,老实");
//设置图片,如果无图片,不设置即可
WordImageEntity image = new WordImageEntity();
image.setHeight(200);
image.setWidth(150);
image.setUrl("E:/excel/pic.jpg");
image.setType(WordImageEntity.URL);
map.put("picture", image);
try {
ExcelUtils.WordTemplateExport(map,"E:/excel/个人简历模板.docx",param.get("fileName").toString(),response);
} catch (Exception e) {
e.printStackTrace();
}
}

3)页面添加按钮和请求方法,见源码。点击即可下载。上面案例导出时有图片,如果不需要图片,可不设置图片路径即可。

2.2使用word模板导出多页

单模板生成多页数据在合适的场景也是需要的,比如一个订单详情信息模板,但是有很多订单,需要导入到一个word里面。

1)在工具类添加方法

    /**
* word模板导出多页
* @param list
* @param templatePath
* @param fileName
* @param response
* @throws Exception
*/
public static void WordTemplateExportMorePage(List<Map<String, Object>> list, String templatePath, String fileName, HttpServletResponse response) throws Exception {
XWPFDocument doc = new ParseWord07().parseWord(templatePath, list);
downLoadWord(fileName, response, doc);
}

2)接口

 /**
* word模板导出多页
* @param param
* @param response
*/
@PostMapping("/wordTemplateMorePage")
public void makeWordTemplateMorePage(@RequestBody Map<String, Object> param, HttpServletResponse response) {
List<Map<String, Object>> list=new ArrayList<>();
for (int i = 0; i < 5; i++) {
Map<String, Object> person = new HashMap<>();
person.put("name", "张三"+i);
person.put("nativePlace", "湖北武汉"+i);
person.put("age", 20+i);
person.put("nation", "汉族");
person.put("phone", "15685654524");
person.put("experience", "湖北武汉,工作三年,java工程师");
person.put("evaluate", "优秀,善良,老实");
person.put("picture", "");
list.add(person);
}
try {
ExcelUtils.WordTemplateExportMorePage(list, "E:/excel/个人简历模板.docx", param.get("fileName").toString(), response);
} catch (Exception e) {
e.printStackTrace();
}
}

3)页面添加按钮和请求方法,见源码。点击即可下载。

最新文章

  1. 使用LogMaster4Net实现应用程序日志的集中管理
  2. inteview que2
  3. three.js 显示一个绿色的正方体
  4. HTTP负载测试——Tsung
  5. android 录音的断点续传
  6. 68. Text Justification
  7. NSString NSMutableString copy mutableCopy retain weak strong整合
  8. huffman编码——原理与实现
  9. 【Backbone】 Backbone初探
  10. Linux环境下网卡配置
  11. Entity Framework——常见报错总结
  12. Android Gradle基于参数化配置实现差异化构建
  13. IdentityModel 中文文档(v1.0.0) 目录
  14. (引用)!Unicode,GBK以及UTF8的联系和区别
  15. Suricata规则编写——常用关键字
  16. GitHub Flow &amp; Git Flow 基于Git 的两种协作开发模式
  17. 编写高质量Python代码总结:待完成
  18. Ubuntu 下解压tar.xz方法
  19. centos7下安装指定版本mysql5.7.23
  20. 数据库中清空数据,保留表结构的sql语句

热门文章

  1. 图的广度优先遍历算法(BFS)
  2. 深入了解JavaScript中基于原型(prototype)的继承机制
  3. Jenkins(1)安装
  4. 【繁星Code】如何在EF将实体注释写入数据库中
  5. CF-gym/101810 J、T-Shirts Dilemma
  6. poj2443Set Operation (bitset)
  7. hdu5627 Clarke and MST (并查集)
  8. STL中pair容器的用法
  9. 11.PowerShell DSC之安装PowerShell Module
  10. 关于vmwaretools