1、POI
官方网址:https://poi.apache.org/
1.1、导包
<!-- poi支持的jar包 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.11</version>
</dependency>
1.2、创建Excel(完成99乘法表)
/*
* 99乘法表
**/
@Test
public void testCreateExcel() throws Exception {
/*
* 1、创建一个工作簿
* 放在内存中
* 里面什么都没有
* */
SXSSFWorkbook wb = new SXSSFWorkbook();
//2、创建一张sheet
Sheet sheet = wb.createSheet("99");
//3、创建行
for (int i = 1; i <= 9; i++) {
Row row = sheet.createRow(i - 1);
//4、创建列
for (int j = 1; j <= i; j++) {
Cell cell = row.createCell(j - 1);
//5、格子内写
cell.setCellValue(i + "×" + j + "=" + (i * j));
}
}
FileOutputStream out = new FileOutputStream("99.xlsx");
wb.write(out);
out.close();
// dispose of temporary files backing this workbook on disk
wb.dispose();
}
1.3、读取Excel
@Test
public void testReadExcel() throws Exception {
//1、读取文件到内容中
Workbook wb = WorkbookFactory.create(new FileInputStream("99.xlsx"));
//2、读取第一个表(根据表名或者序号。从0开始)
Sheet sheetAt = wb.getSheetAt(0);
//3、获取总行数
int lastRowNum = sheetAt.getLastRowNum();
for (int i = 0; i <lastRowNum ; i++) {
//4、获取到行
Row row = sheetAt.getRow(i);
//5、获取总列数
short lastCellNum = row.getLastCellNum();
//6、获取单元格
for (int j = 0; j < lastCellNum; j++) {
Cell cell = row.getCell(j);
System.out.print(cell.getStringCellValue()+" ");
}
System.out.println();
}
}
2、EasyPOI
官方文档:http://easypoi.mydoc.io/
2.1、导包
注意:EasyPOI的包和poi的包可能会产生冲突,所以先将poi的包删除
<!-- easypoi的支持 -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>3.2.0</version>
</dependency>
2.2、测试实体类POIEmployee
@ExcelTarget("emp")
public class POIEmployee {
/*
*加上Excel:表示会导出的列
* name:列名
*
* ExcelExportUtil工具类
* ExportParams:参数
* ,class:表明类型
* list:数据
* */
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("标题","表名"),POIEmployee.class, list);
FileOutputStream out = new FileOutputStream("eml.xlsx");
workbook.write(out);
out.close();
}
@Test
public void testCreate2() throws Exception{
POIDeartment pdm1 = new POIDeartment();
POIDeartment pdm2 = new POIDeartment();
pdm1.setId(1L);
pdm1.setName("IT");
pdm1.setAddress("lalala");
pdm2.setId(2L);
pdm2.setName("SSS");
pdm2.setAddress("3333");
//将数据放入list
List<POIDeartment> list = new ArrayList<>();
list.add(pdm1);
list.add(pdm2);
/*
* ExcelExportUtil工具类
* ExportParams:参数
* ,class:表明类型
* list:数据
* */
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("标题","表名"),POIDeartment.class, list);
FileOutputStream out = new FileOutputStream("dep.xlsx");
workbook.write(out);
out.close();
}
@Test
public void testImport() throws Exception{
//导入的参数
ImportParams params = new ImportParams();
params.setTitleRows(1);
params.setHeadRows(1);
List<POIEmployee> list = ExcelImportUtil.importExcel(new File("eml.xlsx"), POIEmployee.class, params);
list.forEach(e-> System.out.println(e));
}
}
3、导出
以Employee为例子
3.1、domain中的employee加注解
@Entity
@Table(name = "employee")
public class Employee extends BaseDomain {
@Excel(name = "用户名")
@NotNull
private String username;
private String password;
@Excel(name = "邮箱")
private String email;
@Excel(name = "年龄")
@Max(60)
@Min(value = 18,message = "年龄不能小于18")
private Integer age;
@Excel(name = "头像", type = 2)
private String headImage;
private Long isdelete;
/*
*如果添加了懒加载,会出现no Session异常
* 在web.xml中配置过滤器
* 又出现No serializer异常
* 两种方式解决:1、使用注解解决
* 2、配置
* */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
//@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
@ExcelEntity
private Department department;
@ManyToMany
@JoinTable(name = "employee_role", joinColumns = @JoinColumn(name = "employee_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private List<Role> roles = new ArrayList<>();
//get set
3.2、domain中的department加注解
@Entity
@Table(name = "department")
public class Department extends BaseDomain {
@Excel(name = "部门名称")
private String name;
private Long isdelete;
3.3、employee页面增加一个导出按钮
<form id="searchForm" method="post" action="/employee/export">
用户名: <input name="username" class="easyui-textbox" style="width:80px">
邮件: <input name="email" class="easyui-textbox" style="width:80px">
部门: <input class="easyui-combobox" name="departmentid"
data-options="valueField:'id',textField:'name',url:'/department/list',panelHeight:'auto'"/>
<a href="#" data-method="search" class="easyui-linkbutton" iconCls="icon-search">查询</a>
<button type="submit" class="easyui-linkbutton" iconCls="icon-search">导出</button>
</form>
3.4、EmployeeController
注意,这里 return NormalExcelConstants.EASYPOI_EXCEL_VIEW;需要在搜applicationContext-mvc.xml配置一个新的视图解析器,
@RequestMapping("/export")
public String export(EmployeeQuery query, ModelMap map, HttpServletRequest request) {
//获取相应的数据
List<Employee> list = employeeService.findAll(query);
System.out.println(list);
//拿到当前项目的真实路径
String realPath = request.getServletContext().getRealPath("");
list.forEach(e -> {
// /images/head/1.jpg
//设置图片路径
e.setHeadImage(realPath + e.getHeadImage());
});
//设置基本参数
ExportParams params = new ExportParams("员工数据", "员工表", ExcelType.XSSF);
//冻结
// params.setFreezeCol(2);
map.put(NormalExcelConstants.DATA_LIST, list); // 数据集合
map.put(NormalExcelConstants.CLASS, Employee.class);//导出实体
map.put(NormalExcelConstants.PARAMS, params);//参数
map.put(NormalExcelConstants.FILE_NAME, "员工");//文件名称
//easypoiExcelView
return NormalExcelConstants.EASYPOI_EXCEL_VIEW;//View名称
}
3.4、配置applicationContext-mvc.xml
order表示优先级,优先通过这个视图解析器,在这里找不到之后再去另一个视图解析器
4、导入
以Employee为例子
4.1、准备一个导入页面
4.2、新建一个ImportController
导入页面写在WEB-INF内,通过controller的第一个/index进入
如果不需要返回导出错误,即上传错误的文档不给予反馈提示,使用注释的 List list = ExcelImportUtil.importExcel(参数)方法。
如果想通过验证,将导入错误的内容通过新建一个错误附件excel表返回做为提示,使用ExcelImportResult result = ExcelImportUtil.importExcelMore(参数)方法。
可以返回错误信息的方法,得到的是一个结果集,里面包括成功和错误的内容。
EasyPOI自带一些注释的验证,如Max,NotNull,Min等,也可以自定义一个验证(下面代码展示)。
开启验证,必须有 params.setNeedVerfiy(true);
使用自定义验证 params.setVerifyHandler(employeeVerifyHandler);
@Controller
@RequestMapping("/import")
public class ImportController {
@Autowired
private IEmployeeService employeeService;
@Autowired
private IDepartmentService departmentService;
@Autowired
private EmployeeVerifyHandler employeeVerifyHandler;
@RequestMapping("/index")
public String index() {
return "import/index";
}
@RequestMapping("/employeeXlsx")
public String employeeXlsx(MultipartFile empFile, HttpServletResponse response) throws Exception {
//设置导入参数
ImportParams params = new ImportParams();
//设置需要验证为true
params.setNeedVerfiy(true);
//设计验证规则
params.setVerifyHandler(employeeVerifyHandler);
//设置标题和头的行数
//params.setTitleRows(1);
params.setHeadRows(1);
//把上传的文件变成数据 =》 导入时拿到更多的信息
ExcelImportResult<Employee> result = ExcelImportUtil.importExcelMore(
empFile.getInputStream(),
Employee.class, params);
//正确的数据直接保存
result.getList().forEach(e -> {
//设置一个默认密码
e.setPassword("123456");
//获取部门对象
if (e.getDepartment() != null) {
Department department = departmentService.findByName(e.getDepartment().getName());
e.setDepartment(department);
}
employeeService.save(e);
});
//有错误的数据返回工作薄给前台
/* result.getFailList().forEach(e -> {
System.out.println(e);
});*/
if(result.isVerfiyFail()){
Workbook workbook = result.getFailWorkbook();
//设置响应头
response.setHeader("content-disposition", "attachment;filename=error.xlsx");
ServletOutputStream out = response.getOutputStream();
workbook.write(out);
out.flush();
}
return "import/index";
}
/* @RequestMapping("/employeeXlsx")
public String employeeXlsx(MultipartFile empFile) throws Exception {
// System.out.println(empFile.getName()); //empFile(上传控件名称)
// System.out.println(empFile.getOriginalFilename()); //文件名称
// System.out.println(empFile.getContentType()); //文件的mime类型:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
// System.out.println(empFile.getSize()); //文件大小
//设置导入参数
ImportParams params = new ImportParams();
//设置标题和头的行数
//params.setTitleRows(1);
params.setHeadRows(1);
//把上传的文件变成数据
List<Employee> list = ExcelImportUtil.importExcel(
empFile.getInputStream(),
Employee.class, params);
//保存到数据库
list.forEach(e-> {
//设置一个默认密码
e.setPassword("123456");
//获取部门对象
if(e.getDepartment()!=null) {
Department department = departmentService.findByName(e.getDepartment().getName());
e.setDepartment(department);
}
employeeService.save(e);
});
return "import";
}
*/
4.3、验证功能
4.3.1、导包JSR 303规范
<!-- JSR 303 规范验证包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
4.3.2、验证注解
@NotNull(message = “用户名不为空”)
@Max(value = 80,message = “max 最大值不能超过80”)
4.3.3、自定义验证用户名唯一
EmployeeVerifyHandler 实现IExcelVerifyHandler
注意:扫描它,把它交给Spring管理
4.3.2、验证注解
@NotNull(message = “用户名不为空”)
@Max(value = 80,message = “max 最大值不能超过80”)
等等
4.3.3、自定义验证用户名唯一
EmployeeVerifyHandler 实现IExcelVerifyHandler
注意:扫描它,把它交给Spring管理
<context:component-scan base-package="com.xuxusheng.aisell.common"/>
@Component
public class EmployeeVerifyHandler implements IExcelVerifyHandler<Employee> {
@Autowired
private IEmployeeService employeeService;
@Override
public ExcelVerifyHandlerResult verifyHandler(Employee employee) {
Employee emp = employeeService.findByUsername(employee.getUsername());
//如果员工存在,代表重复了,就应该返回false
if (emp != null) {
return new ExcelVerifyHandlerResult(false, "用户名已经存在");
}
return new ExcelVerifyHandlerResult(true);
}
}
来源:CSDN
作者:芒果咖啡冰淇淋
链接:https://blog.csdn.net/weixin_45695995/article/details/103641051