package cn.cslg.pas.service.business; import cn.cslg.pas.common.dto.ExportTaskDTO; import cn.cslg.pas.common.dto.PatentColumnDTO; import cn.cslg.pas.common.dto.PatentExport.PatentExportVO; import cn.cslg.pas.common.dto.es.EsQueryPatentFieldsDTO; import cn.cslg.pas.common.dto.es.InnerFields; import cn.cslg.pas.common.model.cronModel.Records; import cn.cslg.pas.common.model.request.QueryRequest; import cn.cslg.pas.common.model.request.StringRequest; import cn.cslg.pas.common.utils.*; import cn.cslg.pas.common.vo.ConfigVOS.PatentConfigVO; import cn.cslg.pas.common.vo.FieldValueVO; import cn.cslg.pas.common.vo.ImportTaskAMVO; import cn.cslg.pas.common.vo.PatentPageMessageVO; import cn.cslg.pas.common.vo.WebSocketMessageVO; import cn.cslg.pas.common.vo.business.PatentNoVO; import cn.cslg.pas.common.vo.es.EsCustomFieldBatchVO; import cn.cslg.pas.common.vo.es.EsPatentCommonVO; import cn.cslg.pas.common.vo.es.EsPatentFieldsVO; import cn.cslg.pas.common.vo.es.InnerPatentFieldsVO; import cn.cslg.pas.domain.business.ImportTask; import cn.cslg.pas.domain.es.Patent; import cn.cslg.pas.exception.ExceptionEnum; import cn.cslg.pas.exception.XiaoShiException; import cn.cslg.pas.factorys.PatentExportFactory.GetValueImp; import cn.cslg.pas.factorys.PatentExportFactory.PatentExportFactory; import cn.cslg.pas.service.business.es.EsCustomFieldService; import cn.cslg.pas.service.business.es.EsPatentService; import cn.cslg.pas.service.business.es.EsService; import cn.cslg.pas.service.common.MessageService; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.aggregations.Aggregate; import co.elastic.clients.elasticsearch.core.SearchRequest; import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.Hit; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import lombok.extern.slf4j.Slf4j; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.*; import java.util.stream.Collectors; /** * Excel导出专利 * * @Author xiexiang * @Date 2024/1/3 */ @Slf4j @Service public class PatentExportService { @Autowired private PDFExportFirstPageService pdfExportFirstPageService; @Autowired private EsPatentService patentService; @Autowired private MessageService messageService; @Autowired private PatentExportFactory patentExportFactory; @Autowired private ParseByteToFileUtils parseByteToFileUtils; @Autowired private ImportTaskService importTaskService; @Autowired private EsCustomFieldService esCustomFieldService; @Autowired private EsService esService; @Autowired private ElasticsearchClient client; @Autowired private EsPatentService esPatentService; /** * 导出专利 * * @param exportTask * @return * @throws IOException */ @Async public void exportPatent(ExportTaskDTO exportTask) throws IOException { EsCustomFieldBatchVO EsVO = exportTask.getEsVO(); try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { //字段是否被选择 String esSelected = JsonUtils.objectToJson(EsVO.getSelected()); //专利字段的集合 List selected = Optional.ofNullable(JsonUtils.jsonToList(esSelected, PatentExportVO.class)) .orElse(new ArrayList<>()); if (selected.isEmpty()) { throw new IllegalArgumentException("没有选择要导出的字段数据"); } //key的集合(标头:例如patentNo) //过滤出被选择的字段 List patentExportVOS = selected.stream() .filter(PatentExportVO::getSelected) .collect(Collectors.toList()); List types = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"); List innerFieldsList = new ArrayList<>(); for (PatentExportVO patentExportVO : patentExportVOS) { if (types.contains(patentExportVO.getType())) { InnerFields innerFields = new InnerFields(); innerFields.setFieldId(patentExportVO.getValue()); innerFields.setFieldType(Integer.parseInt(patentExportVO.getType())); innerFieldsList.add(innerFields); } } //name的集合 List headers = selected.stream().filter(PatentExportVO::getSelected).map(PatentExportVO::getName).distinct().collect(Collectors.toList()); long startTime = System.currentTimeMillis(); //新建工作簿 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); //新建sheet页 HSSFSheet sheet = hssfWorkbook.createSheet(); sheet.setDefaultColumnWidth(30); //新建标头行 HSSFRow headerRow = sheet.createRow(0); headerRow.setHeight((short) 500); //新建标头行格式 HSSFCellStyle headerCellStyle = hssfWorkbook.createCellStyle(); //新建普通行格式 HSSFCellStyle commonCellStyle = hssfWorkbook.createCellStyle(); //遍历设置标头 for (int i = 0; i < headers.size(); i++) { HSSFCell cell = headerRow.createCell(i); ExcelUtils.setExcelCellStyle(headerCellStyle); headerCellStyle.setAlignment(HorizontalAlignment.CENTER); headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); headerCellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.SKY_BLUE.getIndex()); headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); headerCellStyle.setWrapText(true); cell.setCellStyle(headerCellStyle); cell.setCellValue(headers.get(i)); } //根据projectId查询专利信息 List patentNos = pdfExportFirstPageService.getPatentNo(EsVO); if (patentNos.isEmpty()) { throw new XiaoShiException("未获取到专利信息"); } Integer total = patentNos.size(); Integer defaultNum = 0; for (int i = 0; i < patentNos.size(); i++) { String patentNo = patentNos.get(i); Map map = new LinkedHashMap<>(); PatentNoVO patentNoVO = new PatentNoVO(); patentNoVO.setPatentNo(patentNo); patentNoVO.setProjectId(exportTask.getProjectId()); PatentColumnDTO patent = patentService.selectPatentDetail(patentNoVO); if (patent == null) { defaultNum++; continue; } EsQueryPatentFieldsDTO esQueryPatentFieldsDTO = new EsQueryPatentFieldsDTO(); esQueryPatentFieldsDTO.setProjectId(exportTask.getProjectId()); esQueryPatentFieldsDTO.setTaskId(EsVO.getTaskId()); esQueryPatentFieldsDTO.setPatentNos(patentNos); esQueryPatentFieldsDTO.setInnerFields(innerFieldsList); List list = esCustomFieldService.getPatentFields(esQueryPatentFieldsDTO); for (int j = 0; j < patentExportVOS.size(); j++) { String column = patentExportVOS.get(j).getValue(); String name = patentExportVOS.get(j).getName(); String type = patentExportVOS.get(j).getType(); if (types.contains(type)) { EsPatentFieldsVO esPatentFieldsVO = list.stream() .filter(item -> item.getPatentNo().equals(patentNo)) .findFirst() .orElse(null); if (esPatentFieldsVO != null) { List innerClassFields = esPatentFieldsVO.getInnerClassFields(); if (!innerClassFields.isEmpty()) { InnerPatentFieldsVO innerPatentFieldsVO = innerClassFields.stream() .filter(item -> item.getField().equals(column) && item.getFieldType().equals(Integer.parseInt(type))) .findFirst() .orElse(null); if (innerPatentFieldsVO != null) { List fieldValueVOS = innerPatentFieldsVO.getFieldValueVOS(); if (!fieldValueVOS.isEmpty()) { StringBuffer sb = new StringBuffer(); for (FieldValueVO fieldValueVO : fieldValueVOS) { String valueStr = fieldValueVO.getValue(); sb.append(valueStr); } map.put(name, sb.toString()); } } } } } else { // 使用反射获取属性值 Object value = GenerateObjectUtil.getPropertyValue(patent, column); if (value != null) { String json = CommonService.readJsonFile("patent.json"); List patentConfigVOS = JSON.parseArray(json, PatentConfigVO.class); PatentConfigVO patentConfigVO = patentConfigVOS.stream().filter(item -> item.getValue().equals(column)).findFirst().orElse(null); String exportClass = patentConfigVO.getExportClass(); GetValueImp getValueImp = patentExportFactory.getClass(exportClass); if (getValueImp != null) { String reValue = getValueImp.getValue(value); map.put(name, reValue); } } } } //新建一普通行 HSSFRow row = sheet.createRow(i + 1); row.setHeight((short) 800); for (String key : map.keySet()) { int index = headers.indexOf(key); if (index != -1) { HSSFCell cell = row.createCell(index); ExcelUtils.setExcelCellStyle(commonCellStyle); commonCellStyle.setVerticalAlignment(VerticalAlignment.TOP); commonCellStyle.setWrapText(true); cell.setCellStyle(commonCellStyle); if (StringUtils.isNotNull(map.get(key))) { cell.setCellValue(String.valueOf(map.get(key))); } } } WebSocketMessageVO webSocketMessageVO = new WebSocketMessageVO(); webSocketMessageVO.setProjectId(EsVO.getProjectId()); webSocketMessageVO.setCreateId(exportTask.getCreateId()); webSocketMessageVO.setCode(602); webSocketMessageVO.setAllNum(total); webSocketMessageVO.setCurrentNum(i + 1); webSocketMessageVO.setTaskId(exportTask.getTaskId()); webSocketMessageVO.setState(1); messageService.sendPatentExportMessage(webSocketMessageVO); } hssfWorkbook.write(out); log.info("导出excel结束,总数据量={},耗时={}ms", total, System.currentTimeMillis() - startTime); WebSocketMessageVO webSocketMessageVO = new WebSocketMessageVO(); webSocketMessageVO.setProjectId(EsVO.getProjectId()); webSocketMessageVO.setCreateId(exportTask.getCreateId()); webSocketMessageVO.setCode(603); webSocketMessageVO.setAllNum(total); webSocketMessageVO.setCurrentNum(total); webSocketMessageVO.setTaskId(exportTask.getTaskId()); webSocketMessageVO.setState(2); messageService.sendPatentExportMessage(webSocketMessageVO); String fileGuid = ""; if (out.toByteArray() != null && out.toByteArray().length != 0) { fileGuid = parseByteToFileUtils.uploadFile(out.toByteArray(), 1); } exportTask.setFileGuid(fileGuid); exportTask.setAllNum(total); exportTask.setDefaultNum(defaultNum); exportTask.setDoneNum(total - defaultNum); exportTask.setState(2); Integer taskId = importTaskService.updateExportTask(exportTask); if (taskId == null) { throw new XiaoShiException("导出记录失败"); } } catch (FileNotFoundException e) { throw new FileNotFoundException(); } catch (Exception e) { } } public HSSFWorkbook getExportHssWorkbook(List headers) { //新建工作簿 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); //新建sheet页 HSSFSheet sheet = hssfWorkbook.createSheet(); sheet.setDefaultColumnWidth(30); //新建标头行 HSSFRow headerRow = sheet.createRow(0); headerRow.setHeight((short) 500); //新建标头行格式 HSSFCellStyle headerCellStyle = hssfWorkbook.createCellStyle(); //新建普通行格式 HSSFCellStyle commonCellStyle = hssfWorkbook.createCellStyle(); //遍历设置标头 for (int i = 0; i < headers.size(); i++) { HSSFCell cell = headerRow.createCell(i); ExcelUtils.setExcelCellStyle(headerCellStyle); headerCellStyle.setAlignment(HorizontalAlignment.CENTER); headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); headerCellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.SKY_BLUE.getIndex()); headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); headerCellStyle.setWrapText(true); cell.setCellStyle(headerCellStyle); cell.setCellValue(headers.get(i)); } return hssfWorkbook; } public Integer updateTaskStateToDoing(Integer taskId,Long total) { ImportTask importTask = importTaskService.getById(taskId); if (importTask == null) { throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "导入任务不存在"); } else { importTask.setState(1); importTask.setAllNum(total.intValue()); importTask.updateById(); } return importTask.getId(); } public Records queryPatents(EsPatentCommonVO esPatentCommonVO) throws Exception { List patentList = new ArrayList<>(); Records records = new Records(); SearchRequest.Builder builder = esService.getCommonPatent(esPatentCommonVO); SearchResponse response = client.search(builder.build(), Patent.class); List> hits = response.hits().hits(); Long total = 0L; if (org.apache.commons.lang3.StringUtils.isNotEmpty(esPatentCommonVO.getEsField())) { Aggregate aggregate = response.aggregations().get("count"); total = aggregate.cardinality().value(); } else { total = response.hits().total().value(); } records.setTotal(total); for (Hit hit : hits) { patentList.add(hit.source()); } records.setData(patentList); return records; } @Async public void exportPatent2(ExportTaskDTO exportTask, ImportTaskAMVO importTaskAMVO) throws Exception { EsCustomFieldBatchVO esVO = exportTask.getEsVO(); List selectedFields = esVO.getSelected(); selectedFields=selectedFields.stream().filter(PatentExportVO::getSelected).collect(Collectors.toList()); Integer taskId = exportTask.getTaskId(); Integer projectId = exportTask.getProjectId(); String createId = exportTask.getCreateId(); if (taskId == null) { throw new XiaoShiException(ExceptionEnum.BUSINESS_CHECK, "任务id不可为空"); } if (CollectionUtils.isEmpty(selectedFields)) { throw new IllegalArgumentException("没有选择要导出的字段数据"); } List headers = selectedFields.stream().filter(PatentExportVO::getSelected).map(PatentExportVO::getName).distinct().collect(Collectors.toList()); List notInNos = esVO.getIsDelete(); List inNos = esVO.getIsAdd(); List types = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"); List innerFieldsList = new ArrayList<>(); for (PatentExportVO patentExportVO : selectedFields) { if (types.contains(patentExportVO.getType())) { InnerFields innerFields = new InnerFields(); innerFields.setFieldId(patentExportVO.getValue()); innerFields.setFieldType(Integer.parseInt(patentExportVO.getType())); innerFieldsList.add(innerFields); } } HSSFWorkbook hssfWorkbook = this.getExportHssWorkbook(headers); HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(0); StringRequest queryRequest = new StringRequest(); BeanUtils.copyProperties(esVO, queryRequest); EsQueryPatentFieldsDTO esQueryPatentFieldsDTO = new EsQueryPatentFieldsDTO(); esQueryPatentFieldsDTO.setProjectId(exportTask.getProjectId()); esQueryPatentFieldsDTO.setTaskId(esVO.getTaskId()); esQueryPatentFieldsDTO.setInnerFields(innerFieldsList); HSSFCellStyle commonCellStyle = this.getComCellStyle(hssfWorkbook); Long startNum = null; Long endNum = null; if (esVO.getStartNumber() != null) { startNum =0l+esVO.getStartNumber(); } if (esVO.getEndNumber() != null) { endNum = 0l+esVO.getEndNumber(); } if (startNum == null) { startNum = 1l; } Long toNum = startNum+9l; if (endNum != null && endNum < toNum) { toNum = endNum; } Integer index = 0; String json = CommonService.readJsonFile("patent.json"); List patentConfigVOS = JSON.parseArray(json, PatentConfigVO.class); EsPatentCommonVO esPatentCommonVO = esService.tranPatentRequestToComVO(queryRequest); esPatentCommonVO.setStartNum(startNum); esPatentCommonVO.setEndNum(toNum); Records firstRecords = this.queryPatents(esPatentCommonVO); Long total = 0l; if (startNum != null && endNum != null) { total = (endNum - startNum) + 1; if (notInNos != null) { total = total - notInNos.size(); } if (inNos != null) { total += inNos.size(); } } else if (inNos != null) { total = 0L + inNos.size(); } else { firstRecords.getTotal(); } this.updateTaskStateToDoing(taskId,total); List firstPatentList = (List) firstRecords.getData(); List firstPatentNos = firstPatentList.stream().map(Patent::getPatentNo).collect(Collectors.toList()); //查询自定义字段 esQueryPatentFieldsDTO.setPatentNos(firstPatentNos); List firstEsPatentFieldsVOS = esCustomFieldService.getPatentFields(esQueryPatentFieldsDTO); for (int i = 0; i < firstPatentList.size(); i++) { Patent patent = firstPatentList.get(i); if (notInNos != null && notInNos.contains(patent.getPatentNo())) { continue; } this.loadPatentCell(patent, selectedFields, patentConfigVOS, firstEsPatentFieldsVOS, hssfSheet, commonCellStyle, index); index++; importTaskAMVO.setDoneNum(index); this.sendWebSocketMessage(projectId, taskId, createId, total.intValue(), index, false); } if (endNum == null) { endNum = total; } while (toNum < endNum) { startNum = toNum + 1; toNum = toNum + 10L; if (toNum > endNum) { toNum = endNum; } esPatentCommonVO.setStartNum(startNum); esPatentCommonVO.setEndNum(toNum); Records records = this.queryPatents(esPatentCommonVO); List patentList = (List) records.getData(); List patentNos = patentList.stream().map(Patent::getPatentNo).collect(Collectors.toList()); ; //查询自定义字段 esQueryPatentFieldsDTO.setPatentNos(patentNos); List esPatentFieldsVOS = esCustomFieldService.getPatentFields(esQueryPatentFieldsDTO); for (int i = 0; i < patentList.size(); i++) { Patent patent = patentList.get(i); if (notInNos != null && notInNos.contains(patent.getPatentNo())) { continue; } this.loadPatentCell(patent, selectedFields, patentConfigVOS, esPatentFieldsVOS, hssfSheet, commonCellStyle, index); index++; importTaskAMVO.setDoneNum(index); this.sendWebSocketMessage(projectId, taskId, createId, total.intValue(), index, true); } } esQueryPatentFieldsDTO.setPatentNos(inNos); List esPatentFieldsVOS = esCustomFieldService.getPatentFields(esQueryPatentFieldsDTO); List patentList = esPatentService.getPatentsByNo(inNos, true, null, null); for (int i = 0; i < patentList.size(); i++) { Patent patent = patentList.get(i); if (notInNos != null && notInNos.contains(patent.getPatentNo())) { continue; } this.loadPatentCell(patent, selectedFields, patentConfigVOS, esPatentFieldsVOS, hssfSheet, commonCellStyle, index); index++; importTaskAMVO.setDoneNum(index); importTaskAMVO.setState(2); this.sendWebSocketMessage(projectId, taskId, createId, total.intValue(), index, false); } try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { hssfWorkbook.write(out); String fileGuid = ""; if (out.toByteArray() != null && out.toByteArray().length != 0) { fileGuid = parseByteToFileUtils.uploadFile(out.toByteArray(), 1); } exportTask.setFileGuid(fileGuid); exportTask.setState(2); Integer reTaskId = importTaskService.updateExportTask(exportTask); if (reTaskId == null) { throw new XiaoShiException("导出记录失败"); } } catch (FileNotFoundException e) { e.printStackTrace(); throw new FileNotFoundException(); } catch (Exception e) { e.printStackTrace(); } } public void sendWebSocketMessage(Integer projectId, Integer taskId, String createId, Integer total, Integer index, Boolean ifDone) { WebSocketMessageVO webSocketMessageVO = new WebSocketMessageVO(); webSocketMessageVO.setProjectId(projectId); webSocketMessageVO.setCreateId(createId); if (ifDone) { webSocketMessageVO.setCode(603); } else { webSocketMessageVO.setCode(602); } webSocketMessageVO.setAllNum(total); webSocketMessageVO.setCurrentNum(index); webSocketMessageVO.setTaskId(taskId); if (ifDone) { webSocketMessageVO.setState(2); } else { webSocketMessageVO.setState(1); } messageService.sendPatentExportMessage(webSocketMessageVO); } public HSSFCellStyle getComCellStyle(HSSFWorkbook hssfWorkbook) { HSSFCellStyle commonCellStyle = hssfWorkbook.createCellStyle(); ExcelUtils.setExcelCellStyle(commonCellStyle); commonCellStyle.setVerticalAlignment(VerticalAlignment.TOP); commonCellStyle.setWrapText(true); return commonCellStyle; } public void loadPatentCell(Patent patent, List patentExportVOS, List patentConfigVOS, List esPatentFieldsVOs, HSSFSheet sheet, HSSFCellStyle commonCellStyle, Integer index) { HSSFRow row = sheet.createRow(index + 1); row.setHeight((short) 800); for (int j = 0; j < patentExportVOS.size(); j++) { String column = patentExportVOS.get(j).getValue(); String name = patentExportVOS.get(j).getName(); String type = patentExportVOS.get(j).getType(); List types = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"); if (types.contains(type)) { EsPatentFieldsVO esPatentFieldsVO = esPatentFieldsVOs.stream() .filter(item -> item.getPatentNo().equals(patent.getPatentNo())) .findFirst() .orElse(null); if (esPatentFieldsVO != null) { List innerClassFields = esPatentFieldsVO.getInnerClassFields(); if (!innerClassFields.isEmpty()) { InnerPatentFieldsVO innerPatentFieldsVO = innerClassFields.stream() .filter(item -> item.getField().equals(column) && item.getFieldType().equals(Integer.parseInt(type))) .findFirst() .orElse(null); if (innerPatentFieldsVO != null) { List fieldValueVOS = innerPatentFieldsVO.getFieldValueVOS(); if (!fieldValueVOS.isEmpty()) { StringBuffer sb = new StringBuffer(); for (FieldValueVO fieldValueVO : fieldValueVOS) { String valueStr = fieldValueVO.getValue(); sb.append(valueStr); } HSSFCell cell = row.createCell(j); ExcelUtils.setExcelCellStyle(commonCellStyle); commonCellStyle.setVerticalAlignment(VerticalAlignment.TOP); commonCellStyle.setWrapText(true); cell.setCellStyle(commonCellStyle); cell.setCellValue(sb.toString()); } } } } } else { // 使用反射获取属性值 Object value = GenerateObjectUtil.getPropertyValue(patent, column); if (value != null) { PatentConfigVO patentConfigVO = patentConfigVOS.stream().filter(item -> item.getValue().equals(column)).findFirst().orElse(null); String exportClass = patentConfigVO.getExportClass(); GetValueImp getValueImp = patentExportFactory.getClass(exportClass); if (getValueImp != null) { String reValue = getValueImp.getValue(value); HSSFCell cell = row.createCell(j); cell.setCellStyle(commonCellStyle); cell.setCellValue(reValue); } } } } } }