Commit 97300c53 by SOOLUCKY

init

parents
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zanchina</groupId>
<artifactId>check</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>check</name>
<description>zanchina check work</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
</dependencies>
<build>
<finalName>check</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.zanchina.check;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CheckApplication {
public static void main(String[] args) {
SpringApplication.run(CheckApplication.class, args);
}
}
package com.zanchina.check.common;
import java.util.List;
@lombok.Data
public class ExcelData {
private String[] titles;
private List<String[]> datas;
}
package com.zanchina.check.common;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@Slf4j
public class ExcelRead {
private static ExcelRead inst = new ExcelRead();
private ExcelRead() {
}
public static ExcelRead getInst() {
return inst;
}
public ExcelData parse(String fileName) {
Workbook wb = null;
try {
InputStream is = new FileInputStream(fileName);
String postfix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
if (postfix.equals(".xls")) {
// 针对 2003 Excel 文件
wb = new HSSFWorkbook(new POIFSFileSystem(is));
} else {
// 针对2007 Excel 文件
wb = new XSSFWorkbook(is);
}
} catch (IOException e) {
log.error(e.getMessage(), e);
}
Sheet sheet = wb.getSheetAt(0);
int rowNum = sheet.getLastRowNum();// 得到总行数
Row row = sheet.getRow(0);
int colNum = row.getPhysicalNumberOfCells();
String titles[] = readExcelTitle(row);
List<String[]> list = new ArrayList<String[]>();
String[] content = null;
// 正文内容应该从第二行开始,第一行为表头的标题
for (int i = 1; i <= rowNum; i++) {
int j = 0;
row = sheet.getRow(i);
content = new String[colNum];
do {
content[j] = getCellFormatValue(row.getCell(j)).trim();
j++;
} while (j < colNum);
list.add(content);
}
ExcelData data = new ExcelData();
data.setDatas(list);
data.setTitles(titles);
return data;
}
public ExcelData parse(InputStream in, String fileName, boolean bool) {
Workbook wb = null;
try {
String postfix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
if (postfix.equals(".xls")) {
// 针对 2003 Excel 文件
wb = new HSSFWorkbook(new POIFSFileSystem(in));
} else {
// 针对2007 Excel 文件
wb = new XSSFWorkbook(in);
}
} catch (IOException e) {
log.error(e.getMessage(), e);
}
Sheet sheet = wb.getSheetAt(0);
int rowNum = sheet.getLastRowNum();// 得到总行数
Row row = sheet.getRow(0);
int colNum = row.getPhysicalNumberOfCells();
String titles[] = readExcelTitle(row);
List<String[]> list = new ArrayList<String[]>();
String[] content = null;
// 正文内容应该从第二行开始,第一行为表头的标题
//bool是否从标题行开始
if (bool) {
for (int i = 0; i <= rowNum; i++) {
int j = 0;
row = sheet.getRow(i);
content = new String[colNum];
do {
if (null != row.getCell(j)) {
if (null != getCellFormatValue(row.getCell(j))) {
content[j] = getCellFormatValue(row.getCell(j)).trim();
}
}
j++;
} while (j < colNum);
list.add(content);
}
} else {
for (int i = 1; i <= rowNum; i++) {
int j = 0;
row = sheet.getRow(i);
content = new String[colNum];
do {
content[j] = getCellFormatValue(row.getCell(j)).trim();
j++;
} while (j < colNum);
list.add(content);
}
}
ExcelData data = new ExcelData();
data.setDatas(list);
data.setTitles(titles);
return data;
}
private String[] readExcelTitle(Row row) {
int colNum = row.getPhysicalNumberOfCells();// 获取行的列数
String[] titles = new String[colNum];
for (int i = 0; i < titles.length; i++) {
titles[i] = getCellFormatValue(row.getCell(i));
}
return titles;
}
private String getCellFormatValue(Cell cell) {
String cellvalue = "";
DecimalFormat df = new DecimalFormat("#");
if (cell != null) {
// 判断当前Cell的Type
switch (cell.getCellType()) {
// 如果当前Cell的Type为NUMERIC
case Cell.CELL_TYPE_NUMERIC: {
// 判断当前的cell是否为Date
if (HSSFDateUtil.isCellDateFormatted(cell)) {
// 方法2:这样子的data格式是不带带时分秒的:2011-10-12
Date date = cell.getDateCellValue();
SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.yyyyMMddHHmm1);
cellvalue = sdf.format(date);
} else {
// 如果是纯数字取得当前Cell的数值
cellvalue = String.valueOf(cell.getNumericCellValue());
}
break;
}
// 如果当前Cell的Type为STRIN
case Cell.CELL_TYPE_STRING:
// 取得当前的Cell字符串
cellvalue = cell.getRichStringCellValue().getString();
break;
default:
cellvalue = " ";
}
}
return cellvalue;
}
}
package com.zanchina.check.common;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* @author zhoubinglong
*/
@Slf4j
public class ExcelWrite {
private static ExcelWrite inst = new ExcelWrite();
private ExcelWrite() {
}
private String sheetName = "Sheet1";
public void setSheetName(String sheetName) {
this.sheetName = sheetName;
}
public static ExcelWrite getInst() {
return inst;
}
public void write(ExcelData data, File out) {
write(data, out, null);
}
public void write(ExcelData data, File out, File template) {
Workbook workbook = null;
Sheet sheet = null;
if (null != template) {
try {
if (template.getName().contains(".")&&template.getName().substring(template.getName().lastIndexOf(".")+1, template.getName().length()).toLowerCase().equals("xls")) {
workbook = new HSSFWorkbook(new POIFSFileSystem(new FileInputStream(template)));
}else{
workbook=new XSSFWorkbook(new FileInputStream(template));
}
sheet = workbook.getSheetAt(0);
} catch (Exception e) {
}
} else {
if (out.getName().contains(".")&&out.getName().substring(out.getName().lastIndexOf(".")+1, out.getName().length()).toLowerCase().equals("xls")) {
workbook = new HSSFWorkbook();
}else{
workbook=new XSSFWorkbook();
}
sheet = workbook.createSheet(sheetName);
}
if (null != data.getTitles() && data.getTitles().length > 0) {
Row titleRow = sheet.createRow(0);
for (int j = 0; j < data.getTitles().length; j++) {
Cell busiDataCell = titleRow.createCell(j);
busiDataCell.setCellValue(data.getTitles()[j]);
}
}
for (int i = 0; i < data.getDatas().size(); i++) {
String[] arr = data.getDatas().get(i);
Row busiDataRow = sheet.createRow(i + 1);
for (int j = 0; j < arr.length; j++) {
Cell busiDataCell = busiDataRow.createCell(j);
busiDataCell.setCellValue(arr[j]);
}
}
try {
OutputStream os = new FileOutputStream(out);
workbook.write(os);
if (null != workbook) {
workbook.close();
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
package com.zanchina.check.common;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ExceptionFilesRead {
public static String readFiles(String statusCode, String[] names) throws Exception{
String s="";
String lineTxt = null;
StringBuffer str = new StringBuffer();
StringBuffer[] buffer = new StringBuffer[names.length];
FileReader[] fr = new FileReader[names.length];
BufferedReader[] br = new BufferedReader[names.length];
try {
for(int i=0; i<names.length; i++){
fr[i] = new FileReader(names[i]);
br[i] = new BufferedReader(fr[i]);
}
for(int i=0; i<names.length; i++){
while ((lineTxt = br[i].readLine()) != null) {
buffer[i] = new StringBuffer(lineTxt+"<br />");
}
}
for(int i=0; i<names.length; i++){
str.append(buffer[i].toString());
}
s= "状态码"+statusCode+"的url:<br />"+str.toString()+"<br />";
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return s;
}
}
\ No newline at end of file
package com.zanchina.check.controller;
import com.zanchina.check.common.ExcelData;
import com.zanchina.check.common.ExcelRead;
import com.zanchina.check.service.FileService;
import java.io.InputStream;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
/**
* Created by xiechunlu on 2018-06-15 下午2:40
*/
@Controller
public class FileController {
@Autowired
private FileService fileService;
@GetMapping("")
public String index() {
return "redirect:/index.html";
}
@PostMapping("upload")
@ResponseBody
public ResponseEntity<byte[]> uploadAndExport(
@RequestParam MultipartFile file) {
try {
if (Objects.isNull(file)) {
return null;
}
InputStream inputStream = file.getInputStream();
ExcelRead inst = ExcelRead.getInst();
ExcelData data = inst.parse(inputStream, file.getOriginalFilename(), false);
return fileService.uploadAndExport(data);
} catch (Exception e) {
return null;
}
}
}
package com.zanchina.check.domain;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
/**
* Created by xiechunlu on 2018-06-15 下午5:52
*/
@Data
public class Staff {
/**
* 考勤号
*/
private Integer id;
/**
* 员工名
*/
private String name;
/**
* 出勤列表
*/
private List<WorkCheck> workCheckList = new ArrayList<>();
}
package com.zanchina.check.domain;
import com.zanchina.check.common.DateUtils;
import lombok.Data;
/**
* Created by xiechunlu on 2018-06-15 下午4:17
*/
@Data
public class WorkCheck {
/**
* 出勤日期
*/
private String date;
/**
* 上班签到时间
*/
private String onTime;
/**
* 下班签到时间
*/
private String offTime;
/**
* 出勤状态
*/
private String state;
/**
* 出勤时长(小时为单位)
*/
private Double duration;
public Double getDuration() {
return (double) (DateUtils.parseDate(getOffTime()).getTime() - DateUtils.parseDate(getOnTime()).getTime()) / (60
* 60 * 1000) % 24;
}
}
package com.zanchina.check.service;
import com.zanchina.check.common.ExcelData;
import java.text.ParseException;
import org.springframework.http.ResponseEntity;
/**
* Created by xiechunlu on 2018-06-15 下午2:41
*/
public interface FileService {
ResponseEntity<byte[]> uploadAndExport(ExcelData data) throws Exception;
}
package com.zanchina.check.service.impl;
import com.zanchina.check.common.DateUtils;
import com.zanchina.check.common.ExcelData;
import com.zanchina.check.common.ExcelWrite;
import com.zanchina.check.domain.Staff;
import com.zanchina.check.domain.WorkCheck;
import com.zanchina.check.service.FileService;
import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
/**
* Created by xiechunlu on 2018-06-15 下午2:41
*/
@Service
@Slf4j
public class FileServiceImpl implements FileService {
@Override
public ResponseEntity<byte[]> uploadAndExport(ExcelData data) throws Exception {
//1. 拿到数据后根据id和日期分组
Map<String, Map<String, List<String[]>>> map = data.getDatas().stream()
.collect(Collectors.groupingBy(d -> d[2], Collectors.groupingBy(
d -> {
String date;
try {
date = DateUtils
.formatDate(DateUtils.parseDate(d[3], DateUtils.yyyyMMddHHmm1),
DateUtils.yyyyMMdd1);
} catch (Exception e) {
return null;
}
return date;
})));
//2. 取出最大时间和最小时间,计算考勤状态,生成workcheck
List<Staff> staffList = new ArrayList<>();
map.entrySet().forEach(entry -> {
Staff staff = new Staff();
staff.setId(Integer.valueOf(entry.getKey()));
entry.getValue().entrySet().forEach(entry2 -> {
staff.setName((entry2.getValue().get(0))[1]);
List<String> dateStrList = entry2.getValue().stream().map(e -> e[3])
.collect(Collectors.toList());
List<Date> dateList = entry2.getValue().stream().map(e -> DateUtils.parseDate(e[3]))
.collect(Collectors.toList());
WorkCheck workCheck = new WorkCheck();
workCheck.setDate(DateUtils.formatDate(dateList.get(0), DateUtils.yyyyMMdd1));
// 上班时间算一天当中最小的时间
Date minDate = dateList.stream().min(Comparator.comparing(d -> d.getTime())).get();
workCheck.setOnTime(DateUtils.formatDate(minDate, DateUtils.yyyyMMddHHmm1));
//下班时间算一天当中最大的时间
Date maxDate = dateList.stream().max(Comparator.comparing(d -> d.getTime())).get();
workCheck.setOffTime(DateUtils.formatDate(maxDate, DateUtils.yyyyMMddHHmm1));
//计算出勤状态(迟到、早退、迟到和早退、正常)
boolean isLate = false;
boolean isEarly = false;
double hours = workCheck.getDuration();
Date onTime = DateUtils.getDateTime(dateList.get(0), 9, 30);
Date offTime = DateUtils.getDateTime(dateList.get(0), 18, 00);
isLate = DateUtils.parseDate(workCheck.getOnTime()).after(onTime);
isEarly = DateUtils.parseDate(workCheck.getOffTime()).before(offTime);
//早上迟到
if (isLate) {
if (9 <= hours) {
//工作时长大于九个小时
workCheck.setState("迟到");
} else {
workCheck.setState("迟到和早退");
}
} else {
//早上没有迟到
if (isEarly || (!isEarly && 9.0 > hours)) {
//早退了
workCheck.setState("早退");
} else {
workCheck.setState("正常");
}
}
staff.getWorkCheckList().add(workCheck);
});
staffList.add(staff);
});
staffList.sort(Comparator.comparing(Staff::getId));
return checkExport(staffList, DateUtils.parseDate(staffList.get(0).getWorkCheckList().get(0).getDate()));
}
private ResponseEntity<byte[]> checkExport(List<Staff> staffList, Date month) throws Exception {
ExcelData data = new ExcelData();
ArrayList<String> titleList = new ArrayList<>();
titleList.add("姓名");
titleList.addAll(DateUtils.getAllDatesOfMonth(month).stream().map(date ->
DateUtils.format(date, DateUtils.yyyyMMdd1).concat("(").concat(DateUtils.getWeekday(date))
.concat(")")
).collect(Collectors.toList()));
String[] titleStrArr = titleList.toArray(new String[titleList.size()]);
data.setTitles(titleStrArr);
List<String[]> datas = new ArrayList<>();
staffList.forEach(staff -> {
String[] d = new String[titleStrArr.length];
for (String title : titleList) {
if ("姓名".equalsIgnoreCase(title)) {
d[0] = staff.getName();
} else {
int index = titleList.indexOf(title);
boolean isExist = false;
String week = DateUtils
.getWeekOfDateDigit(DateUtils.parseDate(title.substring(0, title.indexOf("("))));
boolean isWeekend = week.equalsIgnoreCase(Integer.toString(6)) || week
.equalsIgnoreCase(Integer.toString(7));
for (WorkCheck check : staff.getWorkCheckList()) {
if (title.substring(0, title.indexOf("(")).equalsIgnoreCase(check.getDate())) {
String detail = "";
if (!isWeekend) {
detail = check.getState();
}
d[index] = detail.concat("(")
.concat(DateUtils.getHHmmTime(DateUtils.parseDate(check.getOnTime()))).concat("~")
.concat(
DateUtils.getHHmmTime(DateUtils.parseDate(check.getOffTime())).concat(",小时数:")
.concat(Double.toString(
new BigDecimal(check.getDuration())
.setScale(2, BigDecimal.ROUND_HALF_UP)
.doubleValue()))
.concat(")"));
isExist = true;
}
}
if (!isExist) {
if (!isWeekend) {
d[index] = "无考勤记录";
} else {
d[index] = "";
}
}
}
}
datas.add(d);
});
data.setDatas(datas);
ExcelWrite inst = ExcelWrite.getInst();
File dst = File.createTempFile("export", ".xls");
inst.write(data, dst);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
String dfileName = "考勤统计信息.xls";
dfileName = new String(dfileName.getBytes("UTF-8"), "iso8859-1");
headers.setContentDispositionFormData("attachment", dfileName);
return new ResponseEntity<>(FileUtils.readFileToByteArray(dst), headers, HttpStatus.CREATED);
}
}
spring:
http:
multipart:
enabled: true
max-file-size: 30MB
max-request-size: 30MB
encoding:
force: true
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<meta charset="UTF-8">
<title>考勤</title>
</head>
<body>
<form enctype="multipart/form-data" method="post" action="/upload">
<div class="container" style="padding-top: 20%;">
<div class="row align-items-center">
<div class="col">
<input type="file" name="file">
</div>
<div class="col">
<button type="submit" class="btn btn-outline-primary btn-lg btn-block">生成考勤记录</button>
</div>
</div>
</div>
</form>
</body>
</html>
\ No newline at end of file
package com.zanchina.check;
import com.zanchina.check.common.DateUtils;
import java.text.ParseException;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CheckApplicationTests {
@Test
public void contextLoads() throws ParseException {
Date d1 = DateUtils.parseDate("9:00", DateUtils.HHmm);
Date d2 = DateUtils.parseDate("2018/06/19 9:00", DateUtils.yyyyMMddHHmm1);
System.out.print(d1.before(d2));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment