package com.qcadoo.mes.materialFlowResources.palletBalance; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.commons.lang3.time.DateUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFPrintSetup; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.util.CellRangeAddress; import org.joda.time.DateTime; import org.joda.time.DateTimeConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.qcadoo.localization.api.TranslationService; import com.qcadoo.mes.materialFlowResources.constants.PalletBalanceFields; import com.qcadoo.model.api.Entity; import com.qcadoo.report.api.xls.XlsDocumentService; @Service public class PalletBalanceXlsService extends XlsDocumentService { @Autowired private TranslationService translationService; @Autowired private PalletBalanceReportHelper palletBalanceReportHelper; private static final List<String> HEADER_KEYS = Lists.newArrayList("initialState", "inbounds", "outbounds", "moves", "finalState"); @Override public String getReportTitle(Locale locale) { return translationService.translate("materialFlowResource.palletBalance.report.title", locale); } private HSSFCell createRegularCell(StylesContainer stylesContainer, HSSFRow row, int column, String content) { HSSFCell cell = row.createCell(column); cell.setCellValue(content); cell.setCellStyle(StylesContainer.aligned(stylesContainer.regularStyle, HSSFCellStyle.ALIGN_LEFT)); return cell; } private HSSFCell createNumericCell(StylesContainer stylesContainer, HSSFRow row, int column, int value) { HSSFCell cell = row.createCell(column, HSSFCell.CELL_TYPE_NUMERIC); cell.setCellValue(value); cell.setCellStyle(StylesContainer.aligned(stylesContainer.regularStyle, HSSFCellStyle.ALIGN_LEFT)); return cell; } private HSSFCell createHeaderCell(StylesContainer stylesContainer, HSSFRow row, String content, int column, short align) { HSSFCell cell = row.createCell(column); cell.setCellValue(content); cell.setCellStyle(StylesContainer.aligned(stylesContainer.headerStyle, align)); return cell; } @Override protected void addHeader(HSSFSheet sheet, Locale locale, Entity palletBalance) { final FontsContainer fontsContainer = new FontsContainer(sheet.getWorkbook()); final StylesContainer stylesContainer = new StylesContainer(sheet.getWorkbook(), fontsContainer); List<String> typesOfPallet = palletBalanceReportHelper.getTypesOfPallet(); HSSFRow headerRow = sheet.createRow(0); HSSFRow typesOfPalletRow = sheet.createRow(1); addDateHeader(sheet, locale, headerRow, stylesContainer); addTypesOfPalletHeader(sheet, locale, headerRow, typesOfPalletRow, stylesContainer, typesOfPallet); } private void addDateHeader(HSSFSheet sheet, Locale locale, HSSFRow headerRow, StylesContainer stylesContainer) { sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0)); createHeaderCell(stylesContainer, headerRow, translationService.translate("materialFlowResource.palletBalance.report.date", locale), 0, HSSFCellStyle.ALIGN_CENTER); } private void addTypesOfPalletHeader(HSSFSheet sheet, Locale locale, HSSFRow headerRow, HSSFRow typesOfPalletRow, StylesContainer stylesContainer, List<String> typesOfPallet) { int columnIndex = 1; int typesOfPalletCount = typesOfPallet.size(); int lastColumnIndex = typesOfPalletCount + columnIndex - 1; for (String key : HEADER_KEYS) { if (key.equals("moves")) { addHeaderCell(sheet, translationService.translate("materialFlowResource.palletBalance.report.header." + key, locale), headerRow, columnIndex, columnIndex + 1, stylesContainer); createHeaderCell(stylesContainer, typesOfPalletRow, translationService.translate("materialFlowResource.palletBalance.report.header.movesIn", locale), columnIndex, HSSFCellStyle.ALIGN_LEFT); columnIndex++; createHeaderCell(stylesContainer, typesOfPalletRow, translationService.translate("materialFlowResource.palletBalance.report.header.movesOut", locale), columnIndex, HSSFCellStyle.ALIGN_LEFT); columnIndex++; lastColumnIndex = columnIndex + typesOfPalletCount - 1; } else { addHeaderCell(sheet, translationService.translate("materialFlowResource.palletBalance.report.header." + key, locale), headerRow, columnIndex, lastColumnIndex, stylesContainer); for (int i = 0; i < typesOfPalletCount; i++) { createHeaderCell(stylesContainer, typesOfPalletRow, typesOfPallet.get(i), columnIndex + i, HSSFCellStyle.ALIGN_LEFT); } columnIndex = lastColumnIndex + 1; lastColumnIndex += typesOfPalletCount; } } } private void addHeaderCell(HSSFSheet sheet, String content, HSSFRow headerRow, int columnIndex, int lastColumnIndex, StylesContainer stylesContainer) { sheet.addMergedRegion(new CellRangeAddress(0, 0, columnIndex, lastColumnIndex)); createHeaderCell(stylesContainer, headerRow, content, columnIndex, HSSFCellStyle.ALIGN_CENTER); } @Override protected void addSeries(HSSFSheet sheet, Entity palletBalance) { sheet.getPrintSetup().setLandscape(true); sheet.getPrintSetup().setPaperSize(HSSFPrintSetup.A3_PAPERSIZE); sheet.getPrintSetup().setHResolution((short) 1); final FontsContainer fontsContainer = new FontsContainer(sheet.getWorkbook()); final StylesContainer stylesContainer = new StylesContainer(sheet.getWorkbook(), fontsContainer); Date dateFrom = palletBalance.getDateField(PalletBalanceFields.DATE_FROM); Date dateTo = DateUtils.truncate(palletBalance.getDateField(PalletBalanceFields.DATE_TO), Calendar.DATE); boolean includeWeekends = palletBalance.getBooleanField(PalletBalanceFields.INCLUDE_WEEKENDS); List<String> typesOfPallet = palletBalanceReportHelper.getTypesOfPallet(); Map<Date, List<PalletBalanceRowDto>> inbounds = palletBalanceReportHelper.getInbounds(dateFrom); Map<Date, List<PalletBalanceRowDto>> outbounds = palletBalanceReportHelper.getOutbounds(dateFrom); Map<Date, List<PalletBalanceRowDto>> initialState = Maps.newHashMap(); Map<Date, Integer> moves = palletBalanceReportHelper.getMoves(dateFrom); Map<Date, List<PalletBalanceRowDto>> finalState = palletBalanceReportHelper.getCurrentState(dateTo); palletBalanceReportHelper.fillFinalAndInitialState(typesOfPallet, finalState, initialState, inbounds, outbounds, dateFrom, dateTo); int columnIndex = 1; int rowIndex = 2; int columnMax = 0; DateTime currentDate = new DateTime(dateFrom); while (currentDate.toDate().compareTo(dateTo) <= 0) { if (!includeWeekends && currentDate.getDayOfWeek() > DateTimeConstants.FRIDAY) { currentDate = currentDate.plusDays(1); continue; } HSSFRow row = sheet.createRow(rowIndex); createRegularCell(stylesContainer, row, 0, currentDate.toString("dd.MM.yyyy")); Date current = currentDate.toDate(); columnIndex = createRowPart(initialState, row, columnIndex, typesOfPallet, current, stylesContainer); columnIndex = createRowPart(inbounds, row, columnIndex, typesOfPallet, current, stylesContainer); columnIndex = createRowPart(outbounds, row, columnIndex, typesOfPallet, current, stylesContainer); columnIndex = createMovesRowPart(moves, row, columnIndex, current, stylesContainer); createRowPart(finalState, row, columnIndex, typesOfPallet, current, stylesContainer); columnMax = columnIndex; columnIndex = 1; rowIndex++; currentDate = currentDate.plusDays(1); } for (int i = 0; i <= columnMax; i++) { sheet.autoSizeColumn(i, false); } } private int createRowPart(Map<Date, List<PalletBalanceRowDto>> data, HSSFRow row, int columnIndex, List<String> typesOfPallet, Date currentDate, StylesContainer stylesContainer) { for (String typeOfPallet : typesOfPallet) { if (data.containsKey(currentDate)) { PalletBalanceRowDto stateForDay = data.get(currentDate).stream() .filter(dto -> typeOfPallet.equals(dto.getTypeOfPallet())).findAny().orElse(new PalletBalanceRowDto()); createNumericCell(stylesContainer, row, columnIndex, stateForDay.getPalletsCount()); } else { createNumericCell(stylesContainer, row, columnIndex, 0); } columnIndex++; } return columnIndex; } private int createMovesRowPart(Map<Date, Integer> data, HSSFRow row, int columnIndex, Date currentDate, StylesContainer stylesContainer) { if (data.containsKey(currentDate)) { createNumericCell(stylesContainer, row, columnIndex, data.get(currentDate)); columnIndex++; createNumericCell(stylesContainer, row, columnIndex, data.get(currentDate)); columnIndex++; } else { createNumericCell(stylesContainer, row, columnIndex, 0); columnIndex++; createNumericCell(stylesContainer, row, columnIndex, 0); columnIndex++; } return columnIndex; } private static class StylesContainer { private final HSSFCellStyle regularStyle; private final HSSFCellStyle headerStyle; StylesContainer(HSSFWorkbook workbook, FontsContainer fontsContainer) { regularStyle = workbook.createCellStyle(); regularStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); headerStyle = workbook.createCellStyle(); headerStyle.setFont(fontsContainer.headerFont); } private static HSSFCellStyle aligned(HSSFCellStyle style, short align) { style.setAlignment(align); return style; } } private static class FontsContainer { private final Font headerFont; FontsContainer(HSSFWorkbook workbook) { headerFont = workbook.createFont(); headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD); } } }