TTInfoDetailServiceImpl.java
10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
package com.bsth.service.schedule;
import com.bsth.entity.schedule.TTInfoDetail;
import com.bsth.repository.schedule.TTInfoDetailRepository;
import com.bsth.service.impl.BaseServiceImpl;
import com.bsth.service.schedule.utils.DataImportExportService;
import com.bsth.service.schedule.utils.DataToolsProperties;
import jxl.Sheet;
import jxl.Workbook;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by xu on 16/7/2.
*/
@Service
@EnableConfigurationProperties(DataToolsProperties.class)
public class TTInfoDetailServiceImpl extends BaseServiceImpl<TTInfoDetail, Long> implements TTInfoDetailService {
@Autowired
private DataImportExportService dataImportExportService;
@Autowired
private DataToolsProperties dataToolsProperties;
@Autowired
private TTInfoDetailRepository ttInfoDetailRepository;
/**
* 发车信息内部类。
*/
public static class FcInfo {
/** 时刻明细id */
private Long ttdid;
/** 发车时间 */
private String fcsj;
/** 班次类型 */
private String bc_type;
/** 线路上下行 */
private String xldir;
/** 是偶分班 */
private Boolean isfb;
public FcInfo() {
}
public FcInfo(String ttdid_str, String bc_type, String fcsj, String xldir, String isfb) {
this.ttdid = StringUtils.isEmpty(ttdid_str) ? null : Long.valueOf(ttdid_str);
this.bc_type = bc_type;
this.fcsj = fcsj;
this.xldir = xldir;
if ("N".equals(isfb))
this.isfb = false;
else if ("Y".equals(isfb))
this.isfb = true;
else
this.isfb = false;
}
public Long getTtdid() {
return ttdid;
}
public void setTtdid(Long ttdid) {
this.ttdid = ttdid;
}
public String getFcsj() {
return fcsj;
}
public void setFcsj(String fcsj) {
this.fcsj = fcsj;
}
public String getBc_type() {
return bc_type;
}
public void setBc_type(String bc_type) {
this.bc_type = bc_type;
}
public String getXldir() {
return xldir;
}
public void setXldir(String xldir) {
this.xldir = xldir;
}
public Boolean getIsfb() {
return isfb;
}
public void setIsfb(Boolean isfb) {
this.isfb = isfb;
}
}
/**
* 时刻表编辑用的返回数据。
*/
public static class EditInfo {
/** 标题数据 */
private List<String> header = new ArrayList<>();
/** 内容数据 */
private List<List<FcInfo>> contents = new ArrayList<>();
public List<String> getHeader() {
return header;
}
public void setHeader(List<String> header) {
this.header = header;
}
public List<List<FcInfo>> getContents() {
return contents;
}
public void setContents(List<List<FcInfo>> contents) {
this.contents = contents;
}
}
/**
* 获取待编辑的数据。
* @param xlid 线路id
* @param ttid 时刻表id
* @return
*/
public EditInfo getEditInfo(Integer xlid, Long ttid) throws Exception {
// 1、使用ktr转换获取输出文件
// 1.1、获取转换用ktr
File ktrFile = new File(this.getClass().getResource(
dataToolsProperties.getTtinfodetailForeditktr()).toURI());
TransMeta transMeta = new TransMeta(ktrFile.getAbsolutePath());
Trans trans = new Trans(transMeta);
// trans.setLogLevel(LogLevel.DEBUG);
// 1.2、设定命名参数,TODO:之后还要添加其他命名参数
String outputFilePath = "ttinfodetail_" + new DateTime().toString("yyyy-MM-dd_HH-mm-ss");
trans.setParameterValue("tempfilepath", dataToolsProperties.getTransTempdir() + File.separator + outputFilePath); // 数据输出文件路径
trans.setParameterValue("xlid", String.valueOf(xlid));
trans.setParameterValue("ttid", String.valueOf(ttid));
// 1.3、执行转换
trans.execute(null);
// 1.4、等待转换结束
trans.waitUntilFinished();
// 1.5、判定ktr错误数,注意这种错误代表部分数据错误,不会终止转换执行,一般设计ktr的时候,会有错误输出文件,TODO:以后考虑使用日志实时输出
if (trans.getErrors() > 0) {
throw new Exception("转换数据部分错误,请查看相关错误输出文件!");
}
// 1.6、获取最大的发车数,用于输出数据的数量
Long maxfcno = ttInfoDetailRepository.findMaxFcno(xlid, ttid);
if (maxfcno == null)
return new EditInfo();
// 2、读取ktr生成的excel数据,组织编辑用数据返回
// 2-1、读取Excel文件
Workbook book = Workbook.getWorkbook(new File(dataToolsProperties.getTransTempdir() +
File.separator + outputFilePath + ".xls"));
Sheet sheet = book.getSheet(0);
EditInfo editInfo = new EditInfo();
// 2-2、处理数据
String[] headarrays = new String[maxfcno.intValue() + 1];
headarrays[0] = "路牌";
for (int r = 1; r < sheet.getRows(); r++) {
List<FcInfo> fcInfos = new ArrayList<>();
// 每行第一列都是路牌
fcInfos.add(new FcInfo(null, null, sheet.getCell(0, r).getContents(), null, null)); // 用fcsj放置路牌显示
for (int c = 1; c <= maxfcno * 6; ) {
String ttdid_str = sheet.getCell(c, r).getContents(); // 时刻表明细id
String fcsj = sheet.getCell(c + 1, r).getContents(); // 发车时间
String fzdname = sheet.getCell(c + 2, r).getContents(); // 发车站点名称
String bctype = sheet.getCell(c + 3, r).getContents(); // 班次类型
String xldir = sheet.getCell(c + 4, r).getContents(); // 线路上下行
String isfb = sheet.getCell(c + 5, r).getContents(); // 是否分班
FcInfo fcInfo = new FcInfo(ttdid_str, bctype, fcsj, xldir, isfb);
if (StringUtils.isNotEmpty(fzdname))
headarrays[(int)(c / 6) + 1] = fzdname;
fcInfos.add(fcInfo);
c += 6;
}
editInfo.getContents().add(fcInfos);
}
editInfo.getHeader().addAll(Arrays.asList(headarrays));
return editInfo;
}
/**
* 上传并导入数据,和DataImportExportService的同名方法有差别。
* @param datafile form上传文件
* @param xlmc 线路名称
* @param ttinfoname 时刻表名字
* @param tccname 停车场名字
* @throws Exception
*/
public void fileDataImport(MultipartFile datafile,
String xlmc,
String ttinfoname,
String tccname) throws Exception {
// 1、上传数据文件
File uploadFile = dataImportExportService.uploadFile(datafile);
System.out.println("线路名称:" + xlmc);
System.out.println("时刻表名称:" + ttinfoname);
System.out.println("停车场名字:" + tccname);
System.out.println("时刻表明细上传文件:" + uploadFile);
// 2、jexcelapi读取excel文件
Workbook book = Workbook.getWorkbook(uploadFile);
Sheet sheet = book.getSheet(0);
List<String> columnames = new ArrayList<>();
for (int i = 0; i < sheet.getColumns(); i++) { // 获取第一行,数据,作为列名
columnames.add(sheet.getCell(i, 0).getContents());
}
System.out.println("表头1:" + StringUtils.join(columnames.toArray(), ","));
// 2、使用kettle运行封装数据导入逻辑的ktr转换文件
// 2.1、初始化kettle(组件初始化已经做了)
// 2.2、创建转换元数据,转换
File ktrFile = new File(this.getClass().getResource(
dataToolsProperties.getTtinfodetailMetadatainputktr()).toURI());
File ktrFile2 = new File(this.getClass().getResource(
dataToolsProperties.getTtinfodetailDatainputktr()).toURI());
TransMeta transMeta = new TransMeta(ktrFile.getAbsolutePath());
Trans trans = new Trans(transMeta);
// 2.3、设定命名参数,用于指定数据文件,注意每个ktr必须都有以下指定的命名参数
trans.setParameterValue("injectktrfile", ktrFile2.getAbsolutePath()); // 注入元数据的ktr文件
trans.setParameterValue("filepath", uploadFile.getAbsolutePath()); // 指定导入数据文件的位置
trans.setParameterValue("erroroutputdir", dataToolsProperties.getTransErrordir()); // ktr转换错误输出目录
trans.setParameterValue("xlname", xlmc); // 线路名称
trans.setParameterValue("ttinfoname", ttinfoname); // 时刻表名称
trans.setParameterValue("tccname", tccname); // 停车场名字
trans.setParameterValue("excelfieldnames", StringUtils.join(columnames.toArray(), ",")); // 时刻表excel输入字段名,以逗号连接
columnames.remove(0);
trans.setParameterValue("normalizefieldnames", StringUtils.join(columnames.toArray(), ",")); // 数据范式化字段名,以逗号连接
// TODO:可以考虑设定日志输出
// 2.4、执行转换
trans.execute(null);
// 2.5、等待转换结束
trans.waitUntilFinished();
// 3、判定ktr错误数,注意这种错误代表部分数据错误,不会终止转换执行,一般设计ktr的时候,会有错误输出文件,TODO:以后考虑使用日志实时输出
if (trans.getErrors() > 0) {
throw new Exception("转换数据部分错误,请查看相关错误输出文件!");
}
}
}