|
1
|
package com.lframework.xingyun.sc.controller.sample;
|
1
|
package com.lframework.xingyun.sc.controller.sample;
|
|
2
|
|
2
|
|
|
|
|
3
|
+import cn.hutool.core.io.resource.ClassPathResource;
|
|
3
|
import com.lframework.starter.bpm.dto.FlowTaskDto;
|
4
|
import com.lframework.starter.bpm.dto.FlowTaskDto;
|
|
4
|
import com.lframework.starter.bpm.mappers.FlowTaskWrapperMapper;
|
5
|
import com.lframework.starter.bpm.mappers.FlowTaskWrapperMapper;
|
|
5
|
import com.lframework.starter.bpm.vo.flow.task.QueryTodoTaskListVo;
|
6
|
import com.lframework.starter.bpm.vo.flow.task.QueryTodoTaskListVo;
|
|
@@ -10,7 +11,10 @@ import com.lframework.starter.web.core.utils.PageResultUtil; |
|
@@ -10,7 +11,10 @@ import com.lframework.starter.web.core.utils.PageResultUtil; |
|
10
|
import com.lframework.starter.web.core.components.resp.PageResult;
|
11
|
import com.lframework.starter.web.core.components.resp.PageResult;
|
|
11
|
import com.lframework.starter.web.core.components.resp.InvokeResult;
|
12
|
import com.lframework.starter.web.core.components.resp.InvokeResult;
|
|
12
|
import javax.annotation.Resource;
|
13
|
import javax.annotation.Resource;
|
|
|
|
14
|
+import javax.servlet.http.HttpServletResponse;
|
|
13
|
import javax.validation.constraints.NotBlank;
|
15
|
import javax.validation.constraints.NotBlank;
|
|
|
|
16
|
+import com.lframework.starter.web.inner.dto.system.UserInfoDto;
|
|
|
|
17
|
+import com.lframework.starter.web.inner.service.system.SysUserService;
|
|
14
|
import com.lframework.xingyun.sc.bo.sample.confirm.GetProductSampleConfirmationSlipBo;
|
18
|
import com.lframework.xingyun.sc.bo.sample.confirm.GetProductSampleConfirmationSlipBo;
|
|
15
|
import com.lframework.xingyun.sc.bo.sample.confirm.QueryProductSampleConfirmationSlipBo;
|
19
|
import com.lframework.xingyun.sc.bo.sample.confirm.QueryProductSampleConfirmationSlipBo;
|
|
16
|
import com.lframework.xingyun.sc.bo.sample.confirm.QueryProductSampleConfirmationSlipDetailBo;
|
20
|
import com.lframework.xingyun.sc.bo.sample.confirm.QueryProductSampleConfirmationSlipDetailBo;
|
|
@@ -18,6 +22,8 @@ import com.lframework.xingyun.sc.entity.ProductSampleConfirmationSlip; |
|
@@ -18,6 +22,8 @@ import com.lframework.xingyun.sc.entity.ProductSampleConfirmationSlip; |
|
18
|
import com.lframework.xingyun.sc.entity.ProductSampleConfirmationSlipDetail;
|
22
|
import com.lframework.xingyun.sc.entity.ProductSampleConfirmationSlipDetail;
|
|
19
|
import com.lframework.xingyun.sc.service.sample.ProductSampleConfirmationSlipDetailService;
|
23
|
import com.lframework.xingyun.sc.service.sample.ProductSampleConfirmationSlipDetailService;
|
|
20
|
import com.lframework.xingyun.sc.service.sample.ProductSampleConfirmationSlipService;
|
24
|
import com.lframework.xingyun.sc.service.sample.ProductSampleConfirmationSlipService;
|
|
|
|
25
|
+import com.lframework.xingyun.sc.utils.ExcelUtil;
|
|
|
|
26
|
+import com.lframework.xingyun.sc.utils.LatexFormulaExcelExporterUtil;
|
|
21
|
import com.lframework.xingyun.sc.vo.sample.confirm.CreateProductSampleConfirmationSlipVo;
|
27
|
import com.lframework.xingyun.sc.vo.sample.confirm.CreateProductSampleConfirmationSlipVo;
|
|
22
|
import com.lframework.xingyun.sc.vo.sample.confirm.QueryProductSampleConfirmationSlipDetailVo;
|
28
|
import com.lframework.xingyun.sc.vo.sample.confirm.QueryProductSampleConfirmationSlipDetailVo;
|
|
23
|
import com.lframework.xingyun.sc.vo.sample.confirm.QueryProductSampleConfirmationSlipVo;
|
29
|
import com.lframework.xingyun.sc.vo.sample.confirm.QueryProductSampleConfirmationSlipVo;
|
|
@@ -28,12 +34,25 @@ import com.lframework.starter.common.exceptions.impl.DefaultClientException; |
|
@@ -28,12 +34,25 @@ import com.lframework.starter.common.exceptions.impl.DefaultClientException; |
|
28
|
import io.swagger.annotations.ApiOperation;
|
34
|
import io.swagger.annotations.ApiOperation;
|
|
29
|
import com.lframework.starter.common.utils.CollectionUtil;
|
35
|
import com.lframework.starter.common.utils.CollectionUtil;
|
|
30
|
import io.swagger.annotations.Api;
|
36
|
import io.swagger.annotations.Api;
|
|
|
|
37
|
+import lombok.extern.slf4j.Slf4j;
|
|
31
|
import org.apache.commons.collections.CollectionUtils;
|
38
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
|
39
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
40
|
+import org.apache.poi.ss.usermodel.Cell;
|
|
|
|
41
|
+import org.apache.poi.ss.usermodel.Row;
|
|
|
|
42
|
+import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
43
|
+import org.apache.poi.ss.usermodel.Workbook;
|
|
|
|
44
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
|
45
|
+import org.apache.poi.util.IOUtils;
|
|
|
|
46
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
32
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
47
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
33
|
import org.springframework.validation.annotation.Validated;
|
48
|
import org.springframework.validation.annotation.Validated;
|
|
34
|
import org.springframework.web.bind.annotation.*;
|
49
|
import org.springframework.web.bind.annotation.*;
|
|
35
|
import javax.validation.Valid;
|
50
|
import javax.validation.Valid;
|
|
36
|
-import java.util.List;
|
51
|
+import java.io.FileNotFoundException;
|
|
|
|
52
|
+import java.io.IOException;
|
|
|
|
53
|
+import java.io.InputStream;
|
|
|
|
54
|
+import java.net.URLEncoder;
|
|
|
|
55
|
+import java.util.*;
|
|
37
|
import java.util.stream.Collectors;
|
56
|
import java.util.stream.Collectors;
|
|
38
|
|
57
|
|
|
39
|
/**
|
58
|
/**
|
|
@@ -41,6 +60,7 @@ import java.util.stream.Collectors; |
|
@@ -41,6 +60,7 @@ import java.util.stream.Collectors; |
|
41
|
*
|
60
|
*
|
|
42
|
*/
|
61
|
*/
|
|
43
|
@Api(tags = "产品试样确认单")
|
62
|
@Api(tags = "产品试样确认单")
|
|
|
|
63
|
+@Slf4j
|
|
44
|
@Validated
|
64
|
@Validated
|
|
45
|
@RestController
|
65
|
@RestController
|
|
46
|
@RequestMapping("/confirmationSlip")
|
66
|
@RequestMapping("/confirmationSlip")
|
|
@@ -52,6 +72,9 @@ public class ProductSampleConfirmationSlipController extends DefaultBaseControll |
|
@@ -52,6 +72,9 @@ public class ProductSampleConfirmationSlipController extends DefaultBaseControll |
|
52
|
private ProductSampleConfirmationSlipDetailService productSampleConfirmationSlipDetailService;
|
72
|
private ProductSampleConfirmationSlipDetailService productSampleConfirmationSlipDetailService;
|
|
53
|
@Resource
|
73
|
@Resource
|
|
54
|
private FlowTaskWrapperMapper flowTaskWrapperMapper;
|
74
|
private FlowTaskWrapperMapper flowTaskWrapperMapper;
|
|
|
|
75
|
+ @Resource
|
|
|
|
76
|
+ private SysUserService sysUserService;
|
|
|
|
77
|
+
|
|
55
|
|
78
|
|
|
56
|
/**
|
79
|
/**
|
|
57
|
* 查询列表
|
80
|
* 查询列表
|
|
@@ -147,4 +170,349 @@ public class ProductSampleConfirmationSlipController extends DefaultBaseControll |
|
@@ -147,4 +170,349 @@ public class ProductSampleConfirmationSlipController extends DefaultBaseControll |
|
147
|
|
170
|
|
|
148
|
return InvokeResultBuilder.success();
|
171
|
return InvokeResultBuilder.success();
|
|
149
|
}
|
172
|
}
|
|
|
|
173
|
+
|
|
|
|
174
|
+ @ApiOperation("产品试样确认单")
|
|
|
|
175
|
+ @GetMapping("/printConfirmationSlip")
|
|
|
|
176
|
+ public void printConfirmationSlip(@NotBlank(message = "id不能为空") String id, HttpServletResponse response) throws IOException {
|
|
|
|
177
|
+ ProductSampleConfirmationSlip data = productSampleConfirmationSlipService.findById(id);
|
|
|
|
178
|
+
|
|
|
|
179
|
+ // 设置响应头
|
|
|
|
180
|
+ setupResponse(response, data.getOrderingUnitName() + "-产品试样确认单打印.xlsx");
|
|
|
|
181
|
+
|
|
|
|
182
|
+ GetProductSampleConfirmationSlipBo result = new GetProductSampleConfirmationSlipBo(data);
|
|
|
|
183
|
+ QueryProductSampleConfirmationSlipDetailVo vo = new QueryProductSampleConfirmationSlipDetailVo();
|
|
|
|
184
|
+ vo.setConfirmationSlipId(id);
|
|
|
|
185
|
+ List<ProductSampleConfirmationSlipDetail> detailList = productSampleConfirmationSlipDetailService.query(vo);
|
|
|
|
186
|
+ List<QueryProductSampleConfirmationSlipDetailBo> detailBoList = new ArrayList<>();
|
|
|
|
187
|
+ if (CollectionUtil.isNotEmpty(detailList)) {
|
|
|
|
188
|
+ detailBoList = detailList.stream().map(QueryProductSampleConfirmationSlipDetailBo::new).collect(Collectors.toList());
|
|
|
|
189
|
+ }
|
|
|
|
190
|
+
|
|
|
|
191
|
+
|
|
|
|
192
|
+ try {
|
|
|
|
193
|
+ // 加载模板文件
|
|
|
|
194
|
+ ClassPathResource templateResource = new ClassPathResource("templates/confirmationSlipTemplate.xlsx");
|
|
|
|
195
|
+ try (InputStream inputStream = templateResource.getStream();
|
|
|
|
196
|
+ Workbook workbook = new XSSFWorkbook(inputStream)) {
|
|
|
|
197
|
+ try {
|
|
|
|
198
|
+ Sheet sheet = workbook.getSheetAt(0);
|
|
|
|
199
|
+ int startRow = 5; // 产品开始行
|
|
|
|
200
|
+ if (CollectionUtils.isNotEmpty(detailBoList)) {
|
|
|
|
201
|
+
|
|
|
|
202
|
+ for (int i = 1; i < detailBoList.size(); i++) {
|
|
|
|
203
|
+ int targetBrandRow = startRow + (i * 2); // 第2条:5+2=7(Excel第8行)
|
|
|
|
204
|
+ int targetSpecRow = startRow + (i * 2) + 1; // 第2条:5+3=8(Excel第9行)
|
|
|
|
205
|
+ // 复制模板的两行
|
|
|
|
206
|
+ copyRow(workbook, sheet, startRow, targetBrandRow); // 牌号行模板 → 目标
|
|
|
|
207
|
+ //合并B-D
|
|
|
|
208
|
+ CellRangeAddress mergeRegion1 = new CellRangeAddress(targetBrandRow, targetBrandRow, 1, 3);
|
|
|
|
209
|
+ sheet.addMergedRegion(mergeRegion1);
|
|
|
|
210
|
+ copyRow(workbook, sheet, startRow + 1, targetSpecRow); // 规格行模板 → 目
|
|
|
|
211
|
+ //合并B-C
|
|
|
|
212
|
+ CellRangeAddress mergeRegion2 = new CellRangeAddress(targetSpecRow, targetSpecRow, 1, 2);
|
|
|
|
213
|
+ sheet.addMergedRegion(mergeRegion2);
|
|
|
|
214
|
+ //合并E targetBrandRow-E targetSpecRow
|
|
|
|
215
|
+ CellRangeAddress mergeRegion3 = new CellRangeAddress(targetBrandRow, targetSpecRow, 4, 4);
|
|
|
|
216
|
+ sheet.addMergedRegion(mergeRegion3);
|
|
|
|
217
|
+ //合并F targetBrandRow-F targetSpecRow
|
|
|
|
218
|
+ CellRangeAddress mergeRegion4 = new CellRangeAddress(targetBrandRow, targetSpecRow, 5, 5);
|
|
|
|
219
|
+ sheet.addMergedRegion(mergeRegion4);
|
|
|
|
220
|
+ //合并G targetBrandRow-G targetSpecRow
|
|
|
|
221
|
+ CellRangeAddress mergeRegion5 = new CellRangeAddress(targetBrandRow, targetSpecRow, 6, 6);
|
|
|
|
222
|
+ sheet.addMergedRegion(mergeRegion5);
|
|
|
|
223
|
+ }
|
|
|
|
224
|
+ // 创建合并区域:A5:A10
|
|
|
|
225
|
+ int size = detailBoList.size();
|
|
|
|
226
|
+ if (size > 0) {
|
|
|
|
227
|
+ int endRow = startRow + size * 2;
|
|
|
|
228
|
+ CellRangeAddress region = new CellRangeAddress(startRow - 1, endRow, 0, 0);
|
|
|
|
229
|
+ sheet.addMergedRegion(region);
|
|
|
|
230
|
+ }
|
|
|
|
231
|
+ //合并B6-D6
|
|
|
|
232
|
+ CellRangeAddress mergeRegion6 = new CellRangeAddress(5, 5, 1, 3);
|
|
|
|
233
|
+ sheet.addMergedRegion(mergeRegion6);
|
|
|
|
234
|
+ //合并B7-C7
|
|
|
|
235
|
+ CellRangeAddress mergeRegion7 = new CellRangeAddress(6, 6, 1, 2);
|
|
|
|
236
|
+ sheet.addMergedRegion(mergeRegion7);
|
|
|
|
237
|
+ //合并E6-E7
|
|
|
|
238
|
+ CellRangeAddress mergeRegion8 = new CellRangeAddress(5, 6, 4, 4);
|
|
|
|
239
|
+ sheet.addMergedRegion(mergeRegion8);
|
|
|
|
240
|
+ //合并F6-F7
|
|
|
|
241
|
+ CellRangeAddress mergeRegion9 = new CellRangeAddress(5, 6, 5, 5);
|
|
|
|
242
|
+ sheet.addMergedRegion(mergeRegion9);
|
|
|
|
243
|
+ //合并G6-G7
|
|
|
|
244
|
+ CellRangeAddress mergeRegion10 = new CellRangeAddress(5, 6, 6, 6);
|
|
|
|
245
|
+ sheet.addMergedRegion(mergeRegion10);
|
|
|
|
246
|
+ for (int i = 0; i < detailBoList.size(); i++) {
|
|
|
|
247
|
+ QueryProductSampleConfirmationSlipDetailBo bo = detailBoList.get(i);
|
|
|
|
248
|
+ List<LatexFormulaExcelExporterUtil.FormulaComponent> formulaComponentList = new ArrayList<>(3);
|
|
|
|
249
|
+ if (bo.getThickness() != null) {
|
|
|
|
250
|
+ LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
|
|
|
|
251
|
+ formulaComponent.setBase(bo.getThickness());
|
|
|
|
252
|
+ formulaComponent.setSup(bo.getThicknessTolPos());
|
|
|
|
253
|
+ formulaComponent.setSub(bo.getThicknessTolNeg());
|
|
|
|
254
|
+ formulaComponentList.add(formulaComponent);
|
|
|
|
255
|
+ }
|
|
|
|
256
|
+
|
|
|
|
257
|
+ if (bo.getWidth() != null) {
|
|
|
|
258
|
+ LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
|
|
|
|
259
|
+ formulaComponent.setBase(bo.getWidth());
|
|
|
|
260
|
+ formulaComponent.setSup(bo.getWidthTolPos());
|
|
|
|
261
|
+ formulaComponent.setSub(bo.getWidthTolNeg());
|
|
|
|
262
|
+ formulaComponentList.add(formulaComponent);
|
|
|
|
263
|
+ }
|
|
|
|
264
|
+
|
|
|
|
265
|
+ if (bo.getLength() != null) {
|
|
|
|
266
|
+ LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
|
|
|
|
267
|
+ formulaComponent.setBase(bo.getLength());
|
|
|
|
268
|
+ formulaComponent.setSup(bo.getLengthTolPos());
|
|
|
|
269
|
+ formulaComponent.setSub(bo.getLengthTolNeg());
|
|
|
|
270
|
+ formulaComponentList.add(formulaComponent);
|
|
|
|
271
|
+ }
|
|
|
|
272
|
+ int brandRow = startRow + (i * 2); // 5, 7, 9, ...
|
|
|
|
273
|
+ int specRow = startRow + (i * 2) + 1; // 6, 8, 10, ...
|
|
|
|
274
|
+ ExcelUtil.setCellValue(sheet, brandRow, 1, bo.getBrand());
|
|
|
|
275
|
+ ExcelUtil.setCellValue(sheet, specRow, 3, bo.getStatus());
|
|
|
|
276
|
+ String latex = LatexFormulaExcelExporterUtil.convertToLatex(formulaComponentList);
|
|
|
|
277
|
+ if (StringUtils.isNotBlank(latex)) {
|
|
|
|
278
|
+ LatexFormulaExcelExporterUtil.insertLatexImageToCell(workbook, sheet, latex, specRow, 1, 1, 2);
|
|
|
|
279
|
+ }
|
|
|
|
280
|
+
|
|
|
|
281
|
+ ExcelUtil.setCellValue(sheet, brandRow, 4, bo.getQuantity());
|
|
|
|
282
|
+ ExcelUtil.setCellValue(sheet, brandRow, 5, bo.getProvideSamplesName());
|
|
|
|
283
|
+ ExcelUtil.setCellValue(sheet, brandRow, 6, bo.getClearParametersName());
|
|
|
|
284
|
+ }
|
|
|
|
285
|
+ }
|
|
|
|
286
|
+
|
|
|
|
287
|
+ Map<String, Object> dataMap = new HashMap<>();
|
|
|
|
288
|
+ dataMap.put("orderingUnitName", result.getOrderingUnitName() == null ? "" : result.getOrderingUnitName());
|
|
|
|
289
|
+ dataMap.put("sampleTypeName", result.getSampleTypeName() == null ? "" : result.getSampleTypeName());
|
|
|
|
290
|
+ dataMap.put("customerTypeName", result.getCustomerTypeName() == null ? "" : result.getCustomerTypeName());
|
|
|
|
291
|
+ dataMap.put("workshopName", result.getWorkshopName() == null ? "" : result.getWorkshopName());
|
|
|
|
292
|
+ dataMap.put("belongingBreed", result.getBelongingBreed() == null ? "" : result.getBelongingBreed());
|
|
|
|
293
|
+ dataMap.put("originalSupplierPeer", result.getOriginalSupplierPeer() == null ? "" : result.getOriginalSupplierPeer());
|
|
|
|
294
|
+ dataMap.put("totalQuantity", result.getTotalQuantity() == null ? "" : result.getTotalQuantity().stripTrailingZeros());
|
|
|
|
295
|
+ dataMap.put("sampleQuantityRegulation", result.isSampleQuantityRegulation() ? "是" : "否");
|
|
|
|
296
|
+ dataMap.put("specificationQuantityRegulation", result.isSpecificationQuantityRegulation() ? "是" : "否");
|
|
|
|
297
|
+ dataMap.put("sampleFrequency", result.getSampleFrequency() == null ? "" : result.getSampleFrequency());
|
|
|
|
298
|
+ dataMap.put("earlyNonconformityDescription", result.getEarlyNonconformityDescription() == null ? "" : result.getEarlyNonconformityDescription());
|
|
|
|
299
|
+ dataMap.put("preparedByName", result.getPreparedByName() == null ? "" : result.getPreparedByName());
|
|
|
|
300
|
+ if (StringUtils.isNotEmpty(result.getOfficeClerk())) {
|
|
|
|
301
|
+ UserInfoDto info = sysUserService.getInfo(result.getOfficeClerk());
|
|
|
|
302
|
+ dataMap.put("officeClerkName", info == null ? "" : info.getName() == null ? "" : info.getName());
|
|
|
|
303
|
+ } else {
|
|
|
|
304
|
+ dataMap.put("officeClerkName", "");
|
|
|
|
305
|
+ }
|
|
|
|
306
|
+ dataMap.put("officeSupervisorOpinion", "");
|
|
|
|
307
|
+ if (StringUtils.isNotEmpty(result.getOfficeSupervisorReview())) {
|
|
|
|
308
|
+ if ("PASS".equals(result.getOfficeSupervisorReview())) {
|
|
|
|
309
|
+ dataMap.put("officeSupervisorPass", "☑同意生产");
|
|
|
|
310
|
+ dataMap.put("officeSupervisorRefuse", "□不同意生产及原因");
|
|
|
|
311
|
+ } else {
|
|
|
|
312
|
+ dataMap.put("officeSupervisorPass", "□同意生产");
|
|
|
|
313
|
+ dataMap.put("officeSupervisorRefuse", "☑不同意生产及原因");
|
|
|
|
314
|
+ dataMap.put("officeSupervisorOpinion", result.getOfficeSupervisorOpinion() == null ? "" : result.getOfficeSupervisorOpinion());
|
|
|
|
315
|
+ }
|
|
|
|
316
|
+ } else {
|
|
|
|
317
|
+ dataMap.put("officeSupervisorPass", "□同意生产");
|
|
|
|
318
|
+ dataMap.put("officeSupervisorRefuse", "□不同意生产及原因");
|
|
|
|
319
|
+ }
|
|
|
|
320
|
+ dataMap.put("marketingDeputyDirectorOpinion", "");
|
|
|
|
321
|
+ if (StringUtils.isNotEmpty(result.getMarketingDeputyDirectorReview())) {
|
|
|
|
322
|
+ if ("PASS".equals(result.getMarketingDeputyDirectorReview())) {
|
|
|
|
323
|
+ dataMap.put("marketingDeputyDirectorPass", "☑同意生产");
|
|
|
|
324
|
+ dataMap.put("marketingDeputyDirectorRefuse", "□不同意生产及原因");
|
|
|
|
325
|
+ } else {
|
|
|
|
326
|
+ dataMap.put("marketingDeputyDirectorPass", "□同意生产");
|
|
|
|
327
|
+ dataMap.put("marketingDeputyDirectorRefuse", "☑不同意生产及原因");
|
|
|
|
328
|
+ dataMap.put("marketingDeputyDirectorOpinion", result.getMarketingDeputyDirectorOpinion() == null ? "" : result.getMarketingDeputyDirectorOpinion());
|
|
|
|
329
|
+ }
|
|
|
|
330
|
+ } else {
|
|
|
|
331
|
+ dataMap.put("marketingDeputyDirectorPass", "□同意生产");
|
|
|
|
332
|
+ dataMap.put("marketingDeputyDirectorRefuse", "□不同意生产及原因");
|
|
|
|
333
|
+ }
|
|
|
|
334
|
+ dataMap.put("officeManagementSupervisorOpinion", "");
|
|
|
|
335
|
+ if (StringUtils.isNotEmpty(result.getOfficeManagementSupervisorReview())) {
|
|
|
|
336
|
+ if ("PASS".equals(result.getOfficeManagementSupervisorReview())) {
|
|
|
|
337
|
+ dataMap.put("officeManagementSupervisorPass", "☑同意生产");
|
|
|
|
338
|
+ dataMap.put("officeManagementSupervisorRefuse", "□不同意生产及原因");
|
|
|
|
339
|
+ } else {
|
|
|
|
340
|
+ dataMap.put("officeManagementSupervisorPass", "□同意生产");
|
|
|
|
341
|
+ dataMap.put("officeManagementSupervisorRefuse", "☑不同意生产及原因");
|
|
|
|
342
|
+ dataMap.put("officeManagementSupervisorOpinion", result.getOfficeManagementSupervisorOpinion() == null ? "" : result.getOfficeManagementSupervisorOpinion());
|
|
|
|
343
|
+ }
|
|
|
|
344
|
+ } else {
|
|
|
|
345
|
+ dataMap.put("officeManagementSupervisorPass", "□同意生产");
|
|
|
|
346
|
+ dataMap.put("officeManagementSupervisorRefuse", "□不同意生产及原因");
|
|
|
|
347
|
+ }
|
|
|
|
348
|
+ dataMap.put("qualityManagerOpinion", "");
|
|
|
|
349
|
+ if (StringUtils.isNotEmpty(result.getQualityManagerReview())) {
|
|
|
|
350
|
+ if ("PASS".equals(result.getQualityManagerReview())) {
|
|
|
|
351
|
+ dataMap.put("qualityManagerPass", "☑同意生产");
|
|
|
|
352
|
+ dataMap.put("qualityManagerRefuse", "□不同意生产及原因");
|
|
|
|
353
|
+ } else {
|
|
|
|
354
|
+ dataMap.put("qualityManagerPass", "□同意生产");
|
|
|
|
355
|
+ dataMap.put("qualityManagerRefuse", "☑不同意生产及原因");
|
|
|
|
356
|
+ dataMap.put("qualityManagerOpinion", result.getQualityManagerOpinion() == null ? "" : result.getQualityManagerOpinion());
|
|
|
|
357
|
+ }
|
|
|
|
358
|
+ } else {
|
|
|
|
359
|
+ dataMap.put("qualityManagerPass", "□同意生产");
|
|
|
|
360
|
+ dataMap.put("qualityManagerRefuse", "□不同意生产及原因");
|
|
|
|
361
|
+ }
|
|
|
|
362
|
+ dataMap.put("branchFactorySupervisorOpinion", "");
|
|
|
|
363
|
+ if (StringUtils.isNotEmpty(result.getBranchFactorySupervisorReview())) {
|
|
|
|
364
|
+ if ("PASS".equals(result.getBranchFactorySupervisorReview())) {
|
|
|
|
365
|
+ dataMap.put("branchFactorySupervisorPass", "☑同意生产");
|
|
|
|
366
|
+ dataMap.put("branchFactorySupervisorRefuse", "□不同意生产及原因");
|
|
|
|
367
|
+ } else {
|
|
|
|
368
|
+ dataMap.put("branchFactorySupervisorPass", "□同意生产");
|
|
|
|
369
|
+ dataMap.put("branchFactorySupervisorRefuse", "☑不同意生产及原因");
|
|
|
|
370
|
+ dataMap.put("branchFactorySupervisorOpinion", result.getBranchFactorySupervisorOpinion() == null ? "" : result.getBranchFactorySupervisorOpinion());
|
|
|
|
371
|
+ }
|
|
|
|
372
|
+ } else {
|
|
|
|
373
|
+ dataMap.put("branchFactorySupervisorPass", "□同意生产");
|
|
|
|
374
|
+ dataMap.put("branchFactorySupervisorRefuse", "□不同意生产及原因");
|
|
|
|
375
|
+ }
|
|
|
|
376
|
+ dataMap.put("marketingDepartmentManagerOpinion", "");
|
|
|
|
377
|
+ if (StringUtils.isNotEmpty(result.getMarketingDepartmentManagerReview())) {
|
|
|
|
378
|
+ if ("PASS".equals(result.getMarketingDepartmentManagerReview())) {
|
|
|
|
379
|
+ dataMap.put("marketingDepartmentManagerPass", "☑同意生产");
|
|
|
|
380
|
+ dataMap.put("marketingDepartmentManagerRefuse", "□不同意生产及原因");
|
|
|
|
381
|
+ } else {
|
|
|
|
382
|
+ dataMap.put("marketingDepartmentManagerPass", "□同意生产");
|
|
|
|
383
|
+ dataMap.put("marketingDepartmentManagerRefuse", "☑不同意生产及原因");
|
|
|
|
384
|
+ dataMap.put("marketingDepartmentManagerOpinion", result.getMarketingDepartmentManagerOpinion() == null ? "" : result.getMarketingDepartmentManagerOpinion());
|
|
|
|
385
|
+ }
|
|
|
|
386
|
+ } else {
|
|
|
|
387
|
+ dataMap.put("marketingDepartmentManagerPass", "□同意生产");
|
|
|
|
388
|
+ dataMap.put("marketingDepartmentManagerRefuse", "□不同意生产及原因");
|
|
|
|
389
|
+ }
|
|
|
|
390
|
+ dataMap.put("marketingCenterSupervisorOpinion", "");
|
|
|
|
391
|
+ if (StringUtils.isNotEmpty(result.getMarketingCenterSupervisorReview())) {
|
|
|
|
392
|
+ if ("PASS".equals(result.getMarketingCenterSupervisorReview())) {
|
|
|
|
393
|
+ dataMap.put("marketingCenterSupervisorPass", "☑同意生产");
|
|
|
|
394
|
+ dataMap.put("marketingCenterSupervisorRefuse", "□不同意生产及原因");
|
|
|
|
395
|
+ } else {
|
|
|
|
396
|
+ dataMap.put("marketingCenterSupervisorPass", "□同意生产");
|
|
|
|
397
|
+ dataMap.put("marketingCenterSupervisorRefuse", "☑不同意生产及原因");
|
|
|
|
398
|
+ dataMap.put("marketingCenterSupervisorOpinion", result.getMarketingCenterSupervisorOpinion() == null ? "" : result.getMarketingCenterSupervisorOpinion());
|
|
|
|
399
|
+ }
|
|
|
|
400
|
+ } else {
|
|
|
|
401
|
+ dataMap.put("marketingCenterSupervisorPass", "□同意生产");
|
|
|
|
402
|
+ dataMap.put("marketingCenterSupervisorRefuse", "□不同意生产及原因");
|
|
|
|
403
|
+ }
|
|
|
|
404
|
+ dataMap.put("generalManagerOpinion", "");
|
|
|
|
405
|
+ if (StringUtils.isNotEmpty(result.getGeneralManagerReview())) {
|
|
|
|
406
|
+ if ("PASS".equals(result.getGeneralManagerReview())) {
|
|
|
|
407
|
+ dataMap.put("generalManagerPass", "☑同意生产");
|
|
|
|
408
|
+ dataMap.put("generalManagerRefuse", "□不同意生产及原因");
|
|
|
|
409
|
+ } else {
|
|
|
|
410
|
+ dataMap.put("generalManagerPass", "□同意生产");
|
|
|
|
411
|
+ dataMap.put("generalManagerRefuse", "☑不同意生产及原因");
|
|
|
|
412
|
+ dataMap.put("generalManagerOpinion", result.getGeneralManagerOpinion() == null ? "" : result.getGeneralManagerOpinion());
|
|
|
|
413
|
+ }
|
|
|
|
414
|
+ } else {
|
|
|
|
415
|
+ dataMap.put("generalManagerPass", "□同意生产");
|
|
|
|
416
|
+ dataMap.put("generalManagerRefuse", "□不同意生产及原因");
|
|
|
|
417
|
+ }
|
|
|
|
418
|
+ ExcelUtil.processTemplate(workbook, dataMap);
|
|
|
|
419
|
+
|
|
|
|
420
|
+ // 写入响应流
|
|
|
|
421
|
+ workbook.write(response.getOutputStream());
|
|
|
|
422
|
+ response.getOutputStream().flush();
|
|
|
|
423
|
+ } finally {
|
|
|
|
424
|
+ IOUtils.closeQuietly(workbook);
|
|
|
|
425
|
+ }
|
|
|
|
426
|
+
|
|
|
|
427
|
+ } catch (FileNotFoundException e) {
|
|
|
|
428
|
+ throw new RuntimeException("模板文件不存在: templates/confirmationSlipTemplate.xlsx", e);
|
|
|
|
429
|
+ } catch (IOException e) {
|
|
|
|
430
|
+ throw new RuntimeException("无法读取模板文件: templates/confirmationSlipTemplate.xlsx", e);
|
|
|
|
431
|
+ }
|
|
|
|
432
|
+ } catch (Exception e) {
|
|
|
|
433
|
+ log.error("产品试样确认单打印: {}", e.getMessage(), e);
|
|
|
|
434
|
+ throw e;
|
|
|
|
435
|
+ }
|
|
|
|
436
|
+ }
|
|
|
|
437
|
+
|
|
|
|
438
|
+
|
|
|
|
439
|
+ /**
|
|
|
|
440
|
+ * 设置HTTP响应头
|
|
|
|
441
|
+ */
|
|
|
|
442
|
+ private void setupResponse(HttpServletResponse response, String fileName) throws IOException {
|
|
|
|
443
|
+ String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
|
|
|
|
444
|
+
|
|
|
|
445
|
+ response.setContentType("application/vnd.ms-excel");
|
|
|
|
446
|
+ response.setCharacterEncoding("UTF-8");
|
|
|
|
447
|
+ response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName);
|
|
|
|
448
|
+ response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
|
|
|
|
449
|
+ }
|
|
|
|
450
|
+
|
|
|
|
451
|
+ public static void copyRow(Workbook workbook, Sheet sheet,
|
|
|
|
452
|
+ int sourceRowIndex, int targetRowIndex) {
|
|
|
|
453
|
+
|
|
|
|
454
|
+ // 移动目标行及之后的行
|
|
|
|
455
|
+ if (targetRowIndex <= sheet.getLastRowNum()) {
|
|
|
|
456
|
+ sheet.shiftRows(targetRowIndex, sheet.getLastRowNum(), 1, true, false);
|
|
|
|
457
|
+ }
|
|
|
|
458
|
+
|
|
|
|
459
|
+ // 复制行内容
|
|
|
|
460
|
+ Row sourceRow = sheet.getRow(sourceRowIndex);
|
|
|
|
461
|
+ Row newRow = sheet.createRow(targetRowIndex);
|
|
|
|
462
|
+ newRow.setHeight(sourceRow.getHeight());
|
|
|
|
463
|
+
|
|
|
|
464
|
+ // 复制单元格
|
|
|
|
465
|
+ for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
|
|
|
|
466
|
+ Cell oldCell = sourceRow.getCell(i);
|
|
|
|
467
|
+ Cell newCell = newRow.createCell(i);
|
|
|
|
468
|
+
|
|
|
|
469
|
+ if (oldCell != null) {
|
|
|
|
470
|
+ copyCell(workbook, oldCell, newCell);
|
|
|
|
471
|
+ }
|
|
|
|
472
|
+ }
|
|
|
|
473
|
+ // === 关键:清除源行上的所有合并区域(防止被“复制”)===
|
|
|
|
474
|
+ List<Integer> regionsToRemove = new ArrayList<>();
|
|
|
|
475
|
+ for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
|
|
|
|
476
|
+ CellRangeAddress region = sheet.getMergedRegion(j);
|
|
|
|
477
|
+ if (region.getFirstRow() == sourceRowIndex || region.getLastRow() == sourceRowIndex) {
|
|
|
|
478
|
+ regionsToRemove.add(j);
|
|
|
|
479
|
+ }
|
|
|
|
480
|
+ }
|
|
|
|
481
|
+
|
|
|
|
482
|
+ // 从后往前删除,避免索引偏移
|
|
|
|
483
|
+ Collections.reverse(regionsToRemove);
|
|
|
|
484
|
+ for (int idx : regionsToRemove) {
|
|
|
|
485
|
+ sheet.removeMergedRegion(idx);
|
|
|
|
486
|
+ }
|
|
|
|
487
|
+
|
|
|
|
488
|
+ }
|
|
|
|
489
|
+
|
|
|
|
490
|
+
|
|
|
|
491
|
+ /**
|
|
|
|
492
|
+ * 复制单元格内容和样式
|
|
|
|
493
|
+ */
|
|
|
|
494
|
+ private static void copyCell(Workbook workbook, Cell oldCell, Cell newCell) {
|
|
|
|
495
|
+ if (oldCell.getCellStyle() != null) {
|
|
|
|
496
|
+ newCell.setCellStyle(oldCell.getCellStyle());
|
|
|
|
497
|
+ }
|
|
|
|
498
|
+
|
|
|
|
499
|
+ switch (oldCell.getCellTypeEnum()) {
|
|
|
|
500
|
+ case STRING:
|
|
|
|
501
|
+ newCell.setCellValue(oldCell.getStringCellValue());
|
|
|
|
502
|
+ break;
|
|
|
|
503
|
+ case NUMERIC:
|
|
|
|
504
|
+ newCell.setCellValue(oldCell.getNumericCellValue());
|
|
|
|
505
|
+ break;
|
|
|
|
506
|
+ case BOOLEAN:
|
|
|
|
507
|
+ newCell.setCellValue(oldCell.getBooleanCellValue());
|
|
|
|
508
|
+ break;
|
|
|
|
509
|
+ case FORMULA:
|
|
|
|
510
|
+ newCell.setCellFormula(oldCell.getCellFormula());
|
|
|
|
511
|
+ break;
|
|
|
|
512
|
+ default:
|
|
|
|
513
|
+ newCell.setCellValue(oldCell.getStringCellValue());
|
|
|
|
514
|
+ break;
|
|
|
|
515
|
+ }
|
|
|
|
516
|
+ }
|
|
|
|
517
|
+
|
|
150
|
} |
518
|
} |