Commit 4515351c authored by suhuiguang's avatar suhuiguang

1.电梯导出多线程

parent 832141da
......@@ -22,5 +22,10 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
</dependencies>
</project>
package com.yeejoin.amos.boot.module.common.api.excel;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import com.google.common.collect.Lists;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.web.multipart.MultipartFile;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.google.common.collect.Lists;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
public class ExcelUtil {
......@@ -86,7 +89,7 @@ public class ExcelUtil {
*/
public static void createDutyTemplate(HttpServletResponse response, String fileName, String sheetName,
List<? extends Object> data, Class<?> model, List<String> dayByMonth, String[] dutyNameList,
DataSources dataDictionaryMapper, boolean flag, String typeFlag,boolean isTemplete) {
DataSources dataDictionaryMapper, boolean flag, String typeFlag, boolean isTemplete) {
HorizontalCellStyleStrategy horizontalCellStyleStrategy = setMyCellStyle();
try {
......@@ -129,23 +132,23 @@ public class ExcelUtil {
// String s = new String(fileName.getBytes(), "UTF-8");
// response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(s, "UTF-8"));
ExcelWriterSheetBuilder excelWriterSheetBuilder =EasyExcel
ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel
.write(getOutputStream(fileName, response, ExcelTypeEnum.XLSX))
.head(dutyCarTitleList)
.excelType(ExcelTypeEnum.XLSX).sheet(sheetName);
if ("WXXFZB".equals(typeFlag) && isTemplete) {
List<Map<Integer, String[]>> fireStationExplicitListConstraintMap = new ArrayList<Map<Integer, String[]>>();
List<List<Object>> resultList =new ArrayList<List<Object>>();
List<List<Object>> resultList = new ArrayList<List<Object>>();
data.stream().forEach(i -> {
Map<Integer, String[]> map = new HashMap<>();
List<Object> detail = (List<Object>) i;
// 微型消防站中的对应单位微型消防站下拉列表数据的集合
List<String> fireStationDetailList = (List<String>) detail.get(detail.size()-1);
List<String> fireStationDetailList = (List<String>) detail.get(detail.size() - 1);
String[] strings = new String[fireStationDetailList.size()];
map.put(4, fireStationDetailList.toArray(strings));
map.putAll(explicitListConstraintMap);
fireStationExplicitListConstraintMap.add(map);
detail.remove(detail.size()-1);
detail.remove(detail.size() - 1);
resultList.add(detail);
});
excelWriterSheetBuilder.registerWriteHandler(
......@@ -153,21 +156,20 @@ public class ExcelUtil {
.registerWriteHandler(new TemplateCellWriteHandler())
.registerWriteHandler(horizontalCellStyleStrategy);
excelWriterSheetBuilder.doWrite(resultList);
}
else if("JJZB".equals(typeFlag) && isTemplete){
} else if ("JJZB".equals(typeFlag) && isTemplete) {
List<Map<Integer, String[]>> fireStationExplicitListConstraintMap = new ArrayList<Map<Integer, String[]>>();
List<List<Object>> resultList =new ArrayList<List<Object>>();
List<List<Object>> resultList = new ArrayList<List<Object>>();
data.stream().forEach(i -> {
Map<Integer, String[]> map = new HashMap<>();
List<Object> detail = (List<Object>) i;
// 微型消防站中的对应单位微型消防站下拉列表数据的集合
List<String> fireStationDetailList = (List<String>) detail.get(detail.size()-1);
List<String> fireStationDetailList = (List<String>) detail.get(detail.size() - 1);
String[] strings = new String[fireStationDetailList.size()];
List<String> postTypeNameDetailList = (List<String>) detail.get(detail.size()-2);
List<String> postTypeNameDetailList = (List<String>) detail.get(detail.size() - 2);
String[] postTypeNamestrings = new String[postTypeNameDetailList.size()];
List<String> userNameDetailList = (List<String>) detail.get(detail.size()-3);
List<String> userNameDetailList = (List<String>) detail.get(detail.size() - 3);
String[] userNamestrings = new String[userNameDetailList.size()];
List<String> companyNameList = (List<String>) detail.get(detail.size()-4);
List<String> companyNameList = (List<String>) detail.get(detail.size() - 4);
String[] companyNameLists = new String[companyNameList.size()];
map.put(4, fireStationDetailList.toArray(strings));
map.put(3, postTypeNameDetailList.toArray(postTypeNamestrings));
......@@ -175,10 +177,10 @@ public class ExcelUtil {
map.put(1, companyNameList.toArray(companyNameLists));
map.putAll(explicitListConstraintMap);
fireStationExplicitListConstraintMap.add(map);
detail.remove(detail.size()-1);
detail.remove(detail.size()-1);
detail.remove(detail.size()-1);
detail.remove(detail.size()-1);
detail.remove(detail.size() - 1);
detail.remove(detail.size() - 1);
detail.remove(detail.size() - 1);
detail.remove(detail.size() - 1);
resultList.add(detail);
});
excelWriterSheetBuilder
......@@ -187,7 +189,7 @@ public class ExcelUtil {
.registerWriteHandler(new TemplateCellWriteHandler())
.registerWriteHandler(horizontalCellStyleStrategy);
excelWriterSheetBuilder.doWrite(resultList);
}else {
} else {
excelWriterSheetBuilder = excelWriterSheetBuilder
.registerWriteHandler(
new TemplateCellWriteHandlerDate(explicitListConstraintMap))
......@@ -390,7 +392,6 @@ public class ExcelUtil {
}
/**
* 生成excel模板
*
......@@ -408,12 +409,12 @@ public class ExcelUtil {
List<List<Object>> listData = Lists.newArrayList();
for (Object t : data) {
List<Object> rowLine = new ArrayList<>();
for(String head: headstr) {
for (String head : headstr) {
List<Object> row = new ArrayList<>();
String getMethodName = "get" + head.substring(0,1).toUpperCase() + head.substring(1);
String getMethodName = "get" + head.substring(0, 1).toUpperCase() + head.substring(1);
Class clazz = t.getClass();
Method getMethod;
getMethod = clazz.getMethod(getMethodName, new Class[]{} );
getMethod = clazz.getMethod(getMethodName, new Class[]{});
Object value = getMethod.invoke(t, new Object[]{});
rowLine.add(value);
}
......@@ -421,9 +422,9 @@ public class ExcelUtil {
}
ExcelTypeEnum typeEnum = null;
if("1039".equals(fileType)) {
if ("1039".equals(fileType)) {
typeEnum = ExcelTypeEnum.XLS;
} else if("1040".equals(fileType)) {
} else if ("1040".equals(fileType)) {
typeEnum = ExcelTypeEnum.XLSX;
}
......@@ -440,4 +441,97 @@ public class ExcelUtil {
}
private static ByteArrayOutputStream exportData2(List<?> subList, List<List<String>> heads) {
ByteArrayOutputStream singleOutputStream = new ByteArrayOutputStream();
ExcelWriter excelWriter = EasyExcel.write(singleOutputStream).build();
WriteSheet writeSheet = EasyExcel.writerSheet("电梯信息").build();
writeSheet.setHead(heads);
excelWriter.write(subList, writeSheet);
excelWriter.finish();
return singleOutputStream;
}
public static void exportWithMplThread2(HttpServletResponse response,
String fileName,
List<?> data,
List<List<String>> heads,
String fileType,
Executor executorService,
int excelNumber) {
int dataSize = data.size();
int threadDataSize = dataSize / excelNumber;
int lastDataSize = dataSize % excelNumber;
List<CompletableFuture<ByteArrayOutputStream>> futures = new ArrayList<>();
for (int i = 0; i < excelNumber; i++) {
int start = i * threadDataSize;
int end = start + threadDataSize;
if (i == excelNumber - 1) {
end = start + threadDataSize + lastDataSize;
}
List<?> subList = data.subList(start, end);
CompletableFuture<ByteArrayOutputStream> future = CompletableFuture.supplyAsync(() -> exportData2(subList, heads), executorService)
.exceptionally(ex -> {
ex.printStackTrace();
return null; // Handle exception and return a default result or null
});
futures.add(future);
}
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
CompletableFuture<List<ByteArrayOutputStream>> combinedFuture = allOfFuture
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
List<ByteArrayOutputStream> results = combinedFuture.join();
try {
response.setContentType("application/zip");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setHeader("Content-Disposition",
"attachment; filename=" + URLEncoder.encode(fileName+ ".zip", StandardCharsets.UTF_8.name()));
List<File> tempList = new ArrayList<>();
ExcelTypeEnum typeEnum;
if ("1039".equals(fileType)) {
typeEnum = ExcelTypeEnum.XLS;
} else {
typeEnum = ExcelTypeEnum.XLSX;
}
results.forEach(b -> {
try {
File tempFile = File.createTempFile(fileName, typeEnum.getValue());
Files.write(tempFile.toPath(), b.toByteArray(), StandardOpenOption.CREATE);
tempList.add(tempFile);
} catch (IOException e) {
e.printStackTrace();
}
});
File[] tempFiles = tempList.toArray(new File[0]);
File zipFile = new File(fileName + ".zip");
ZipUtil.zip(zipFile, false, tempFiles);
Arrays.stream(tempFiles).forEach(File::delete);
try (OutputStream outputStream = response.getOutputStream();
FileInputStream zipFileStream = new FileInputStream(zipFile);
BufferedInputStream inputStream = new BufferedInputStream(zipFileStream)) {
byte[] buffer = new byte[8192];
int count;
while ((count = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
zipFile.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
......@@ -11,4 +11,9 @@ public interface BizCommonConstant {
* 所有平台企业数据redisKey
*/
String COMPANY_TREE_REDIS_KEY = "REGULATOR_UNIT_TREE";
/**
* 电梯数据key
*/
String OLD_ELEVATOR_REDIS_KEY = "OLD_ELEVATOR_REDIS_KEY";
}
......@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.common.api.excel.ExcelUtil;
import com.yeejoin.amos.boot.module.elevator.api.common.BizCommonConstant;
import com.yeejoin.amos.boot.module.elevator.api.dto.ElevatorDto;
import com.yeejoin.amos.boot.module.elevator.api.dto.ExportDto;
import com.yeejoin.amos.boot.module.elevator.api.entity.TemplateExport;
......@@ -15,7 +16,10 @@ import com.yeejoin.amos.boot.module.elevator.api.service.IRescueStationService;
import com.yeejoin.amos.boot.module.elevator.api.service.IUseUnitService;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.ElevatorServiceImpl;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.VoiceRecordFileServiceImpl;
import com.yeejoin.amos.boot.module.elevator.biz.utils.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.RequestMapping;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.Api;
......@@ -25,6 +29,7 @@ import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.TemplateExportServiceImpl;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
......@@ -69,6 +74,12 @@ public class TemplateExportController extends BaseController {
@Autowired
VoiceRecordFileServiceImpl voiceRecordFileServiceImpl;
@Autowired
RedisUtil redisUtil;
@Autowired
Executor customExecutor;
/**
* 新增模板表
*
......@@ -177,7 +188,7 @@ public class TemplateExportController extends BaseController {
@TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
@ApiOperation(httpMethod = "POST", value = "根据字段类型导出", notes = "根据字段类型导出")
@PostMapping("/exportByTypeParams")
public void exportByTypeParams(@RequestBody ExportDto exportDto, HttpServletResponse response) {
public void exportByTypeParams(@RequestBody ExportDto exportDto, HttpServletResponse response) throws Exception {
if (ValidationUtil.isEmpty(exportDto.getExportArray())
|| ValidationUtil.isEmpty(exportDto.getDataType())
|| ValidationUtil.isEmpty(exportDto.getFileName())
......@@ -206,9 +217,16 @@ public class TemplateExportController extends BaseController {
heads.add(tempList);
}
String fileName = exportDto.getFileName();
if("ELEVATOR".equals(exportDto.getExportType())) { // 查询电梯数据
// 查询电梯数据
if("ELEVATOR".equals(exportDto.getExportType())) {
if(redisUtil.hasKey(BizCommonConstant.OLD_ELEVATOR_REDIS_KEY)){
list = JSONObject.parseArray(redisUtil.get(BizCommonConstant.OLD_ELEVATOR_REDIS_KEY).toString(),ElevatorDto.class);
} else {
list = elevatorServiceImpl.selectExportData(exportDto.getExportId());
sheetName = "电梯信息";
redisUtil.set(BizCommonConstant.OLD_ELEVATOR_REDIS_KEY,JSONObject.toJSONString(list));
}
ExcelUtil.exportWithMplThread2(response,fileName,list,heads,exportDto.getFileType(),customExecutor,10);
return;
} else if("MAINTENANCE_COMPANY".equals(exportDto.getExportType())) { // 查询维保单位数据
list = iMaintenanceUnitService.selectExportData(exportDto.getExportId());
sheetName = "维保单位";
......@@ -222,7 +240,6 @@ public class TemplateExportController extends BaseController {
sheetName = "通话录音";
list = voiceRecordFileServiceImpl.selectExportData(exportDto.getExportId());
}
ExcelUtil.createTemplateWithHeaders(response, fileName, sheetName, list, heads, headstr, exportDto.getFileType());
ExcelUtil.createTemplateWithHeaders(response, fileName, sheetName, list,heads,headstr,exportDto.getFileType());
}
}
package com.yeejoin.amos.boot.module.elevator.biz.core.threadpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Executor;
/**
* 线程池
*/
@Configuration
public class AmosThreadPool {
/**
* 日志记录器
*/
private static final Logger log = LoggerFactory.getLogger(AmosThreadPool.class);
/**
* 单例
*/
private static AmosThreadPool instance;
/**
* 执行服务
*/
private static ExecutorService executorService;
/**
* 获取单例
*
* @return
*/
public static AmosThreadPool getInstance() {
if (instance == null) {
synchronized (AmosThreadPool.class) {
if (instance == null) {
instance = new AmosThreadPool();
}
}
}
return instance;
}
static {
executorService = Executors
.newFixedThreadPool(20);
}
/**
* 执行线程
*
* @param task
*/
public void execute(Runnable task) {
executorService.execute(task);
@Bean
public Executor customExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 初始核心线程数
executor.setCorePoolSize(10);
// 最大线程数
executor.setMaxPoolSize(20);
// 任务队列容量
executor.setQueueCapacity(50);
// 线程名前缀
executor.setThreadNamePrefix("CustomExecutor-");
executor.initialize();
return executor;
}
}
package com.yeejoin.amos.boot.module.elevator.biz.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.module.elevator.api.common.BizCommonConstant;
import com.yeejoin.amos.boot.module.elevator.api.dto.ElevatorDto;
import com.yeejoin.amos.boot.module.elevator.biz.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class ElevatorAppRunner implements ApplicationRunner {
@Autowired
RedisUtil redisUtil;
@Autowired
ElevatorServiceImpl elevatorServiceImpl;
@Override
public void run(ApplicationArguments args) {
// 缓存电梯数据
List<ElevatorDto> list = elevatorServiceImpl.selectExportData(null);
redisUtil.set(BizCommonConstant.OLD_ELEVATOR_REDIS_KEY, JSONObject.toJSONString(list));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment