java生成excel甘特图
java生成excel甘特图
·
生成效果如下:
代码:
public class GenerateGanttChart3 {
// 创建数据
public static ProjectEntity generateData() {
List<ProjectEntity> projectEntityList = new ArrayList<>();
List<UnitEntity> unitEntityList = new ArrayList<>();
UnitEntity unitEntity = new UnitEntity("单体1", "安装单元1", "前置任务1", LocalDate.parse("2022-07-01"), LocalDate.parse("2022-07-02"));
unitEntityList.add(unitEntity);
unitEntity = new UnitEntity("单体1", "安装单元2", "前置任务2", LocalDate.parse("2022-07-02"), LocalDate.parse("2022-07-25"));
unitEntityList.add(unitEntity);
unitEntity = new UnitEntity("单体2", "安装单元1", "前置任务1",LocalDate.parse("2022-07-03"), LocalDate.parse("2022-07-13"));
unitEntityList.add(unitEntity);
unitEntity = new UnitEntity("单体2", "安装单元2", "前置任务2",LocalDate.parse("2022-07-13"), LocalDate.parse("2022-07-16"));
unitEntityList.add(unitEntity);
unitEntity = new UnitEntity("单体2", "安装单元3", "前置任务3",LocalDate.parse("2022-07-16"), LocalDate.parse("2022-07-20"));
unitEntityList.add(unitEntity);
unitEntity = new UnitEntity("单体2", "安装单元4", "前置任务4",LocalDate.parse("2022-07-20"), LocalDate.parse("2022-09-23"));
unitEntityList.add(unitEntity);
unitEntity = new UnitEntity("单体3", "安装单元1", "前置任务1",LocalDate.parse("2022-07-10"), LocalDate.parse("2022-08-13"));
unitEntityList.add(unitEntity);
unitEntity = new UnitEntity("单体3", "安装单元2", "前置任务2",LocalDate.parse("2022-07-13"), LocalDate.parse("2022-08-23"));
unitEntityList.add(unitEntity);
ProjectEntity projectEntity1 = new ProjectEntity("项目编号1", "项目名称1", "合同编号1", "项目经理1", LocalDate.parse("2022-08-23"), unitEntityList);
return projectEntity1;
}
//获取横向单元格总数量
public static Map<String, Object> getCellNum(ProjectEntity projectEntity) {
Map<String, Object> resultMap = new HashMap<>();
//前面固定有五列
int preCellNum = 5;
//循环数据 获取最大日期和最小日期并得到天数查
LocalDate minDate = projectEntity.getEntityList().get(0).getStartTime();
LocalDate maxDate = projectEntity.getEntityList().get(0).getEndTime();
for (int i = 0; i < projectEntity.getEntityList().size(); i ++) {
if (projectEntity.getEntityList().get(i).getStartTime().isBefore(minDate)) {
minDate = projectEntity.getEntityList().get(i).getStartTime();
}
if (projectEntity.getEntityList().get(i).getEndTime().isAfter(maxDate)) {
maxDate = projectEntity.getEntityList().get(i).getEndTime();
}
}
int dayDiff = (int) (maxDate.toEpochDay()-minDate.toEpochDay());
int totalCellNum = preCellNum + dayDiff;
// 修改 判断mindate是否为周一 如果不是 加
int weekNum = WeekEnum.getWeekDayByCode(String.valueOf(minDate.getDayOfWeek()));
if (weekNum != 1) {
minDate = minDate.plusDays(-weekNum + 1);
dayDiff = dayDiff + weekNum - 1;
totalCellNum = totalCellNum + weekNum - 1;
}
int weekNumMax = WeekEnum.getWeekDayByCode(String.valueOf(maxDate.getDayOfWeek()));
if (weekNumMax != 7) {
dayDiff = dayDiff + 7 - weekNumMax;
totalCellNum = totalCellNum + 7 - weekNumMax;
}
resultMap.put("minDate", minDate);
resultMap.put("maxDate", maxDate);
resultMap.put("totalCellNum", totalCellNum);
resultMap.put("dayDiff", dayDiff);
System.out.println(resultMap);
return resultMap;
}
//生成甘特图
public static void generateGantt() {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet("甘特图");
//背景色为鲜红色
XSSFCellStyle redBackgroundStyle = wb.createCellStyle();
redBackgroundStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
redBackgroundStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
//背景色为绿色
XSSFCellStyle greenBackgroundStyle = wb.createCellStyle();
greenBackgroundStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
greenBackgroundStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
ProjectEntity projectEntity = generateData();
Map<String, Object> resultMap = getCellNum(projectEntity);
for (int i = 0; i <= 4; i++) {
sheet.setColumnWidth(i, (int) (12 * 256.0D));
}
for (int i = 5; i <= (Integer) resultMap.get("totalCellNum"); i++) {
sheet.setColumnWidth(i, (int) (4 * 256.0D));
}
// 日期格式
XSSFCellStyle dateStyle = wb.createCellStyle();
CreationHelper createHelper = wb.getCreationHelper();
dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy/mm/dd;@"));
dateStyle.setAlignment(HorizontalAlignment.CENTER);
dateStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 居中格式
XSSFCellStyle centerStyle = wb.createCellStyle();
centerStyle.setAlignment(HorizontalAlignment.CENTER);
centerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 左对齐
XSSFCellStyle leftStyle = wb.createCellStyle();
leftStyle.setAlignment(HorizontalAlignment.LEFT);
leftStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 前面固定列数
int preFixedCellNum = 5;
// 第一行
XSSFRow row1 = sheet.createRow(0);
XSSFCell cell10 = row1.createCell(0);
cell10.setCellValue("项目计划更新甘特图");
cell10.setCellStyle(centerStyle);
CellRangeAddress cellRangeAddress10 = new CellRangeAddress(0, 0, 0, (Integer) resultMap.get("totalCellNum"));
sheet.addMergedRegion(cellRangeAddress10);
// 第二行
XSSFRow row2 = sheet.createRow(1);
XSSFCell cell20 = row2.createCell(0);
cell20.setCellValue("项目编号:" + projectEntity.getProjectCode());
cell20.setCellStyle(leftStyle);
CellRangeAddress cellRangeAddress20 = new CellRangeAddress(1, 1, 0, 2);
sheet.addMergedRegion(cellRangeAddress20);
XSSFCell cell23 = row2.createCell(3);
cell23.setCellValue("合同编号:" + projectEntity.getContractCode());
cell23.setCellStyle(leftStyle);
CellRangeAddress cellRangeAddress23 = new CellRangeAddress(1, 1, 3, 5);
sheet.addMergedRegion(cellRangeAddress23);
// 第三行
XSSFRow row3 = sheet.createRow(2);
XSSFCell cell30 = row3.createCell(0);
cell30.setCellValue("项目名称:" + projectEntity.getProjectName());
cell30.setCellStyle(leftStyle);
CellRangeAddress cellRangeAddress30 = new CellRangeAddress(2, 2, 0, 2);
sheet.addMergedRegion(cellRangeAddress30);
// 第四行
XSSFRow row4 = sheet.createRow(3);
XSSFCell cell40 = row4.createCell(0);
cell40.setCellValue("项目预计完成时间:" + projectEntity.getPlanCompleteTime());
cell40.setCellStyle(leftStyle);
CellRangeAddress cellRangeAddress40 = new CellRangeAddress(3, 3, 0, 2);
sheet.addMergedRegion(cellRangeAddress40);
XSSFCell cell43 = row2.createCell(3);
cell43.setCellValue("项目经理:" + projectEntity.getProjectMaster());
cell43.setCellStyle(leftStyle);
CellRangeAddress cellRangeAddress43 = new CellRangeAddress(3, 3, 3, 5);
sheet.addMergedRegion(cellRangeAddress43);
// 第五行
XSSFRow row5 = sheet.createRow(4);
XSSFCell cell50 = row5.createCell(0);
cell50.setCellValue("单体名称");
cell50.setCellStyle(centerStyle);
CellRangeAddress cellRangeAddress50 = new CellRangeAddress(4, 5, 0, 0);
sheet.addMergedRegion(cellRangeAddress50);
XSSFCell cell51 = row5.createCell(1);
cell51.setCellValue("安装单元编号");
cell51.setCellStyle(centerStyle);
CellRangeAddress cellRangeAddress51 = new CellRangeAddress(4, 5, 1, 1);
sheet.addMergedRegion(cellRangeAddress51);
XSSFCell cell52 = row5.createCell(2);
cell52.setCellValue("前置任务");
cell52.setCellStyle(centerStyle);
CellRangeAddress cellRangeAddress52 = new CellRangeAddress(4, 5, 2, 2);
sheet.addMergedRegion(cellRangeAddress52);
XSSFCell cell53 = row5.createCell(3);
cell53.setCellValue("开始时间");
cell53.setCellStyle(centerStyle);
CellRangeAddress cellRangeAddress53 = new CellRangeAddress(4, 5, 3, 3);
sheet.addMergedRegion(cellRangeAddress53);
XSSFCell cell54 = row5.createCell(4);
cell54.setCellValue("结束时间");
cell54.setCellStyle(centerStyle);
CellRangeAddress cellRangeAddress54 = new CellRangeAddress(4, 5, 4, 4);
sheet.addMergedRegion(cellRangeAddress54);
//日期
int dayDiff = (Integer) resultMap.get("dayDiff");
LocalDate minDate = (LocalDate) resultMap.get("minDate");
for (int i = 0; i <= dayDiff; i++) {
XSSFCell cell5 = row5.createCell(preFixedCellNum + i);
cell5.setCellValue(minDate.plusDays(i));
cell5.setCellStyle(dateStyle);
}
// 第六行
// 修改
XSSFRow row6 = sheet.createRow(5);
for (int i = 0; i <= dayDiff; i++) {
LocalDate date = LocalDate.from(row5.getCell(preFixedCellNum + i).getLocalDateTimeCellValue());
XSSFCell cell6 = row6.createCell(preFixedCellNum + i);
cell6.setCellValue(String.valueOf(date.getDayOfMonth()));
cell6.setCellStyle(dateStyle);
}
int insertIndex = 0;
int toIndex = 0;
LocalDate minDate2 = null;
LocalDate maxDate2 = null;
for (int i = 0; i < projectEntity.getEntityList().size() - 1; i++) {
//获取第0列和第1列每行单元格的 值 如果相等 将合并列的数量加一
String name1 = projectEntity.getEntityList().get(i).getSingleBodyName();
String name2 = projectEntity.getEntityList().get(i + 1).getSingleBodyName();
if (name2.equals(name1)) {
toIndex ++;
} else {
// 获取最大日期和最小日期
//循环数据 获取最大日期和最小日期并得到天数查
minDate2 = projectEntity.getEntityList().get(insertIndex).getStartTime();
maxDate2 = projectEntity.getEntityList().get(toIndex).getEndTime();
for (int j = insertIndex; j < toIndex; j++ ) {
if (projectEntity.getEntityList().get(i).getStartTime().isBefore(minDate2)) {
minDate2 = projectEntity.getEntityList().get(i).getStartTime();
}
if (projectEntity.getEntityList().get(i).getEndTime().isAfter(maxDate2)) {
maxDate2 = projectEntity.getEntityList().get(i).getEndTime();
}
}
UnitEntity unitEntity = new UnitEntity(projectEntity.getEntityList().get(i).getSingleBodyName(), "", "", minDate2, maxDate2);
projectEntity.getEntityList().add(insertIndex, unitEntity);
i++;
insertIndex = i + 1;
toIndex = i + 1;
}
if (i == projectEntity.getEntityList().size() - 2) {
minDate2 = projectEntity.getEntityList().get(insertIndex).getStartTime();
maxDate2 = projectEntity.getEntityList().get(toIndex).getEndTime();
for (int j = insertIndex; j < toIndex; j++ ) {
if (projectEntity.getEntityList().get(i).getStartTime().isBefore(minDate2)) {
minDate2 = projectEntity.getEntityList().get(i).getStartTime();
}
if (projectEntity.getEntityList().get(i).getEndTime().isAfter(maxDate2)) {
maxDate2 = projectEntity.getEntityList().get(i).getEndTime();
}
}
UnitEntity unitEntity = new UnitEntity(projectEntity.getEntityList().get(i).getSingleBodyName(), "", "", minDate2, maxDate2);
projectEntity.getEntityList().add(insertIndex, unitEntity);
break;
}
}
// 第七行
Boolean UnitFlag = Boolean.TRUE;
for (int i = 0; i < projectEntity.getEntityList().size(); i++) {
XSSFRow row7 = sheet.createRow(6 + i);
for (int j = 0; j <= (Integer) resultMap.get("totalCellNum"); j++) {
XSSFCell cell70 = row7.createCell(j);
LocalDate startTime = projectEntity.getEntityList().get(i).getStartTime();
LocalDate endTime = projectEntity.getEntityList().get(i).getEndTime();
if (j == 0) {
if (projectEntity.getEntityList().get(i).getUnitCode() == null || "".equals(projectEntity.getEntityList().get(i).getUnitCode())) {
cell70.setCellValue(projectEntity.getEntityList().get(i).getSingleBodyName());
cell70.setCellStyle(centerStyle);
UnitFlag = Boolean.FALSE;
} else {
UnitFlag = Boolean.TRUE;
}
} else if (j == 1) {
cell70.setCellValue(projectEntity.getEntityList().get(i).getUnitCode());
cell70.setCellStyle(centerStyle);
} else if (j == 2) {
cell70.setCellValue(projectEntity.getEntityList().get(i).getPreUnitCodes());
cell70.setCellStyle(centerStyle);
} else if (j == 3) {
cell70.setCellValue(startTime);
cell70.setCellStyle(dateStyle);
} else if (j == 4) {
cell70.setCellValue(endTime);
cell70.setCellStyle(dateStyle);
} else {
//如果 第五行该单元格的值 在当前行开始时间和结束时间之内 改变单元格背景颜色
//获取第二行第j列的值
LocalDate theTime = row5.getCell(j).getLocalDateTimeCellValue().toLocalDate();
if ((theTime.isAfter(startTime) || theTime.equals(startTime))
&& (theTime.isBefore(endTime) || theTime.equals(endTime))) {
if (UnitFlag == Boolean.FALSE) {
// 单体颜色
cell70.setCellStyle(greenBackgroundStyle);
} else {
cell70.setCellStyle(redBackgroundStyle);
}
}
}
}
}
//日期合并
int begin = 5;
int end = 5;
boolean flag = false;
// 当前周第一个时间
LocalDate beforeTime = null;
// 前一个单元格的时间
LocalDate beforeDate = null;
String cellValue = null;
for (int i = 0; i <= dayDiff; i++) {
if (i >= 1 && flag) {
beforeTime = beforeDate;
flag = false;
}
if (beforeTime != null) {
// 如果属于同一周
if (checkWeekBetween(beforeTime,minDate.plusDays(i))) {
end ++;
beforeDate = minDate.plusDays(i);
} else {
if (begin != end) {
CellRangeAddress cellRangeAddressEnd = new CellRangeAddress(4, 4, begin, end);
sheet.addMergedRegion(cellRangeAddressEnd);
}
beforeTime = null;
if (cellValue == null) {
cellValue = beforeDate.format(DateTimeFormatter.ofPattern("yyyy/M/d"));
} else {
cellValue = cellValue + beforeDate.format(DateTimeFormatter.ofPattern("yyyy/M/d"));
}
beforeDate = minDate.plusDays(i);
row5.getCell(begin).setCellValue(cellValue);
row5.getCell(begin).setCellStyle(dateStyle);
begin = end + 1;
end = begin;
cellValue = beforeDate.format(DateTimeFormatter.ofPattern("yyyy/M/d")) + "-";
flag = true;
}
} else {
beforeDate = minDate.plusDays(i);
cellValue = beforeDate.format(DateTimeFormatter.ofPattern("yyyy/M/d")) + "-";
flag = true;
}
if (i == dayDiff) {
if (!cellValue.contains(beforeDate.format(DateTimeFormatter.ofPattern("yyyy/M/d")))) {
cellValue = cellValue + beforeDate.format(DateTimeFormatter.ofPattern("yyyy/M/d"));
} else {
cellValue = beforeDate.format(DateTimeFormatter.ofPattern("yyyy/M/d"));
}
row5.getCell(begin).setCellValue(cellValue);
row5.getCell(begin).setCellStyle(dateStyle);
if (begin != end) {
CellRangeAddress cellRangeAddressEnd = new CellRangeAddress(4, 4, begin, end);
sheet.addMergedRegion(cellRangeAddressEnd);
}
}
}
try {
FileOutputStream fout = new FileOutputStream("D:\\文件\\公司\\需求\\甘特图\\甘特图3.xlsx");
wb.write(fout);
fout.close();
System.out.println("excel生成成功");
} catch (IOException e) {
System.out.println("excel生成失败:" + e.getMessage());
}
}
/**
* 以second为主进行判断
* 以first为开始时间,second为结束时间
* 判断两个时间是否在通过一个周内。
*
* @param first
* @param second
*/
private static Boolean checkWeekBetween(LocalDate first, LocalDate second){
// 两个时间差不超过7天,
Period period = Period.between(first,second);
int years = period.getYears();
if(years > 0){
return false;
}
int months = period.getMonths();
if(months > 0){
return false;
}
int days = period.getDays();
if(days == 0){
// 表明是同一天
return true;
}
if(days > 7 || days < -7){
// 两个时间差 超出了7天
return false;
}
int firstDayOfWeek = first.getDayOfWeek().getValue();
int secondDayOfWeek = second.getDayOfWeek().getValue();
if(secondDayOfWeek == 1){
if(oneDay(firstDayOfWeek,secondDayOfWeek,days)){
return true;
}else {
return false;
}
}
if(secondDayOfWeek == 7){
if(sevenDay(firstDayOfWeek,secondDayOfWeek,days)){
return true;
}else {
return false;
}
}
if(otherDay(firstDayOfWeek,secondDayOfWeek,days)){
return true;
}else{
return false;
}
}
/**
* secondDayOfWeek 是所在星期的第一天
* 星期的第一天 数据处理
* @return
*/
private static Boolean oneDay(int firstDayOfWeek,int secondDayOfWeek,int days){
if(days > 0 ){
// 表明 first 比second 小 不在同一周
return false;
}else {
// 表明 first 比second 大
if(secondDayOfWeek - days == firstDayOfWeek){
return true;
}
}
return false;
}
/**
* 星期的第7天的时候处理数据
* @return
*/
private static Boolean sevenDay(int firstDayOfWeek,int secondDayOfWeek,int days){
// second 是周日
if(firstDayOfWeek + days == secondDayOfWeek){
return true;
}
return false;
}
/**
* 其他天的数据处理
* @return
*/
private static Boolean otherDay(int firstDayOfWeek,int secondDayOfWeek,int days){
if(days < 0){
// 表明 first 比 second 大
if((secondDayOfWeek - days) == firstDayOfWeek){
// 两者是 一周内
return true;
}
}else {
// 表明 first 比 second 小
if(firstDayOfWeek + days == secondDayOfWeek){
// 两者是 一周内
return true;
}
}
return false;
}
public static void main(String[] args) {
generateGantt();
}
}
ProjectEntity类:
public class ProjectEntity {
private String projectCode;
private String projectName;
private String contractCode;
private String projectMaster;
private LocalDate planCompleteTime;
private List<UnitEntity> entityList;
private String singleBodyName;
private String unitCode;
private String preUnitCodes;
private LocalDate startTime;
private LocalDate endTime;
public ProjectEntity(String projectCode, String singleBodyName, String unitCode, LocalDate startTime, LocalDate endTime) {
this.projectCode = projectCode;
this.singleBodyName = singleBodyName;
this.unitCode = unitCode;
this.startTime = startTime;
this.endTime = endTime;
}
public String getSingleBodyName() {
return singleBodyName;
}
public void setSingleBodyName(String singleBodyName) {
this.singleBodyName = singleBodyName;
}
public String getUnitCode() {
return unitCode;
}
public void setUnitCode(String unitCode) {
this.unitCode = unitCode;
}
public String getPreUnitCodes() {
return preUnitCodes;
}
public void setPreUnitCodes(String preUnitCodes) {
this.preUnitCodes = preUnitCodes;
}
public LocalDate getStartTime() {
return startTime;
}
public void setStartTime(LocalDate startTime) {
this.startTime = startTime;
}
public LocalDate getEndTime() {
return endTime;
}
public void setEndTime(LocalDate endTime) {
this.endTime = endTime;
}
public ProjectEntity(String projectCode, String projectName, String contractCode, String projectMaster, LocalDate planCompleteTime, List<UnitEntity> entityList) {
this.projectCode = projectCode;
this.projectName = projectName;
this.contractCode = contractCode;
this.projectMaster = projectMaster;
this.planCompleteTime = planCompleteTime;
this.entityList = entityList;
}
public String getProjectCode() {
return projectCode;
}
public void setProjectCode(String projectCode) {
this.projectCode = projectCode;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getContractCode() {
return contractCode;
}
public void setContractCode(String contractCode) {
this.contractCode = contractCode;
}
public String getProjectMaster() {
return projectMaster;
}
public void setProjectMaster(String projectMaster) {
this.projectMaster = projectMaster;
}
public LocalDate getPlanCompleteTime() {
return planCompleteTime;
}
public void setPlanCompleteTime(LocalDate planCompleteTime) {
this.planCompleteTime = planCompleteTime;
}
public List<UnitEntity> getEntityList() {
return entityList;
}
public void setEntityList(List<UnitEntity> entityList) {
this.entityList = entityList;
}
}
UnitEntity类:
public class UnitEntity {
private String singleBodyName;
private String unitCode;
private String preUnitCodes;
private LocalDate startTime;
private LocalDate endTime;
public UnitEntity(String singleBodyName, String unitCode, String preUnitCodes, LocalDate startTime, LocalDate endTime) {
this.singleBodyName = singleBodyName;
this.unitCode = unitCode;
this.preUnitCodes = preUnitCodes;
this.startTime = startTime;
this.endTime = endTime;
}
public String getSingleBodyName() {
return singleBodyName;
}
public void setSingleBodyName(String singleBodyName) {
this.singleBodyName = singleBodyName;
}
public String getUnitCode() {
return unitCode;
}
public void setUnitCode(String unitCode) {
this.unitCode = unitCode;
}
public String getPreUnitCodes() {
return preUnitCodes;
}
public void setPreUnitCodes(String preUnitCodes) {
this.preUnitCodes = preUnitCodes;
}
public LocalDate getStartTime() {
return startTime;
}
public void setStartTime(LocalDate startTime) {
this.startTime = startTime;
}
public LocalDate getEndTime() {
return endTime;
}
public void setEndTime(LocalDate endTime) {
this.endTime = endTime;
}
}
WeekEnum类:
public enum WeekEnum {
MONDAY("MONDAY",1,"星期一"),
TUESDAY("TUESDAY",2,"星期二"),
WEDNESDAY("WEDNESDAY",3,"星期三"),
THURSDAY("THURSDAY",4,"星期四"),
FRIDAY("FRIDAY",5,"星期五"),
SATURDAY("SATURDAY",6,"星期六"),
SUNDAY("SUNDAY",7,"星期日");
private String code;
private Integer weekDay;
private String des;
public String getCode() {
return code;
}
public Integer getWeekDay() {
return weekDay;
}
public String getDes() {
return des;
}
WeekEnum(String code, Integer weekDay, String des) {
this.code = code;
this.weekDay = weekDay;
this.des = des;
}
/**
* 根据code 得到对应的 周(几)数字
* @param code
* @return
*/
public static Integer getWeekDayByCode(String code) {
Integer result = null;
for (WeekEnum order : WeekEnum.values()) {
if (StringUtils.equals(order.getCode(),code)) {
result = order.getWeekDay();
break;
}
}
return result;
}
/**
* 根据code 得到对应的 周(几)描述
* @param code
* @return
*/
public static String getDesByCode(String code) {
String result = null;
for (WeekEnum order : WeekEnum.values()) {
if (StringUtils.equals(order.getCode(),code)) {
result = order.getDes();
break;
}
}
return result;
}
}
更多推荐
所有评论(0)