文章目录

  • 七、POI报表
    • 1、服务统一管理
      • <1>、服务发现组件Eureka
        • (1)、Eureka服务端
        • (2)、微服务注册
      • <2>、微服务调用组件Feign
        • (1)、简介
        • (2)、操作
    • 2、POI报表的概述
      • <1>、需求说明
      • <2>、Excel的俩种形式
      • <3>、常见的Excel操作工具
      • <4>、POI的概述
      • <5>、使用场景
    • 3、POI入门操作
      • <1>、搭建环境
      • <2>、结构说明
      • <3>、API说明
      • <4>、基本操作
        • (1)、使用POI创建一个Excel
        • (2)、创建单元格并写入内容
        • (3)、单元格样式处理
        • (4)、绘制图形
        • (5)、读取Excel并解析
    • 4、POI报表导入
      • <1>、需求分析
      • <2>、员工导入
        • (1)、环境搭建
        • (2)、Excel上传
        • (3)、调用企业微服务获取部门数据
    • 5、POI报表导出
      • <1>、需求分析
      • <2>、报表导出
        • (1)、步骤分析
        • (2)、实现

七、POI报表

1、服务统一管理

<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")
public interface DepartmentFeignClient {/*** 调用微服务的接口*/@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);}}}}};}
}

2、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>、使用场景

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

3、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 workbook = 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;}

运行结果如下:

4、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 ++) {Row 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);

5、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();                                           //刷数据}
}

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

前后端分离微服务管理系统项目实战SaaS-HRM项目(七)——POI报表入门相关推荐

  1. 前后端分离微服务管理系统项目实战SaaS-HRM项目(二)——数据库设计与前端框架

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

  2. 前后端分离微服务管理系统项目实战SaaS-HRM项目(九)——文件上传与PDF报表入门

    文章目录 九.文件上传与PDF报表入门 1.图片上传 <1>.Data URL (1).概述 (2).入门 (3).基本原理 (4).优缺点分析 <2>.实现用户头像上传 2. ...

  3. 若依前后端分离/微服务版怎样构造免密链接实现其他系统免登录访问

    场景 若依前后端分离版手把手教你本地搭建环境并运行项目: 若依前后端分离版手把手教你本地搭建环境并运行项目_BADAO_LIUMANG_QIZHI的博客-CSDN博客 上面在搭建起来前后端分离版的项目 ...

  4. 前后端分离微服务架构如何设计?

    一.职责划分 前端 前端工作专注业务的页面呈现,非常注重用户体验度,也是与各种角色打交道最多的. 比如: 前端开发人员会经常与产品经理或者客户讨论页面样式.视觉效果,页面布局等各种页面渲染效果 前端开 ...

  5. java版b2b2c多商家入驻微信小程序商城源码Spring Cloud+Spring Boot+mybatis+security+uniapp+直播带货+VR全景+前后端分离微服务商城源码

    1. 涉及平台 平台管理.商家端(PC端.手机端).买家平台(H5/公众号.小程序.APP端(IOS/Android).微服务平台(业务服务.系统服务.中间件服务) 2. 核心架构 Spring Cl ...

  6. 数风流人物还看今朝|前后端分离微服务项目常用中间件以及指令

    日常积累 1.常用集成开发环境(IDE) 1.1.IDEA(后端) 1.2.VSCode(前端) 2.常用中间件 2.1 .redis及其常用指令 2.1.1.启动redis服务(器) 2.1.2.关 ...

  7. 讲解开源项目:一步步跑起来个 Java 前后端分离的人力资源管理系统

    本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和运行项目,本示例是在 Windows 操作系统下演示. 本文作者:HelloGitHub-秦人 大家好!这里是 HelloGitHub 推出 ...

  8. 视频教程-基于springboot2.x+layui+shiro+redis整合前后端分离的权限管理系统-Java

    基于springboot2.x+layui+shiro+redis整合前后端分离的权限管理系统 拥有八年的Java项目开发经验,擅长Java.vue.SpringBoot.springCloud.sp ...

  9. 视频教程-springboot+Vue整合前后端分离权限后台管理系统-Java

    springboot+Vue整合前后端分离权限后台管理系统 拥有八年的Java项目开发经验,擅长Java.vue.SpringBoot.springCloud.spring.springmvc.myb ...

  10. 视频教程-SpringBoot+Security+Vue前后端分离开发权限管理系统-Java

    SpringBoot+Security+Vue前后端分离开发权限管理系统 10多年互联网一线实战经验,现就职于大型知名互联网企业,架构师, 有丰富实战经验和企业面试经验:曾就职于某上市培训机构数年,独 ...

最新文章

  1. c++中几种常见的类型转换。int与string的转换,float与string的转换以及string和long类型之间的相互转换。to_string函数的实现和应用。...
  2. 2019蓝桥杯省赛---java---B---6(特别数的和)
  3. 对等通信_新的通信技术如何影响对等参与
  4. [转]PCM文件格式
  5. 在中國古代是沒有這種現象的
  6. (day 1)创建项目--3【创建应用】
  7. 《码出高效:Java 开发手册》“码” 出高效的同时编写出高质量的代“码”。PDF文档资料免费开放下载!
  8. 云存储安全,主要面临哪些问题
  9. 敏捷开发中的文档怎么写
  10. 编译contrail-nodemgr
  11. P61 浮点数、定点数、位类型讲解
  12. Linux篇之局域网文件共享服务samba的搭建和使用
  13. android程序联网失败,请检查网络是否可用
  14. hive编写自定义UDF函数
  15. 三维重建(5)之三角测量计算双目相机坐标系下三维坐标
  16. 零基础用Android Studio实现简单的本地视频播放器
  17. 计算机编程课程顺序_您可以在2月开始免费在线编程和计算机科学课程
  18. 计算机网络- Internet是如何工作的
  19. DFA确定化和最小化
  20. 新推荐个百度网盘不限速下载神器

热门文章

  1. vbs整人小程序集合
  2. linux 在ftp gt 下登录,cutftp显示的是啥意思?
  3. 儿童素描手绘创意设计字体 for mac
  4. 国内android源码下载方法
  5. iis 6 7 8预加载,提升web访速
  6. %3c大自然的语言%3e竺可桢题目,大自然的语言竺可桢阅读答案
  7. 【操作系统⑩】——进程死锁【银行家算法+详细样例 进程死锁的预防机制、避免机制、检测与解决】
  8. Element Dialog弹框回到顶部
  9. opencv的lena项目,用android studio 3.6可以运行——drawable如何引入lena图片
  10. JVM内存模型及CMS、G1和ZGC垃圾回收器详解