Commit f8160609b5a81c5272deb5219352031cb5eafadc

Authored by 徐烜
1 parent 80c9d172

1、重构时刻表预览数据导出功能,修正导出的excel班次排序问题(00点之后的班次要排到后面,而不是第一个班次)

src/main/java/com/bsth/service/schedule/impl/TTInfoDetailServiceImpl.java
... ... @@ -31,6 +31,7 @@ import com.bsth.service.schedule.exception.ScheduleException;
31 31 import com.bsth.service.schedule.timetable.TimetableExcelData;
32 32 import com.bsth.service.schedule.timetable.TimetableExcelFormatType;
33 33 import com.bsth.service.schedule.timetable.strategy.impl.TimetableExcelDataValidateStrategyImpl;
  34 +import com.bsth.service.schedule.timetable.strategy.impl.TimetableExcelPVDataExportStrategyImpl;
34 35 import com.bsth.service.schedule.utils.*;
35 36 import org.apache.commons.lang3.StringUtils;
36 37 import org.apache.commons.lang3.time.DateFormatUtils;
... ... @@ -158,184 +159,14 @@ public class TTInfoDetailServiceImpl extends BServiceImpl<TTInfoDetail, Long> im
158 159 @Transactional
159 160 @Override
160 161 public DataToolsFile exportPvInfo(Long ttInfoId) throws ScheduleException {
161   - // 1、获取时刻表,时刻表明细数据
162   - TTInfo ttInfo = this.infoRepository.findOneExtend(ttInfoId);
163   - List<TTInfoDetail> ttInfoDetailList = this.ttInfoDetailRepository.findByTtinfoId(ttInfoId);
164   - LOGGER.info("----------------- 开始导出时刻表[{}]预览视图信息---------------", ttInfo.getName());
165   -
166   - // 2、构造导出信息
167   - try {
168   - // 使用excel2007格式(xlsx)
169   - ExcelPoiOperator excelPoiOperator = new Excel2007PoiOperator();
170   - Workbook wb = excelPoiOperator.createWorkBook(); // 创建workbook
171   - Sheet sheet = excelPoiOperator.createWorkBookSheet(wb, "预览信息"); // 创建sheet
172   -
173   - // 创建表头(从第2行开始,第1行需要合并单元格显示站点名字)
174   - int[] headColNums = new int[] {0, 1, 2, 3, 4, 7, 8, 9, 10, 11};
175   - String[] headColLabels = new String[] {"序号", "路牌", "发车时间", "到达时间", "备注", "序号", "路牌", "发车时间", "到达时间", "备注"};
176   - int[] headColWidth = new int[] {10, 10, 20, 20, 35, 10, 10, 20, 20, 35};
177   -
178   - Row headRow = excelPoiOperator.createSheetRow(sheet, 1);
179   - headRow.setHeight((short) (35 * 20)); // 单位:1/20个点
180   - for (int i = 0; i < headColNums.length; i ++) {
181   - excelPoiOperator.createCell(
182   - wb, headRow, (short) headColNums[i],
183   - headColLabels[i], XSSFCell.CELL_TYPE_STRING,
184   - HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
185   - BorderStyle.THIN, new java.awt.Color(0x000000),
186   - (short) 14, new java.awt.Color(0xffffff), "宋体",
187   - new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
188   - sheet.setColumnWidth(headColNums[i], headColWidth[i] * 256); // 单位:1/256个字符宽度
189   - }
190   -
191   - // 获取上行线路并按照时间排序
192   - List<TTInfoDetail> upBcList = sortedByBcsjAsc(ttInfoDetailList, true);
193   - List<TTInfoDetail> downBcList = sortedByBcsjAsc(ttInfoDetailList, false);
194   - int rowDiff = upBcList.size() - downBcList.size();
195   - int rowSize;
196   - if (rowDiff >= 0) { // 上行班次多
197   - rowSize = downBcList.size();
198   - } else { // 下行班次多
199   - rowSize = upBcList.size();
200   - }
201   - for (int i = 0; i < rowSize; i++) {
202   - Row bcRow = excelPoiOperator.createSheetRow(sheet, i + 2);
203   - // 上行班次
204   - excelPoiOperator.createIntegerCell(wb, bcRow, (short) 0, i + 1);
205   - String lpName = upBcList.get(i).getLp().getLpName();
206   - if (StringUtils.isNumeric(lpName)) {
207   - excelPoiOperator.createIntegerCell(wb, bcRow, (short) 1, Integer.valueOf(lpName));
208   - } else {
209   - excelPoiOperator.createStringCell(wb, bcRow, (short) 1, lpName);
210   - }
211   - excelPoiOperator.createStringCell(wb, bcRow, (short) 2, upBcList.get(i).getFcsj());
212   - Date ddsj_up = MyDateUtils.hhssTimePlusMinunits(upBcList.get(i).getFcsj(), upBcList.get(i).getBcsj(), 0);
213   - excelPoiOperator.createStringCell(wb, bcRow, (short) 3, DateFormatUtils.format(ddsj_up, "HH:mm"));
214   - excelPoiOperator.createStringCell(wb, bcRow, (short) 4, StringUtils.trimToEmpty(upBcList.get(i).getRemark()));
215   -
216   - // 下行班次
217   - excelPoiOperator.createIntegerCell(wb, bcRow, (short) 7, i + 1);
218   - lpName = downBcList.get(i).getLp().getLpName();
219   - if (StringUtils.isNumeric(lpName)) {
220   - excelPoiOperator.createIntegerCell(wb, bcRow, (short) 8, Integer.valueOf(lpName));
221   - } else {
222   - excelPoiOperator.createStringCell(wb, bcRow, (short) 8, lpName);
223   - }
224   - excelPoiOperator.createStringCell(wb, bcRow, (short) 9, downBcList.get(i).getFcsj());
225   - Date ddsj_down = MyDateUtils.hhssTimePlusMinunits(downBcList.get(i).getFcsj(), downBcList.get(i).getBcsj(), 0);
226   - excelPoiOperator.createStringCell(wb, bcRow, (short) 10, DateFormatUtils.format(ddsj_down, "HH:mm"));
227   - excelPoiOperator.createStringCell(wb, bcRow, (short) 11, StringUtils.trimToEmpty(downBcList.get(i).getRemark()));
228   - }
229   -
230   - List<TTInfoDetail> rowDiffBcList; // 剩下的班次
231   - int rowDiffColIndexStart;
232   - if (rowDiff >= 0) { // 上行班次多
233   - rowDiffBcList = upBcList;
234   - rowDiffColIndexStart = 0;
235   - } else { // 下行班次多
236   - rowDiffBcList = downBcList;
237   - rowDiffColIndexStart = 7;
238   - }
239   - for (int i = rowSize; i < rowSize + Math.abs(rowDiff); i++) {
240   - Row bcRow = excelPoiOperator.createSheetRow(sheet, i + 2);
241   - excelPoiOperator.createIntegerCell(wb, bcRow, (short) (rowDiffColIndexStart + 0), i + 1);
242   - String lpName = rowDiffBcList.get(i).getLp().getLpName();
243   - if (StringUtils.isNumeric(lpName)) {
244   - excelPoiOperator.createIntegerCell(wb, bcRow, (short) (rowDiffColIndexStart + 1), Integer.valueOf(lpName));
245   - } else {
246   - excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 1), lpName);
247   - }
248   - excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 2), rowDiffBcList.get(i).getFcsj());
249   - Date ddsj = MyDateUtils.hhssTimePlusMinunits(rowDiffBcList.get(i).getFcsj(), rowDiffBcList.get(i).getBcsj(), 0);
250   - excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 3), DateFormatUtils.format(ddsj, "HH:mm"));
251   - excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 4), StringUtils.trimToEmpty(rowDiffBcList.get(i).getRemark()));
252   -
253   - }
254   -
255   - // 创建第一行,合并列
256   - sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 4));
257   - sheet.addMergedRegion(new CellRangeAddress(0, 0, 7, 11));
258   - Row firstRow = excelPoiOperator.createSheetRow(sheet, 0);
259   - firstRow.setHeight((short) (50 * 20)); // 单位:1/20个点
260   - if (upBcList.size() > 0 && downBcList.size() > 0) {
261   - String upBcLabel = "";
262   - for (TTInfoDetail ttInfoDetail : upBcList) {
263   - if ("normal".equals(ttInfoDetail.getBcType())) {
264   - upBcLabel = "上行站点:" + ttInfoDetail.getQdzName() + " >> " + ttInfoDetail.getZdzName();
265   - break;
266   - }
267   - }
268   - String downBcLabel = "";
269   - for (TTInfoDetail ttInfoDetail : downBcList) {
270   - if ("normal".equals(ttInfoDetail.getBcType())) {
271   - downBcLabel = "下行站点:" + ttInfoDetail.getQdzName() + " >> " + ttInfoDetail.getZdzName();
272   - break;
273   - }
274   - }
275   -
276   - excelPoiOperator.createCell(
277   - wb, firstRow, (short) 0,
278   - upBcLabel, XSSFCell.CELL_TYPE_STRING,
279   - HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
280   - BorderStyle.NONE, new java.awt.Color(0x000000),
281   - (short) 20, new java.awt.Color(0xffffff), "宋体",
282   - new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
283   -
284   - excelPoiOperator.createCell(
285   - wb, firstRow, (short) 7,
286   - downBcLabel, XSSFCell.CELL_TYPE_STRING,
287   - HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
288   - BorderStyle.NONE, new java.awt.Color(0x000000),
289   - (short) 20, new java.awt.Color(0xffffff), "宋体",
290   - new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
291   - }
292   -
293   - // 锁定第1第2行
294   - sheet.createFreezePane(0, 2);
295   -
296   - // wb内存写入文件
297   - String filepath = dataToolsProperties.getFileoutputDir() +
298   - File.separator +
299   - ttInfo.getName() + "预览信息-" +
300   - new DateTime().toString("yyyyMMddHHmmss") + ".xlsx";
301   - File file = new File(filepath);
302   - excelPoiOperator.writeExcel(file, wb);
303   -
304   - DataToolsFile dataToolsFile = new DataToolsFile();
305   - dataToolsFile.setFileType(DataToolsFileType.XLSX);
306   - dataToolsFile.setFile(file);
307   -
308   - return dataToolsFile;
309   -
310   - } catch (Exception exp) {
311   - LOGGER.error("----------------- 导出时刻表[{}]预览视图信息失败---------------", ttInfo.getName());
312   - throw new ScheduleException(exp);
313   - }
314   - }
315   - private List<TTInfoDetail> sortedByBcsjAsc(List<TTInfoDetail> bcList, boolean isUp) {
316   - List<TTInfoDetail> sortedList = new ArrayList<>();
317   - for (TTInfoDetail ttInfoDetail : bcList) {
318   - if (isUp) {
319   - if ("0".equals(ttInfoDetail.getXlDir())) {
320   - sortedList.add(ttInfoDetail);
321   - }
322   - } else {
323   - if ("1".equals(ttInfoDetail.getXlDir())) {
324   - sortedList.add(ttInfoDetail);
325   - }
326   - }
327   - }
328   - Collections.sort(sortedList, new Comparator<TTInfoDetail>() {
329   - @Override
330   - public int compare(TTInfoDetail o1, TTInfoDetail o2) {
331   - Date d1 = MyDateUtils.hhssTimePlusMinunits(o1.getFcsj(), 0, 0);
332   - Date d2 = MyDateUtils.hhssTimePlusMinunits(o2.getFcsj(), 0, 0);
333   -
334   - return d1.compareTo(d2);
335   - }
336   - });
337   -
338   - return sortedList;
  162 + TimetableExcelData timetableExcelData = TimetableExcelData.withPVExcelExportBuilder()
  163 + .setTtInfoId(ttInfoId)
  164 + .setTtInfoRepository(this.infoRepository)
  165 + .setTtInfoDetailRepository(this.ttInfoDetailRepository)
  166 + .setDataToolsProperties(this.dataToolsProperties)
  167 + .setTimetableExcelPVDataExportStrategy(new TimetableExcelPVDataExportStrategyImpl())
  168 + .build();
  169 + return timetableExcelData.doPVExport();
339 170 }
340 171  
341 172 @Transactional
... ...
src/main/java/com/bsth/service/schedule/timetable/TimetableExcelData.java
... ... @@ -3,16 +3,22 @@ package com.bsth.service.schedule.timetable;
3 3 import com.bsth.entity.Line;
4 4 import com.bsth.entity.LsStationRoute;
5 5 import com.bsth.entity.schedule.GuideboardInfo;
  6 +import com.bsth.entity.schedule.TTInfo;
  7 +import com.bsth.entity.schedule.TTInfoDetail;
  8 +import com.bsth.repository.schedule.TTInfoDetailRepository;
  9 +import com.bsth.repository.schedule.TTInfoRepository;
6 10 import com.bsth.service.LineService;
7 11 import com.bsth.service.StationRouteService;
8 12 import com.bsth.service.schedule.GuideboardInfoService;
9 13 import com.bsth.service.schedule.exception.ScheduleException;
10 14 import com.bsth.service.schedule.timetable.strategy.TimetableExcelDataImportStrategy;
11 15 import com.bsth.service.schedule.timetable.strategy.TimetableExcelDataValidateStrategy;
  16 +import com.bsth.service.schedule.timetable.strategy.TimetableExcelPVDataExportStrategy;
12 17 import com.bsth.service.schedule.utils.*;
13 18 import org.apache.commons.lang3.StringUtils;
14 19 import org.apache.poi.ss.usermodel.Sheet;
15 20 import org.apache.poi.ss.usermodel.Workbook;
  21 +import org.joda.time.DateTime;
16 22 import org.slf4j.Logger;
17 23 import org.slf4j.LoggerFactory;
18 24 import org.springframework.util.Assert;
... ... @@ -31,7 +37,7 @@ public class TimetableExcelData {
31 37 /** 日志记录器 */
32 38 private final static Logger LOG = LoggerFactory.getLogger(TimetableExcelData.class);
33 39  
34   - // ------------------ 公共属性及方法,如下:------------------- //
  40 + // ------------------ 验证,导入用公共属性及方法,如下:------------------- //
35 41 /** 待导入excel workbook对象 */
36 42 private Workbook excelWorkBook;
37 43 /** 待导入excel workbook 工作区对象 */
... ... @@ -138,6 +144,26 @@ public class TimetableExcelData {
138 144 this.timetableExcelFormatType);
139 145 }
140 146  
  147 + // ------------------ 导出用公共属性及方法,如下:------------------- //
  148 + /** 时刻表 */
  149 + private TTInfo ttInfo;
  150 + /** 时刻表明细 */
  151 + private List<TTInfoDetail> ttInfoDetailList;
  152 + /** 导出的文件路径 */
  153 + private String pvExportFilePath;
  154 +
  155 + // ------------------ 导出预览数据相关属性及方法,如下:---------------- //
  156 + /** 时刻表预览excel导出策略 */
  157 + private TimetableExcelPVDataExportStrategy timetableExcelPVDataExportStrategy;
  158 + /**
  159 + * 导出excel预览数据。
  160 + */
  161 + public DataToolsFile doPVExport() throws ScheduleException {
  162 + return this.timetableExcelPVDataExportStrategy.doPVExport(
  163 + this.ttInfo,
  164 + this.ttInfoDetailList,
  165 + this.pvExportFilePath);
  166 + }
141 167  
142 168 // ----------- 构造函数 ---------- //
143 169 public TimetableExcelData(ValidateBuilder validateBuilder) {
... ... @@ -176,6 +202,14 @@ public class TimetableExcelData {
176 202 // 构造内部Excel单元格二维数组
177 203 this.initInternalExcelCells();
178 204 }
  205 + public TimetableExcelData(PVExcelExportBuilder pvExcelExportBuilder) {
  206 + // 公共属性
  207 + this.ttInfo = pvExcelExportBuilder.ttInfo;
  208 + this.ttInfoDetailList = pvExcelExportBuilder.ttInfoDetailList;
  209 + this.pvExportFilePath = pvExcelExportBuilder.pvExportFilePath;
  210 + // 预览excel数据导出策略
  211 + this.timetableExcelPVDataExportStrategy = pvExcelExportBuilder.timetableExcelPVDataExportStrategy;
  212 + }
179 213  
180 214 // ----------- builder类 ----------- //
181 215 public static ValidateBuilder withValidateBuilder() {
... ... @@ -462,4 +496,79 @@ public class TimetableExcelData {
462 496 }
463 497 }
464 498  
  499 + public static PVExcelExportBuilder withPVExcelExportBuilder() {
  500 + return new PVExcelExportBuilder();
  501 + }
  502 + public static class PVExcelExportBuilder {
  503 + private PVExcelExportBuilder() {}
  504 +
  505 + /** 时刻表Id */
  506 + private Long ttInfoId;
  507 + /** 时刻表repo */
  508 + private TTInfoRepository ttInfoRepository;
  509 + /** 时刻表明细repo */
  510 + private TTInfoDetailRepository ttInfoDetailRepository;
  511 + /** 配置文件 */
  512 + private DataToolsProperties dataToolsProperties;
  513 + /** 时刻表预览数据Excel导出策略 */
  514 + private TimetableExcelPVDataExportStrategy timetableExcelPVDataExportStrategy;
  515 +
  516 + public PVExcelExportBuilder setTtInfoId(Long ttInfoId) {
  517 + this.ttInfoId = ttInfoId;
  518 + return this;
  519 + }
  520 +
  521 + public PVExcelExportBuilder setTtInfoRepository(TTInfoRepository ttInfoRepository) {
  522 + this.ttInfoRepository = ttInfoRepository;
  523 + return this;
  524 + }
  525 +
  526 + public PVExcelExportBuilder setTtInfoDetailRepository(TTInfoDetailRepository ttInfoDetailRepository) {
  527 + this.ttInfoDetailRepository = ttInfoDetailRepository;
  528 + return this;
  529 + }
  530 +
  531 + public PVExcelExportBuilder setDataToolsProperties(DataToolsProperties dataToolsProperties) {
  532 + this.dataToolsProperties = dataToolsProperties;
  533 + return this;
  534 + }
  535 +
  536 + public PVExcelExportBuilder setTimetableExcelPVDataExportStrategy(TimetableExcelPVDataExportStrategy timetableExcelPVDataExportStrategy) {
  537 + this.timetableExcelPVDataExportStrategy = timetableExcelPVDataExportStrategy;
  538 + return this;
  539 + }
  540 +
  541 + // ---------------- 内部生成的属性 ------------------ //
  542 + /** 时刻表 */
  543 + private TTInfo ttInfo;
  544 + /** 时刻表明细 */
  545 + private List<TTInfoDetail> ttInfoDetailList;
  546 + /** 导出的文件路径 */
  547 + private String pvExportFilePath;
  548 +
  549 + public TimetableExcelData build() {
  550 + // 1、参数验证
  551 + Assert.notNull(this.ttInfoId, "时刻表Id为空!");
  552 + Assert.notNull(ttInfoRepository, "时刻表repo为空!");
  553 + Assert.notNull(ttInfoDetailRepository, "时刻表明细repo为空!");
  554 + Assert.notNull(timetableExcelPVDataExportStrategy, "时刻表预览excel数据导出策略为空!");
  555 +
  556 + // 2、获取时刻表数据
  557 + this.ttInfo = this.ttInfoRepository.findOneExtend(this.ttInfoId);
  558 + Assert.notNull(this.ttInfo, "时刻表[id=" + this.ttInfoId + "]未找到!");
  559 +
  560 + // 3、获取时刻表明细数据
  561 + this.ttInfoDetailList = this.ttInfoDetailRepository.findByTtinfoId(this.ttInfoId);
  562 +
  563 + // 4、计算导出文件路径
  564 + Assert.notNull(this.dataToolsProperties, "dataTools配置文件类为空!");
  565 + this.pvExportFilePath = dataToolsProperties.getFileoutputDir() +
  566 + File.separator +
  567 + ttInfo.getName() + "预览信息-" +
  568 + new DateTime().toString("yyyyMMddHHmmss") + ".xlsx";
  569 +
  570 + return new TimetableExcelData(this);
  571 + }
  572 + }
  573 +
465 574 }
... ...
src/main/java/com/bsth/service/schedule/timetable/strategy/TimetableExcelPVDataExportStrategy.java 0 → 100644
  1 +package com.bsth.service.schedule.timetable.strategy;
  2 +
  3 +import com.bsth.entity.schedule.TTInfo;
  4 +import com.bsth.entity.schedule.TTInfoDetail;
  5 +import com.bsth.service.schedule.exception.ScheduleException;
  6 +import com.bsth.service.schedule.utils.DataToolsFile;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 时刻表预览数据excel导出策略。
  12 + */
  13 +public interface TimetableExcelPVDataExportStrategy {
  14 + /**
  15 + * 导出预览数据
  16 + * @param ttInfo 时刻表
  17 + * @param ttInfoDetailList 时刻表明细
  18 + * @param pvExportFilePath 导出文件路径
  19 + * @return 文件包装类
  20 + */
  21 + DataToolsFile doPVExport(
  22 + TTInfo ttInfo,
  23 + List<TTInfoDetail> ttInfoDetailList,
  24 + String pvExportFilePath) throws ScheduleException;
  25 +}
... ...
src/main/java/com/bsth/service/schedule/timetable/strategy/impl/TimetableExcelPVDataExportStrategyImpl.java 0 → 100644
  1 +package com.bsth.service.schedule.timetable.strategy.impl;
  2 +
  3 +import com.bsth.entity.schedule.TTInfo;
  4 +import com.bsth.entity.schedule.TTInfoDetail;
  5 +import com.bsth.service.schedule.datatools.Excel2007PoiOperator;
  6 +import com.bsth.service.schedule.datatools.ExcelPoiOperator;
  7 +import com.bsth.service.schedule.exception.ScheduleException;
  8 +import com.bsth.service.schedule.timetable.strategy.TimetableExcelPVDataExportStrategy;
  9 +import com.bsth.service.schedule.utils.DataToolsFile;
  10 +import com.bsth.service.schedule.utils.DataToolsFileType;
  11 +import com.bsth.service.schedule.utils.MyDateUtils;
  12 +import org.apache.commons.lang3.StringUtils;
  13 +import org.apache.commons.lang3.time.DateFormatUtils;
  14 +import org.apache.poi.ss.usermodel.*;
  15 +import org.apache.poi.ss.util.CellRangeAddress;
  16 +import org.apache.poi.xssf.usermodel.XSSFCell;
  17 +import org.slf4j.Logger;
  18 +import org.slf4j.LoggerFactory;
  19 +
  20 +import java.awt.Color;
  21 +import java.io.File;
  22 +import java.util.*;
  23 +import java.util.List;
  24 +
  25 +/**
  26 + * 时刻表预览数据excel导出策略实现。
  27 + */
  28 +public class TimetableExcelPVDataExportStrategyImpl implements TimetableExcelPVDataExportStrategy {
  29 + /** 日志记录器 */
  30 + private final static Logger LOG = LoggerFactory.getLogger(TimetableExcelPVDataExportStrategyImpl.class);
  31 +
  32 + @Override
  33 + public DataToolsFile doPVExport(
  34 + TTInfo ttInfo,
  35 + List<TTInfoDetail> ttInfoDetailList,
  36 + String pvExportFilePath) throws ScheduleException {
  37 + LOG.info("----------------- 开始导出时刻表[{}]预览视图信息---------------", ttInfo.getName());
  38 +
  39 + // 2、构造导出信息
  40 + try {
  41 + // 使用excel2007格式(xlsx)
  42 + ExcelPoiOperator excelPoiOperator = new Excel2007PoiOperator();
  43 + Workbook wb = excelPoiOperator.createWorkBook(); // 创建workbook
  44 + Sheet sheet = excelPoiOperator.createWorkBookSheet(wb, "预览信息"); // 创建sheet
  45 +
  46 + // 创建表头(从第2行开始,第1行需要合并单元格显示站点名字)
  47 + int[] headColNums = new int[] {0, 1, 2, 3, 4, 7, 8, 9, 10, 11};
  48 + String[] headColLabels = new String[] {"序号", "路牌", "发车时间", "到达时间", "备注", "序号", "路牌", "发车时间", "到达时间", "备注"};
  49 + int[] headColWidth = new int[] {10, 10, 20, 20, 35, 10, 10, 20, 20, 35};
  50 +
  51 + Row headRow = excelPoiOperator.createSheetRow(sheet, 1);
  52 + headRow.setHeight((short) (35 * 20)); // 单位:1/20个点
  53 + for (int i = 0; i < headColNums.length; i ++) {
  54 + excelPoiOperator.createCell(
  55 + wb, headRow, (short) headColNums[i],
  56 + headColLabels[i], XSSFCell.CELL_TYPE_STRING,
  57 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  58 + BorderStyle.THIN, new java.awt.Color(0x000000),
  59 + (short) 14, new java.awt.Color(0xffffff), "宋体",
  60 + new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
  61 + sheet.setColumnWidth(headColNums[i], headColWidth[i] * 256); // 单位:1/256个字符宽度
  62 + }
  63 +
  64 + // 获取上行线路并按照时间排序
  65 + List<TTInfoDetail> upBcList = sortedByBcsjAsc(ttInfoDetailList, true);
  66 + List<TTInfoDetail> downBcList = sortedByBcsjAsc(ttInfoDetailList, false);
  67 + int rowDiff = upBcList.size() - downBcList.size();
  68 + int rowSize;
  69 + if (rowDiff >= 0) { // 上行班次多
  70 + rowSize = downBcList.size();
  71 + } else { // 下行班次多
  72 + rowSize = upBcList.size();
  73 + }
  74 + for (int i = 0; i < rowSize; i++) {
  75 + Row bcRow = excelPoiOperator.createSheetRow(sheet, i + 2);
  76 + // 上行班次
  77 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) 0, i + 1);
  78 + String lpName = upBcList.get(i).getLp().getLpName();
  79 + if (StringUtils.isNumeric(lpName)) {
  80 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) 1, Integer.valueOf(lpName));
  81 + } else {
  82 + excelPoiOperator.createStringCell(wb, bcRow, (short) 1, lpName);
  83 + }
  84 + if ("out".equals(upBcList.get(i).getBcType())) {
  85 + excelPoiOperator.createStringCell(wb, bcRow, (short) 2, upBcList.get(i).getFcsj() + "-出场");
  86 + } else if ("in".equals(upBcList.get(i).getBcType())) {
  87 + excelPoiOperator.createStringCell(wb, bcRow, (short) 2, upBcList.get(i).getFcsj() + "-进场");
  88 + } else {
  89 + excelPoiOperator.createStringCell(wb, bcRow, (short) 2, upBcList.get(i).getFcsj());
  90 + }
  91 + Date ddsj_up = MyDateUtils.hhssTimePlusMinunits(upBcList.get(i).getFcsj(), upBcList.get(i).getBcsj(), 0);
  92 + excelPoiOperator.createStringCell(wb, bcRow, (short) 3, DateFormatUtils.format(ddsj_up, "HH:mm"));
  93 + excelPoiOperator.createStringCell(wb, bcRow, (short) 4, StringUtils.trimToEmpty(upBcList.get(i).getRemark()));
  94 +
  95 + // 下行班次
  96 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) 7, i + 1);
  97 + lpName = downBcList.get(i).getLp().getLpName();
  98 + if (StringUtils.isNumeric(lpName)) {
  99 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) 8, Integer.valueOf(lpName));
  100 + } else {
  101 + excelPoiOperator.createStringCell(wb, bcRow, (short) 8, lpName);
  102 + }
  103 + if ("out".equals(downBcList.get(i).getBcType())) {
  104 + excelPoiOperator.createStringCell(wb, bcRow, (short) 9, downBcList.get(i).getFcsj() + "-出场");
  105 + } else if ("in".equals(downBcList.get(i).getBcType())) {
  106 + excelPoiOperator.createStringCell(wb, bcRow, (short) 9, downBcList.get(i).getFcsj() + "-进场");
  107 + } else {
  108 + excelPoiOperator.createStringCell(wb, bcRow, (short) 9, downBcList.get(i).getFcsj());
  109 + }
  110 + Date ddsj_down = MyDateUtils.hhssTimePlusMinunits(downBcList.get(i).getFcsj(), downBcList.get(i).getBcsj(), 0);
  111 + excelPoiOperator.createStringCell(wb, bcRow, (short) 10, DateFormatUtils.format(ddsj_down, "HH:mm"));
  112 + excelPoiOperator.createStringCell(wb, bcRow, (short) 11, StringUtils.trimToEmpty(downBcList.get(i).getRemark()));
  113 + }
  114 +
  115 + List<TTInfoDetail> rowDiffBcList; // 剩下的班次
  116 + int rowDiffColIndexStart;
  117 + if (rowDiff >= 0) { // 上行班次多
  118 + rowDiffBcList = upBcList;
  119 + rowDiffColIndexStart = 0;
  120 + } else { // 下行班次多
  121 + rowDiffBcList = downBcList;
  122 + rowDiffColIndexStart = 7;
  123 + }
  124 + for (int i = rowSize; i < rowSize + Math.abs(rowDiff); i++) {
  125 + Row bcRow = excelPoiOperator.createSheetRow(sheet, i + 2);
  126 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) (rowDiffColIndexStart + 0), i + 1);
  127 + String lpName = rowDiffBcList.get(i).getLp().getLpName();
  128 + if (StringUtils.isNumeric(lpName)) {
  129 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) (rowDiffColIndexStart + 1), Integer.valueOf(lpName));
  130 + } else {
  131 + excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 1), lpName);
  132 + }
  133 + excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 2), rowDiffBcList.get(i).getFcsj());
  134 + Date ddsj = MyDateUtils.hhssTimePlusMinunits(rowDiffBcList.get(i).getFcsj(), rowDiffBcList.get(i).getBcsj(), 0);
  135 + excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 3), DateFormatUtils.format(ddsj, "HH:mm"));
  136 + excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 4), StringUtils.trimToEmpty(rowDiffBcList.get(i).getRemark()));
  137 +
  138 + }
  139 +
  140 + // 创建第一行,合并列
  141 + sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 4));
  142 + sheet.addMergedRegion(new CellRangeAddress(0, 0, 7, 11));
  143 + Row firstRow = excelPoiOperator.createSheetRow(sheet, 0);
  144 + firstRow.setHeight((short) (50 * 20)); // 单位:1/20个点
  145 + if (upBcList.size() > 0 && downBcList.size() > 0) {
  146 + String upBcLabel = "";
  147 + for (TTInfoDetail ttInfoDetail : upBcList) {
  148 + if ("normal".equals(ttInfoDetail.getBcType())) {
  149 + upBcLabel = "上行站点:" + ttInfoDetail.getQdzName() + " >> " + ttInfoDetail.getZdzName();
  150 + break;
  151 + }
  152 + }
  153 + String downBcLabel = "";
  154 + for (TTInfoDetail ttInfoDetail : downBcList) {
  155 + if ("normal".equals(ttInfoDetail.getBcType())) {
  156 + downBcLabel = "下行站点:" + ttInfoDetail.getQdzName() + " >> " + ttInfoDetail.getZdzName();
  157 + break;
  158 + }
  159 + }
  160 +
  161 + excelPoiOperator.createCell(
  162 + wb, firstRow, (short) 0,
  163 + upBcLabel, XSSFCell.CELL_TYPE_STRING,
  164 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  165 + BorderStyle.NONE, new java.awt.Color(0x000000),
  166 + (short) 20, new java.awt.Color(0xffffff), "宋体",
  167 + new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
  168 +
  169 + excelPoiOperator.createCell(
  170 + wb, firstRow, (short) 7,
  171 + downBcLabel, XSSFCell.CELL_TYPE_STRING,
  172 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  173 + BorderStyle.NONE, new java.awt.Color(0x000000),
  174 + (short) 20, new java.awt.Color(0xffffff), "宋体",
  175 + new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
  176 + }
  177 +
  178 + // 锁定第1第2行
  179 + sheet.createFreezePane(0, 2);
  180 +
  181 + // wb内存写入文件
  182 + File file = new File(pvExportFilePath);
  183 + excelPoiOperator.writeExcel(file, wb);
  184 +
  185 + DataToolsFile dataToolsFile = new DataToolsFile();
  186 + dataToolsFile.setFileType(DataToolsFileType.XLSX);
  187 + dataToolsFile.setFile(file);
  188 +
  189 + return dataToolsFile;
  190 +
  191 + } catch (Exception exp) {
  192 + LOG.error("----------------- 导出时刻表[{}]预览视图信息失败---------------", ttInfo.getName());
  193 + throw new ScheduleException(exp);
  194 + }
  195 + }
  196 +
  197 + private List<TTInfoDetail> sortedByBcsjAsc(List<TTInfoDetail> bcList, boolean isUp) {
  198 + List<TTInfoDetail> sortedList = new ArrayList<>();
  199 + for (TTInfoDetail ttInfoDetail : bcList) {
  200 + if (isUp) {
  201 + if ("0".equals(ttInfoDetail.getXlDir())) {
  202 + sortedList.add(ttInfoDetail);
  203 + }
  204 + } else {
  205 + if ("1".equals(ttInfoDetail.getXlDir())) {
  206 + sortedList.add(ttInfoDetail);
  207 + }
  208 + }
  209 + }
  210 + Collections.sort(sortedList, new Comparator<TTInfoDetail>() {
  211 + @Override
  212 + public int compare(TTInfoDetail o1, TTInfoDetail o2) {
  213 + // 使用 saTimeTablePreView.js中的判定方法,保持一致
  214 + // 判定如果发车时间是以00,01,02,03开头的,说明是下一天凌晨的班次,需要加1天判定
  215 + Date d1;
  216 + Date d2;
  217 + if (o1.getFcsj().indexOf("00:") == 0 ||
  218 + o1.getFcsj().indexOf("01:") == 0 ||
  219 + o1.getFcsj().indexOf("02:") == 0) {
  220 + d1 = MyDateUtils.hhssTimePlusMinunits(o1.getFcsj(), 0, 1);
  221 + } else {
  222 + d1 = MyDateUtils.hhssTimePlusMinunits(o1.getFcsj(), 0, 0);
  223 + }
  224 + if (o2.getFcsj().indexOf("00:") == 0 ||
  225 + o2.getFcsj().indexOf("01:") == 0 ||
  226 + o2.getFcsj().indexOf("02:") == 0) {
  227 + d2 = MyDateUtils.hhssTimePlusMinunits(o2.getFcsj(), 0, 1);
  228 + } else {
  229 + d2 = MyDateUtils.hhssTimePlusMinunits(o2.getFcsj(), 0, 0);
  230 + }
  231 +
  232 + return d1.compareTo(d2);
  233 + }
  234 + });
  235 +
  236 + return sortedList;
  237 + }
  238 +}
... ...
src/main/java/com/bsth/service/schedule/utils/MyDateUtils.java
... ... @@ -11,10 +11,10 @@ import java.util.Date;
11 11 public class MyDateUtils {
12 12  
13 13 /**
14   - * 将HH:mm格式的时间格式加上指定分钟后,生成新的日期返回。
15   - * @param hhssDate
16   - * @param minutes
17   - * @param day 是否跨天
  14 + * 将HH:mm格式的时间格式加上指定分钟、天后,生成新的日期返回。
  15 + * @param hhssDate 字符串时间(格式:HH:mm)
  16 + * @param minutes 分钟
  17 + * @param day 天数
18 18 */
19 19 public static Date hhssTimePlusMinunits(String hhssDate, Integer minutes, Integer day) {
20 20 try {
... ...