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

文章目录

  • iHRM 人力资源管理系统_第7章 POI报表的入门
      • 1 员工管理
        • 1.1 需求分析
        • 1.2 数据库表概述
        • 1.3 **代码实现**
      • 1.4 服务发现组件 Eureka
        • 1.4.1 Eureka服务端开发
        • 1.4.2 微服务注册
      • 1.5 微服务调用组件Feign
        • 1.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.springframework.cloud.netflix.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.springframework.cloud.netflix.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 com.ihrm.common.entity.Result;
import com.ihrm.domain.company.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 com.ihrm.common.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;@Configuration
public 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分为两个大的版本Excel2003和Excel2007及以上两个版本,两者的区别如下:

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

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

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

  • JXL只能对Excel进行操作,属于比较老的框架,只支持Excel95-2000的版本,现在已经停止更新和维护
  • POI是Apache的项目,可对微软的Word、Excel、PPT进行操作,包括office2003和2007,Excel2003和Excel2007。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
@ToString
public 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 a.companyId=?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层

 /*** 当月人事报表导出*  参数:*      年月-月(2018-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 com.ihrm.common.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工具类```java
package com.ihrm.common.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表格的形式导出。

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

  1. iHRM 人力资源管理系统_第8章POI报表高级应用

    iHRM 人力资源管理系统_第8章POI报表高级应用 文章目录 iHRM 人力资源管理系统_第8章POI报表高级应用 八.POI报表高级应用 1.模板打印 <1>.概述 <2> ...

  2. iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门

    iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门 文章目录 iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门 PDF报表入门 3 ...

  3. iHRM 人力资源管理系统_第2章、数据库设计与前端框架

    文章目录 第2章.数据库设计与前端框架 1.多租户SaaS平台的数据库方案 <1>.多租户概述 <2>.需求分析 <3>.多租户的数据库方案分析 (1).独立数据库 ...

  4. Java实战教程:《iHRM 人力资源管理系统》

    iHRM是一款基于SaaS平台的人力资源管理系统, 企业通过该系统可以完成员工管理.审批管理.考勤管理.社保公积金管理.薪资管理等功能,为企业的人力资源管理提供一站式解决方案. Java项目SaaS移 ...

  5. 基于java的人力资源管理系统_基于JavaWeb的企业人力资源管理系统的设计与实现...

    <基于Java Web的企业人力资源管理系统的设计与实现.doc>由会员分享,可免费在线阅读全文,更多与<基于Java Web的企业人力资源管理系统的设计与实现>相关文档资源请 ...

  6. 基于java的人力资源管理系统_基于Java Web的企业人力资源管理系统的设计与实现(样例3)...

    <基于Java Web的企业人力资源管理系统的设计与实现.doc>由会员分享,可免费在线阅读全文,更多与<基于Java Web的企业人力资源管理系统的设计与实现>相关文档资源请 ...

  7. 管理系统中计算机应用课件,管理系统中计算机应用_第三章课件.ppt

    <管理系统中计算机应用_第三章课件.ppt>由会员分享,提供在线免费全文阅读可下载,此文档格式为ppt,更多相关<管理系统中计算机应用_第三章课件.ppt>文档请在天天文库搜索 ...

  8. 员工薪资管理系统在netbeans中的全部代码_北京哪家人力资源管理系统比较靠谱...

    北京哪家人力资源管理系统比较靠谱 作为一个近十几年的人力资源系统开发员来讲,开发过和使用过多款优秀的人力资源管理系统,也遇到过不好用户体验度比较差的软件,导致人力资源管理越来与困难的事情,觉得十分有必 ...

  9. 客户管理系统代码项目_西安人力资源管理系统如何有效管理销售,提高工作的效率...

    人力资源管理系统如何有效管理销售,提高工作的效率 发布人:汇聚华企管理系统 原创分享 销售过程会出现的管理问题各种各样,比如说库存状态,比如说报价,又比如说客户关系管理,其实这些管理上的问题都能用软件 ...

最新文章

  1. 自建通用Makefile 分享
  2. 360 开源企业级 Kubernetes 多集群管理平台 Wayne
  3. nginx处理http(http变量篇)
  4. php服务docker化,docker化你的PHP应用环境Nginx PHP-FPM
  5. 2019款iPhone XR新配色机模上手:就是这个味儿
  6. week7 read
  7. python爬取网页文本_手把手教你如何用Python爬取网站文本信息
  8. paip.提升用户体验----记住用户名与自动登录
  9. 2018年华尔街高盛、花旗等投行业绩创新高!
  10. bzoj3224 普通平衡树(splay 模板)
  11. curl的安装及使用
  12. 计算机为啥启用不了网络发现,Windows7系统无法启用网络发现怎么解决?
  13. Air202学习 三 (模块串口使用)
  14. 随机过程之基本概念(一)
  15. CAD全称AutoCAD (全系列中文版软件+注册机下载) 2004-2020 安装视频教程
  16. 【FPGA——工具篇】:Modelsim SE-64 10.4下载、破解、安装过程
  17. 数据库 1NF、2NF、3NF、BCNF
  18. 邮件发送(qq邮箱)
  19. 团队建设之做好技术团队管理
  20. java web属于什么语言_java web开发是什么

热门文章

  1. 符合Scorm的LMS系统
  2. mysql字符串分割为数组_mysql下将分隔字符串转换为数组
  3. 《胜负无定数,敢拼搏成七分》的读后感
  4. autoit3模拟鼠标点击之MouseClick
  5. 关于自己配置电脑的一点心得
  6. 搜索爬行原理_使用Diffbot爬行和搜索整个域
  7. 每日分享 环境报错:Exception in thread “main“ java.lang.RuntimeException: Cannot create staging directory
  8. allure报告定制
  9. 计算机专业秃顶图片,大学被叫惨的三大专业,计算机秃顶是常事,医学专业这个就惨了!...
  10. 编写类的步骤编写测试类