300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > iHRM 人力资源管理系统_第7章 POI报表的入门

iHRM 人力资源管理系统_第7章 POI报表的入门

时间:2024-06-07 13:02:20

相关推荐

iHRM 人力资源管理系统_第7章 POI报表的入门

iHRM 人力资源管理系统_第7章 POI报表的入门

文章目录

iHRM 人力资源管理系统_第7章 POI报表的入门1 员工管理1.1 需求分析1.2 数据库表概述1.3 **代码实现** 1.4 服务发现组件 Eureka1.4.1 Eureka服务端开发1.4.2 微服务注册 1.5 微服务调用组件Feign1.5.1 简介1.5.2 快速体验 七、POI报表2、服务统一管理<1>、服务发现组件Eureka(1)、Eureka服务端(2)、微服务注册 <2>、微服务调用组件Feign(1)、简介(2)、操作 3、POI报表的概述<1>、需求说明<2>、Excel的俩种形式<3>、常见的Excel操作工具<4>、POI的概述<5>、使用场景 4、POI入门操作<1>、搭建环境<2>、结构说明<3>、API说明<4>、基本操作(1)、使用POI创建一个Excel(2)、创建单元格并写入内容(3)、单元格样式处理(4)、绘制图形(5)、读取Excel并解析 5、POI报表导入<1>、需求分析<2>、员工导入(1)、环境搭建(2)、Excel上传(3)、调用企业微服务获取部门数据 6、POI报表导出<1>、需求分析<2>、报表导出(1)、步骤分析(2)、实现

1 员工管理

1.1 需求分析

企业员工管理是人事资源管理系统中最重要的一个环节,分为对员工入职,转正,离职,调岗,员工报表导入导出

等业务逻辑。需求看似复杂,实际上都是对数据库表的基本操作。

1.2 数据库表概述

对于员工操作而言,涉及到的数据库表如下表格说明:

1.3代码实现

由于此部分内容全部围绕的基本CRUD操作,为了节省课程时间,员工管理的代码以资料的形式给各位学员下发, 学员们直接导入到工程即可。重点功能突出讲解即可

1.3.1 服务端实现

(1) 创建员工微服务 ihrm_employee(2) 配置文件 application.yml(3) 配置Shiro核心配置类ShiroConfiguration(4) 配置启动类EmployeeApplication(5)导入资源中提供的基本Controller,Service,Dao,Domain代码

1.3.2 前端实现

导入资源中提供的前端代码。

1.4 服务发现组件 Eureka

Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能。Eureka包含两个组件:Eureka Server和Eureka Client。

Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就别一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。

1.4.1 Eureka服务端开发

(1) 创建ihrm_eureka模块

(2) 引入依赖 父工程pom.xml定义SpringCloud版本

<dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Finchley.M9</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

ihrm_eureka模块pom.xml引入eureka-server

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eurekaserver</artifactId></dependency></dependencies>

(3)添加application.yml

#eureka服务的配置文件server:port: 6868 #服务端口eureka:client:registerWithEureka: false #是否将自己注册到Eureka服务中,本身就是所有无需注册fetchRegistry: false #是否从Eureka中获取注册信息serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址defaultZone: http://127.0.0.1:${server.port}/eureka/

(4) 配置启动类

package com.ihrm.eureka;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.flix.eureka.server.EnableEurekaServer;/*** eureka服务端的启动类*/@SpringBootApplication@EnableEurekaServer //开启eureka服务端配置public class EurekaServer {public static void main(String[] args) {SpringApplication.run(EurekaServer.class,args);}}

1.4.2 微服务注册

我们现在就将所有的微服务都注册到Eureka中,这样所有的微服务之间都可以互相调用了。

(1)将其他微服务模块添加依赖【将其他模块注册到Eureka】

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

(2)修改每个微服务的application.yml,添加注册eureka服务的配置

eureka:client:service-url:defaultZone: http://localhost:6868/eurekaistance:prefer-ip-address: true

(3)修改每个服务类的启动类,添加注解

@EnableEurekaClient

1.5 微服务调用组件Feign

1.5.1 简介

Feign是简化Java HTTP客户端开发的工具(java-to-httpclient-binder),它的灵感来自于Retrofit、JAXRS-2.0和

WebSocket。Feign的初衷是降低统一绑定Denominator到HTTP API的复杂度,不区分是否为restful

1.5.2 快速体验

我们现在在系统微服务调用企业微服务的方法(根据ID查询部门)

(1)在ihrm_system模块添加依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

(2)修改ihrm_system模块的启动类,添加注解

@EnableDiscoveryClient@EnableFeignClients

(3)在Ihrm_system模块创建com.ihrm.system.client包,包下创建接口

//@FeignClient注解用于指定从哪个服务中调用功能 ,注意里面的名称与被调用的服务名保持一致@FeignClient(value = "ihrm-company")public interface DepartmentFeignClient {//@RequestMapping注解用于对被调用的微服务进行地址映射@RequestMapping(value = "/company/departments/{id}/", method = RequestMethod.GET)public Department findById(@PathVariable("id") String id) throws Exception;}

(4)修改Ihrm_system模块的 UserController

@Autowiredprivate DepartmentFeignClient departmentFeignClient;//测试通过系统微服务调用企业微服务方法@RequestMapping(value = "/test/{id}")public void findDeptById(@PathVariable String id){Department dept = departmentFeignClient.findById(id);System.out.println(dept);}

(5)配置Feign拦截器添加请求头

/*** FeignConfiguration 过滤器,配置请求头信息*/@Configurationpublic class FeignConfiguration {@Beanpublic RequestInterceptor requestInterceptor() {return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate template) {ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if (attributes != null) {HttpServletRequest request = attributes.getRequest();Enumeration<String> headerNames = request.getHeaderNames();if (headerNames != null) {while (headerNames.hasMoreElements()) {String name = headerNames.nextElement();String values = request.getHeader(name);template.header(name, values);}}}}};}}

七、POI报表

2、服务统一管理

<1>、服务发现组件Eureka

Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netfix中,实现SpringCloud的服务发现功能。Eureka包含两个组件:Eureka Server和Eureka Client

Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就别一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动之后,将会向Eureka Server发送心跳,默认周期是30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)

(1)、Eureka服务端

1、在父工程中引入SpringCloud相关依赖,指定其版本

<dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Finchley.SR1</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

2、创建ihrm_eureka模块导入相关依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>

3、在resources目录下创建application.yml添加Eureka服务的相关配置

#eureka服务的配置文件server:port: 6868 #服务端口eureka:client:registerWithEureka: false #是否将自己注册到Eureka服务中,本身就是所有无需注册fetchRegistry: false #是否从Eureka中获取注册信息serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址defaultZone: http://127.0.0.1:${server.port}/eureka/

4、创建Eureka服务端的启动类

package com.ihrm.eureka;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.flix.eureka.server.EnableEurekaServer;/*** eureka服务端的启动类*/@SpringBootApplication@EnableEurekaServer //开启eureka服务端配置public class EurekaServer {public static void main(String[] args) {SpringApplication.run(EurekaServer.class,args);}}

(2)、微服务注册

1、在企业微服务、员工微服务和系统微服务的pom中添加依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

2、在application,yml中添加eureka的服务地址

#注册到eureka的服务地址eureka:client:service-url:defaultZone: http://localhost:6868/eureka/

3、在微服务的启动类中添加如下注解即可:

@EnableEurekaClient

<2>、微服务调用组件Feign

(1)、简介

Feign是简化java HTTP客户端开发的工具(java-to-httpclient-binder),灵感来自Retrofit、JAXRS-2.0和WebSocket。Feign初衷是降低统一绑定Denominator到HTTP API的复杂度,不区分是否为restful

(2)、操作

1、在系统微服务的pom中引入Feign的相关依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

2、修改ihrm-system启动类,添加注解

@EnableDiscoveryClient@EnableFeignClients

3、创建DepartmentFeignClient接口

package com.ihrm.system.client;import mon.entity.Result;import com.pany.Department;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;/*** 声明接口,通过feign调用其他微服务*///声明调用的微服务名称@FeignClient("ihrm-company") //模块在eureka注册名public interface DepartmentFeignClient {/*** 调用微服务的接口://模块在eureka注册名下面的方法*/@RequestMapping(value="/company/department/{id}",method = RequestMethod.GET)Result findById(@PathVariable(value="id") String id);

4、修改ihrm-system的UserController

/*** 测试Feign组件* 调用系统微服务的/test接口传递部门id,通过feign调用部门微服务获取部门信息*/@RequestMapping(value = "/test/{id}", method = RequestMethod.GET)public Result testFeign(@PathVariable(value = "id") String id) {Result result = departmentFeignClient.findById(id);return result;}

5、在ihrm_common模块中配置Feign拦截器添加请求头

Feign拦截器的作用:

获取到浏览器发送的请求头使用Feign调用其他微服务的时候,将请求头信息添加上

package mon.feign;import feign.RequestInterceptor;import feign.RequestTemplate;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.util.Enumeration;@Configurationpublic class FeignConfiguration {//配置feign拦截器,解决请求头问题@Beanpublic RequestInterceptor requestInterceptor() {return new RequestInterceptor(){//获取所有浏览器发送的请求属性,请求头赋值到feign@Overridepublic void apply(RequestTemplate requestTemplate) {//请求属性ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if(attributes != null) {HttpServletRequest request = attributes.getRequest();//获取浏览器发起的请求头Enumeration<String> headerNames = request.getHeaderNames();if (headerNames != null) {while (headerNames.hasMoreElements()){String name = headerNames.nextElement(); //请求头名称 AuthorizationString value = request.getHeader(name);//请求头数据 "Bearer b1dbb4cf-7de6-41e5-99e2-0e8b7e8fe6ee"requestTemplate.header(name,value);}}}}};}}

3、POI报表的概述

<1>、需求说明

在企业级应用开发中,Excel报表是一种最常见的报表需求,Excel报表开发一般分为两种形式:

为了方便操作,基于Excel的报表批量上传数据通过Java代码生成Excel报表

<2>、Excel的俩种形式

目前市面上的Excel分为两个大的版本Excel和Excel及以上两个版本,两者的区别如下:

Excel是一个特有的二进制根式,其核心是复合文档类型的结构,存储数据量较小;Excel的核心结构是XML类型的结构,采用的是基于XML的压缩方式,使其占用的空间更小,操作效率更高。

<3>、常见的Excel操作工具

Java中常见的用来操作Excel的方式一般有两种:JXL和POI

JXL只能对Excel进行操作,属于比较老的框架,只支持Excel95-2000的版本,现在已经停止更新和维护POI是Apache的项目,可对微软的Word、Excel、PPT进行操作,包括office和,Excel和Excel。POI现在一直在更新,因此现在主流使用POI。

<4>、POI的概述

Apache POI是Apache软件基金会的开源项目,由Java编写的免费开源的跨平台的Java API,Apache POI提供API给Java语言操作Microsoft Office的功能。

<5>、使用场景

数据报表生成数据备份数据批量上传

4、POI入门操作

<1>、搭建环境

创建一个maven工程,导入相关依赖

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.0.1</version></dependency>

<2>、结构说明

HSSF提供读写Microsoft Excel XLS格式档案的功能

XSSF提供读写Microsoft Excel OOXML XLSX格式档案的功能

HWPF提供读写Microsoft Word DOC格式档案的功能

HSLF提供读写Microsoft PowerPoint格式档案的功能

HDGF提供读Microsoft Visio格式档案的功能

HPBF提供读Microsoft Publisher格式档案的功能

HSMF提供读Microsoft Outlook格式档案的功能

<3>、API说明

<4>、基本操作

(1)、使用POI创建一个Excel

package poi.test;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import org.junit.Test;import java.io.FileOutputStream;public class PoiTest {/*** 1、使用POI创建Excel*/@Testpublic void PoiTest01() throws Exception{//1、创建工作簿Workbook workbook = new XSSFWorkbook();//2、创建表单Sheet sheet = workbook.createSheet("test");//3、文件输出流FileOutputStream fos = new FileOutputStream("/Users/xiaotongxin/work/poi/test.xlsx");//4、写入文件workbook.write(fos);//5、关闭流fos.close();}}

(2)、创建单元格并写入内容

/*** 2、创建单元格并写入内容*/@Testpublic void PoiTest02() throws Exception{//创建工作簿Workbook workbook = new XSSFWorkbook();//创建表单Sheet sheet = workbook.createSheet("test");//创建行对象 参数:索引(从0开始)Row row = sheet.createRow(3);//创建单元格对象 参数:索引(从0开始)Cell cell = row.createCell(3);cell.setCellValue("I Love You Forever");//文件输出流FileOutputStream fos = new FileOutputStream("/Users/xiaotongxin/IdeaProjects/hrm/poi-test/src/poi/test1.xlsx");//写入文件workbook.write(fos);//关闭流fos.close();}

测试结果如下:

(3)、单元格样式处理

从上例可以看出,单元格内的内容已经超出了边框,这时需要对写入的内容做一些相应的处理,如字体、字号、边框、行高列宽等等。

/*** 3、单元格样式*/@Testpublic void PoiTest03() throws Exception{//创建工作簿Workbook workbook = new XSSFWorkbook();//创建表单Sheet sheet = workbook.createSheet("test");//创建行对象 参数:索引(从0开始)Row row = sheet.createRow(3);//创建单元格对象 参数:索引(从0开始)Cell cell = row.createCell(3);cell.setCellValue("I Love You Forever");/*** 样式处理*///创建样式对象CellStyle cellStyle = workbook.createCellStyle();//设置边框cellStyle.setBorderTop(BorderStyle.HAIR);cellStyle.setBorderBottom(BorderStyle.HAIR);cellStyle.setBorderLeft(BorderStyle.HAIR);cellStyle.setBorderRight(BorderStyle.HAIR);//创建字体对象Font font = workbook.createFont();font.setFontName("仿宋"); //设置字体font.setFontHeightInPoints((short) 15); //设置字号cellStyle.setFont(font); //字体对象绑定到样式对象中row.setHeightInPoints(50); //行高sheet.setColumnWidth(3, 30 * 256); //列宽 字符宽度cellStyle.setAlignment(HorizontalAlignment.CENTER); //水平居中cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //垂直居中cell.setCellStyle(cellStyle); //样式对象绑定到单元格对象中//文件输出流FileOutputStream fos = new FileOutputStream("/Users/xiaotongxin/IdeaProjects/hrm/poi-test/src/poi/test2.xlsx");//写入文件workbook.write(fos);//关闭流fos.close();}

运行结果如下:

(4)、绘制图形

在实际中,通常需要在Excel表格中添加一些简单的图片

/*** 4、插入图形*/@Testpublic void PoiTest04() throws Exception{//创建工作簿Workbook workbook = new XSSFWorkbook();//创建表单Sheet sheet = workbook.createSheet("test");//读取图片的文件流FileInputStream fis = new FileInputStream("/Users/xiaotongxin/IdeaProjects/hrm/poi-test/src/poi/1.jpg");//转换成二进制数组byte[] bytes = IOUtils.toByteArray(fis);fis.read(bytes);//向POI内存中添加一张图片,返回的值是图片在图片集合中的索引值int index = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);//绘制图片工具类CreationHelper helper = workbook.getCreationHelper();//创建一个绘图对象Drawing<?> patriarch = sheet.createDrawingPatriarch();//创建锚点、设置图片的坐标ClientAnchor anchor = helper.createClientAnchor();anchor.setRow1(1);anchor.setCol1(1);//绘制图片Picture picture = patriarch.createPicture(anchor, index);picture.resize();//自适应渲染图片//文件输出流FileOutputStream fos = new FileOutputStream("/Users/xiaotongxin/IdeaProjects/hrm/poi-test/src/poi/test3.xlsx");//写入文件workbook.write(fos);//关闭流fos.close();}

运行结果如下:

(5)、读取Excel并解析

在实际开发工作中,我们往往不是创建工作簿,大部分都是读取已有的Excel并对其中的数据进行分析,从中获取我们需要的信息。

/*** 5、读取Excel并解析*sheet.getLastRowNum():最后一行索引*row.getLastCellNum():最后一个单元格号码*/@Testpublic void PoiTest05() throws Exception{//创建工作簿Workbook wor-kbook = new XSSFWorkbook("/Users/xiaotongxin/IdeaProjects/hrm/poi-test/src/poi/hr-demo.xlsx");//获取sheetSheet sheet = workbook.getSheetAt(0);//获取sheet每一行和每一个单元格for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum ++){Row row = sheet.getRow(rowNum);StringBuilder stringBuilder = new StringBuilder();for (int cellNum = 0; cellNum < row.getLastCellNum(); cellNum ++){//根据索引获取每一个单元格Cell cell = row.getCell(cellNum);//获取每一个单元格中的内容Object value = getValue(cell);stringBuilder.append(value).append(",");}System.out.println(stringBuilder.toString());}}/*** 根据传入的cell判断单元格中内容的格式,从而获取到相应的值*/public static Object getValue(Cell cell){//获取单元格的属性CellType cellType = cell.getCellType();//根据单元格属性获取数据Object value = null;switch (cellType){case STRING:value = cell.getStringCellValue();break;case BOOLEAN:value = cell.getBooleanCellValue();break;case NUMERIC:if (DateUtil.isCellDateFormatted(cell)){//日期value = cell.getDateCellValue();}else {//数字value = cell.getNumericCellValue();}break;case FORMULA: //公式value = cell.getCellFormula();}return value;}

运行结果如下:

5、POI报表导入

<1>、需求分析

实现批量导入员工功能,页面端上传Excel表格,服务端解析表格获取数据,批量新增用户

<2>、员工导入

(1)、环境搭建

在父工程中导入相关依赖

<!--POI--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.0.1</version></dependency>

(2)、Excel上传

1、在系统微服务中的UserController中添加导入Excel添加用户的方法

/*** 导入Excel,添加用户* 文件上传:SpringBoot*/@RequestMapping(value="/user/import",method = RequestMethod.POST)public Result importUser(@RequestParam(name="file") MultipartFile file) throws Exception {//1.解析Excel//1.1.根据Excel文件创建工作簿Workbook wb = new XSSFWorkbook(file.getInputStream());//1.2.获取SheetSheet sheet = wb.getSheetAt(0);//参数:索引//1.3.获取Sheet中的每一行,和每一个单元格//2.获取用户数据列表List<User> list = new ArrayList<>();System.out.println(sheet.getLastRowNum());for (int rowNum = 1; rowNum<= sheet.getLastRowNum() ;rowNum ++) {//从第二行开始读取,索引是1Row row = sheet.getRow(rowNum);//根据索引获取每一个行Object [] values = new Object[row.getLastCellNum()];for(int cellNum=1;cellNum< row.getLastCellNum(); cellNum ++) {Cell cell = row.getCell(cellNum);Object value = getCellValue(cell);values[cellNum] = value;}User user = new User(values);list.add(user);}//3.批量保存用户userService.saveAll(list,companyId,companyName);return new Result(ResultCode.SUCCESS);}

2、在ihrm_common工程User类中添加相应的构造方法

public User(Object [] values) {//用户名手机号工号 聘用形式入职时间部门编码this.username = values[1].toString();this.mobile = values[2].toString();this.workNumber = new DecimalFormat("#").format(values[3]).toString();this.formOfEmployment =((Double) values[4]).intValue();this.timeOfEntry = (Date) values[5];this.departmentId = values[6].toString(); //部门编码 != 部门id}

3、在系统微服务中的UserService中添加批量保存用户的方法

@Autowiredprivate DepartmentFeignClient departmentFeignClient;/*** 批量保存用户*/@Transactional //事务处理public void saveAll(List<User> list ,String companyId,String companyName){for (User user : list) {//默认密码user.setPassword(new Md5Hash("123456",user.getMobile(),3).toString());//iduser.setId(idWorker.nextId()+"");//基本属性user.setCompanyId(companyId);user.setCompanyName(companyName);user.setInServiceStatus(1);user.setEnableState(1);user.setLevel("user");//填充部门的属性Department department = departmentFeignClient.findByCode(user.getDepartmentId(), companyId);if(department != null) {user.setDepartmentId(department.getId());user.setDepartmentName(department.getName());}userDao.save(user);}}

4、在企业微服务中的DepartmentController添加findByCode方法【远程调用

@RequestMapping(value="/department/search",method = RequestMethod.POST)public Department findByCode(@RequestParam(value="code") String code,@RequestParam(value="companyId") String companyId) {Department dept = departmentService.findByCode(code,companyId);return dept;}

5、在企业微服务中的DepartmentService添加findByCode方法

/*** 根据部门编码和企业id查询部门*/public Department findByCode(String code, String companyId) {return departmentDao.findByCodeAndCompanyId(code,companyId);}

6、在企业微服务中的DepartmentDao添加findByCodeAndCompanyId抽象方法

public interface DepartmentDao extends JpaRepository<Department,String> ,JpaSpecificationExecutor<Department> {Department findByCodeAndCompanyId(String code, String companyId);}

(3)、调用企业微服务获取部门数据

因此要进行跨服务调用方法,因此在ihrm_system微服务中的DepartmentFeignClient接口中添加和企业微服务的DepartmentController中findByCode相类似的方法,注意DepartmentFeignClient的@RequestMapping的value值要写全请求地址,千万不要省略

@RequestMapping(value="/company/department/search",method = RequestMethod.POST)Department findByCode(@RequestParam(value="code") String code, @RequestParam(value="companyId") String companyId);

6、POI报表导出

<1>、需求分析

完成当月人事报表的导出:包含当月入职员工信息和离职员工的信息。

<2>、报表导出

(1)、步骤分析

1、构造Excel表格数据

2、创建工作簿

3、创建sheet

4、创建行对象

5、创建单元格对象

6、填充数据、设置样式

7、下载

(2)、实现

1、在ihrm_common_model中创建返回值对象

package com.ihrm.domain.employee.response;import com.ihrm.domain.employee.EmployeeResignation;import com.ihrm.domain.employee.UserCompanyPersonal;import com.ihrm.domain.poi.ExcelAttribute;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;import lombok.ToString;import org.springframework.beans.BeanUtils;@Getter@Setter@NoArgsConstructor@ToStringpublic class EmployeeReportResult {private String userId;private String username;private String departmentName;private String mobile;private String timeOfEntry;private String companyId;private String sex;/*** 出生日期*/private String dateOfBirth;/*** 最高学历*/private String theHighestDegreeOfEducation;/*** 国家地区*/private String nationalArea;/*** 护照号*/private String passportNo;/*** 身份证号*/private String idNumber;/*** 身份证照片-正面*/private String idCardPhotoPositive;/*** 身份证照片-背面*/private String idCardPhotoBack;/*** 籍贯*/private String nativePlace;/*** 民族*/private String nation;/*** 英文名*/private String englishName;/*** 婚姻状况*/private String maritalStatus;/*** 员工照片*/private String staffPhoto;/*** 生日*/private String birthday;/*** 属相*/private String zodiac;/*** 年龄*/private String age;/*** 星座*/private String constellation;/*** 血型*/private String bloodType;/*** 户籍所在地*/private String domicile;/*** 政治面貌*/private String politicalOutlook;/*** 入党时间*/private String timeToJoinTheParty;/*** 存档机构*/private String archivingOrganization;/*** 子女状态*/private String stateOfChildren;/*** 子女有无商业保险*/private String doChildrenHaveCommercialInsurance;/*** 有无违法违纪行为*/private String isThereAnyViolationOfLawOrDiscipline;/*** 有无重大病史*/private String areThereAnyMajorMedicalHistories;/*** QQ*/private String qq;/*** 微信*/private String wechat;/*** 居住证城市*/private String residenceCardCity;/*** 居住证办理日期*/private String dateOfResidencePermit;/*** 居住证截止日期*/private String residencePermitDeadline;/*** 现居住地*/private String placeOfResidence;/*** 通讯地址*/private String postalAddress;/*** 联系手机*/private String contactTheMobilePhone;/*** 个人邮箱*/private String personalMailbox;/*** 紧急联系人*/private String emergencyContact;/*** 紧急联系电话*/private String emergencyContactNumber;/*** 社保电脑号*/private String socialSecurityComputerNumber;/*** 公积金账号*/private String providentFundAccount;/*** 银行卡号*/private String bankCardNumber;/*** 开户行*/private String openingBank;/*** 学历类型*/private String educationalType;/*** 毕业学校*/private String graduateSchool;/*** 入学时间*/private String enrolmentTime;/*** 毕业时间*/private String graduationTime;/*** 专业*/private String major;/*** 毕业证书*/private String graduationCertificate;/*** 学位证书*/private String certificateOfAcademicDegree;/*** 上家公司*/private String homeCompany;/*** 职称*/private String title;/*** 简历*/private String resume;/*** 有无竞业限制*/private String isThereAnyCompetitionRestriction;/*** 前公司离职证明*/private String proofOfDepartureOfFormerCompany;/*** 备注*/private String remarks;/*** 离职时间*/private String resignationTime;/*** 离职类型*/private String typeOfTurnover;/*** 申请离职原因*/private String reasonsForLeaving;public EmployeeReportResult(UserCompanyPersonal personal, EmployeeResignation resignation) {BeanUtils.copyProperties(personal,this);if(resignation != null) {BeanUtils.copyProperties(resignation,this);}}}

2、在DAO层添加方法

@Query(value="select new com.ihrm.domain.employee.response.EmployeeReportResult(a,b) from UserCompanyPersonal a " +"LEFT JOIN EmployeeResignation b on a.userId=b.userId where panyId=?1 and a.timeOfEntry like?2 or (" +"b.resignationTime like ?2)")List<EmployeeReportResult> findByReport(String companyId,String month);

3、Service层

public List<EmployeeReportResult> findByReport(String companyId,String month) {return userCompanyPersonalDao.findByReport(companyId,month+"%");}

4、Controller层

/*** 当月人事报表导出* 参数:*年月-月(-02%)*/@RequestMapping(value = "/export/{month}", method = RequestMethod.GET)public void export(@PathVariable String month) throws Exception {//1.获取报表数据List<EmployeeReportResult> list = userCompanyPersonalService.findByReport(companyId,month);//2.构造Excel//创建工作簿//SXSSFWorkbook : 百万数据报表//Workbook wb = new XSSFWorkbook();SXSSFWorkbook wb = new SXSSFWorkbook(100); //阈值,内存中的对象数量最大数量//构造sheetSheet sheet = wb.createSheet();//创建行//标题String [] titles = "编号,姓名,手机,最高学历,国家地区,护照号,籍贯,生日,属相,入职时间,离职类型,离职原因,离职时间".split(",");//处理标题Row row = sheet.createRow(0);int titleIndex=0;for (String title : titles) {Cell cell = row.createCell(titleIndex++);cell.setCellValue(title);}int rowIndex = 1;Cell cell = null;for (EmployeeReportResult employeeReportResult : list) {row = sheet.createRow(rowIndex++);// 编号,cell = row.createCell(0);cell.setCellValue(employeeReportResult.getUserId());// 姓名,cell = row.createCell(1);cell.setCellValue(employeeReportResult.getUsername());// 手机,cell = row.createCell(2);cell.setCellValue(employeeReportResult.getMobile());// 最高学历,cell = row.createCell(3);cell.setCellValue(employeeReportResult.getTheHighestDegreeOfEducation());// 国家地区,cell = row.createCell(4);cell.setCellValue(employeeReportResult.getNationalArea());// 护照号,cell = row.createCell(5);cell.setCellValue(employeeReportResult.getPassportNo());// 籍贯,cell = row.createCell(6);cell.setCellValue(employeeReportResult.getNativePlace());// 生日,cell = row.createCell(7);cell.setCellValue(employeeReportResult.getBirthday());// 属相,cell = row.createCell(8);cell.setCellValue(employeeReportResult.getZodiac());// 入职时间,cell = row.createCell(9);cell.setCellValue(employeeReportResult.getTimeOfEntry());// 离职类型,cell = row.createCell(10);cell.setCellValue(employeeReportResult.getTypeOfTurnover());// 离职原因,cell = row.createCell(11);cell.setCellValue(employeeReportResult.getReasonsForLeaving());// 离职时间cell = row.createCell(12);cell.setCellValue(employeeReportResult.getResignationTime());}//3.完成下载ByteArrayOutputStream os = new ByteArrayOutputStream();wb.write(os);new DownloadUtils().download(os,response,month+"人事报表.xlsx");}

5、DownloadUtils工具类

package mon.utils;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletResponse;import java.io.ByteArrayOutputStream;import java.io.IOException;public class DownloadUtils {public void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException {response.setContentType("application/octet-stream");returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1"));//保存的文件名,必须和页面编码一致,否则乱码response.addHeader("content-disposition","attachment;filename=" + returnName);response.setContentLength(byteArrayOutputStream.size());ServletOutputStream outputstream = response.getOutputStream();//取得输出流byteArrayOutputStream.writeTo(outputstream);//写到输出流byteArrayOutputStream.close();//关闭outputstream.flush();//刷数据}}

cell = row.createCell(12);cell.setCellValue(employeeReportResult.getResignationTime());}//3.完成下载ByteArrayOutputStream os = new ByteArrayOutputStream();wb.write(os);new DownloadUtils().download(os,response,month+"人事报表.xlsx");}

5、DownloadUtils工具类```javapackage mon.utils;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletResponse;import java.io.ByteArrayOutputStream;import java.io.IOException;public class DownloadUtils {public void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException {response.setContentType("application/octet-stream");returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1"));//保存的文件名,必须和页面编码一致,否则乱码response.addHeader("content-disposition","attachment;filename=" + returnName);response.setContentLength(byteArrayOutputStream.size());ServletOutputStream outputstream = response.getOutputStream();//取得输出流byteArrayOutputStream.writeTo(outputstream);//写到输出流byteArrayOutputStream.close();//关闭outputstream.flush();//刷数据}}

现在就可以实现将员工的数据以Excel表格的形式导出。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。