Java中使用EasyExcel写excel文件
1、公式
package com.web.report.handler;import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.csv.CsvCellStyle;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.util.List;@Slf4j
public class CustomCellWriteHandler implements CellWriteHandler {@Overridepublic void afterCellDispose(CellWriteHandlerContext context) {Cell cell = context.getCell();// 这里可以对cell进行任何操作int rowIndex = cell.getRowIndex();String cellValue = cell.getStringCellValue();if (cellValue.startsWith("$$") && cellValue.endsWith("$$")) {String statisType = cellValue.substring(2, cellValue.length() - 2);String columnTitle = convertToTitle(cell.getColumnIndex() + 1);switch (statisType) {case "min":cell.setCellFormula("min(" + columnTitle + (rowIndex + 5) + ":" + columnTitle + 1000000 + ")");break;case "max":cell.setCellFormula("max(" + columnTitle + (rowIndex + 4) + ":" + columnTitle + 1000000 + ")");break;
// case "testNum":
// cell.setCellFormula("COUNTA(A" + (rowIndex + 1 + 3) + ":A" + 1000000 + ")");
// break;
// case "median":
// cell.setCellFormula("MEDIAN(" + columnTitle + (rowIndex + 3) + ":" + columnTitle + 1000000 + ")");
// break;case "avg":cell.setCellFormula("IF(COUNT(" + columnTitle + (rowIndex + 3) + ":" + columnTitle + 1000000 + ")>0,AVERAGE(" + columnTitle + (rowIndex + 3) + ":" + columnTitle + 1000000 + "),0)");break;case "stddev":cell.setCellFormula("IF(COUNT(" + columnTitle + (rowIndex + 2) + ":" + columnTitle + 1000000 + ")>1,STDEV(" + columnTitle + (rowIndex + 2) + ":" + columnTitle + 1000000 + "),0)");break;}} else {try {Double value = Double.valueOf(cellValue);cell.setCellValue(value);} catch (Exception e) {}}}public String convertToTitle(int n) {StringBuilder sb = new StringBuilder();while(n > 0){n--; // 重点sb.append((char)(n % 26 + 'A'));n /= 26;}sb.reverse();return sb.toString();}}
2、合并
package com.web.report.handler;import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;public class CustomMergeStrategy extends AbstractMergeStrategy {private Integer columnLength;private Sheet sheet;public CustomMergeStrategy(Integer columnLength) {this.columnLength = columnLength;}// 合并成一个单元格private void mergeCommonColumn(Integer rowIndexStart, Integer rowIndexEnd,Integer columnIndexStart,Integer columnIndexEnd ) {CellRangeAddress cellRangeAddress = new CellRangeAddress(rowIndexStart, rowIndexEnd, columnIndexStart, columnIndexEnd);sheet.addMergedRegionUnsafe(cellRangeAddress);}@Overrideprotected void merge(Sheet sheet, Cell cell, Head head, Integer integer) {this.sheet = sheet;if (cell.getRowIndex() < 13) {this.mergeCommonColumn(cell.getRowIndex(),cell.getRowIndex(),1,this.columnLength-1);}}}
3、样式
package com.web.report.style;import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import org.apache.poi.ss.usermodel.*;public class StyleUtils {/*** 标题样式* @return*/public static WriteCellStyle getHeadStyle(){// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 背景颜色
// headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE1.getIndex());
// headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);// 字体
// WriteFont headWriteFont = new WriteFont();
// headWriteFont.setFontName("宋体");//设置字体名字
// headWriteFont.setFontHeightInPoints((short)14);//设置字体大小
// headWriteFont.setBold(true);//字体加粗
// headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;
//
// // 样式
// headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
// headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
// headWriteCellStyle.setBorderLeft(BorderStyle.THIN); //设置左边框;
// headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
// headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
// headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
// headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
// headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
//
// headWriteCellStyle.setWrapped(true); //设置自动换行;headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //设置垂直对齐的样式为居中对齐;headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适return headWriteCellStyle;}/*** 内容样式* @return*/public static WriteCellStyle getContentStyle(){// 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 背景绿色// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
// contentWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
// contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);// 设置字体
// WriteFont contentWriteFont = new WriteFont();
// contentWriteFont.setFontHeightInPoints((short) 12);//设置字体大小
// contentWriteFont.setFontName("宋体"); //设置字体名字
// contentWriteCellStyle.setWriteFont(contentWriteFont);//在样式用应用设置的字体;
//
// //设置样式;
// contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
// contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
// contentWriteCellStyle.setBorderLeft(BorderStyle.THIN); //设置左边框;
// contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
// contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
// contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
// contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
// contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中contentWriteCellStyle.setWrapped(true); //设置自动换行;// contentWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适return contentWriteCellStyle;}}
4、 注解
package com.web.report.annotation;import com.web.report.enums.HeaderLabelTypeEnum;
import com.web.report.enums.HeaderTypeEnum;import java.lang.annotation.*;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface TableHeader {/*** 表头显示名称* @return*/String[] label() default {"."};/*** 正数加在对开头,负数加在结尾* @return*/int index() default 1;/*** 表头类型* @return*/HeaderTypeEnum headerType() default HeaderTypeEnum.NORMAL;HeaderLabelTypeEnum labelType() default HeaderLabelTypeEnum.NORMAL;}
5、枚举
package com.web.report.enums;public enum HeaderLabelTypeEnum {NORMAL, CONFIG
}package com.web.report.enums;public enum HeaderTypeEnum {NORMAL, FLAT
}
6、各种DTO
(1)TableHeaderConfigDTO
package com.web.report.dto;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.List;@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TableHeaderConfigDTO {private List<String> labels;private String value;
}
(2)WorkReportConditionDTO
package com.web.report.dto;import com.web.enums.WorkProcedureResultEnum;
import com.web.report.annotation.TableHeader;
import com.web.report.enums.HeaderLabelTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class WorkReportConditionDTO {@TableHeader(labelType = HeaderLabelTypeEnum.CONFIG, index = 1)private TableHeaderConfigDTO ConditionDTO;}
(3)WorkReportDTOT
package com.web.report.dto;import com.web.report.annotation.TableHeader;
import com.web.report.enums.HeaderTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.List;@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class WorkReportDTOT {@TableHeader(index = 1, headerType= HeaderTypeEnum.FLAT)private List<WorkReportConditionDTO> serialNo;@TableHeader(index = 2, headerType= HeaderTypeEnum.FLAT)private List<WorkReportConditionDTO> sequence;@TableHeader(index = 3, headerType= HeaderTypeEnum.FLAT)private List<WorkReportConditionDTO> bin;@TableHeader(index = 4, headerType= HeaderTypeEnum.FLAT)private List<WorkReportProcedureDTO> workReportProcedureDTOS;}
4、使用
@Component
@Slf4j
public class WorkReportUtilT {@Autowiredprivate ProjectManageService projectManageService;@Autowiredprivate WorkManageService workManageService;@Autowiredprivate WorkResultService WorkResultService;private static final Map<String, Integer> code2Index = new HashMap<>();private static final Map<String, String> tmMap = new HashMap<>();private static final List<String> conditionsList = new ArrayList<>();private static final List<String> conditionValueList = new ArrayList<>();public void buildReport(WorkManageVO work, String filePath) {// 1.初始话报告内容XinGanXianWorkReportDTOT workReportDTO = null;// 2.判断文件是否存在,如果没有文件那就创建文件并添加表头,表头与数据分开写,防止表头合并File file = new File(filePath);if (!file.exists()) {// 测试结果和头部workReportDTO = buildWorkReportDTO(work, false);List<List<String>> listHead = buildReportHead(workReportDTO);//ExcelWriter excelWriter = EasyExcel.write(file).build();// 合并单元格CustomMergeStrategy customMergeStrategy = new CustomMergeStrategy(listHead.size());// 只写测试结果头部excelWriter.write(new ArrayList<>(),EasyExcel.writerSheet(0).head(listHead).registerWriteHandler(new CustomCellWriteHandler()).registerWriteHandler(customMergeStrategy).build());//这一步很关键,不然文件会损坏excelWriter.finish();excelWriter.close();}// 3. 报告内容为空的话,构建if(workReportDTO == null){workReportDTO = buildWorkReportDTO(work, false);}// 4.往文件中追加数据List<Object> oldData = EasyExcel.read(file).sheet(0).headRowNumber(0).doReadSync();List<XinGanXianWorkReportConditionDTO> serialNo = workReportDTO.getSerialNo();serialNo.get(0).getConditionDTO().setValue(String.valueOf(oldData.size() - 21));List<String> procedureDataList = buildReportData(workReportDTO);oldData.add(procedureDataList);// 5.写入文件ExcelWriter excelWriter = EasyExcel.write(file).build();// 合并单元格CustomMergeStrategy customMergeStrategy = new CustomMergeStrategy(procedureDataList.size());// 设置单元格样式HorizontalCellStyleStrategy horizontalCellStyleStrategy =new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());excelWriter.write(oldData,EasyExcel.writerSheet(0).registerWriteHandler(new CustomColumnWidthHandler()).registerWriteHandler(new CustomCellWriteHandler()).registerWriteHandler(customMergeStrategy).registerWriteHandler(horizontalCellStyleStrategy).build());excelWriter.finish();excelWriter.close();}private List<String> buildReportData(Object o) {List<Field> fields = ReflectionUtil.getAllField(o);List<String> collectDataList = fields.stream().filter(field -> field.isAnnotationPresent(TableHeader.class)).sorted(Comparator.comparingInt(f -> f.getAnnotation(TableHeader.class).index())).flatMap(field -> {TableHeader tableHeader = field.getAnnotation(TableHeader.class);Object value;try {field.setAccessible(true);value = field.get(o);} catch (IllegalAccessException e) {throw new ServiceException("导出报告获取值错误");}if (tableHeader.headerType() == HeaderTypeEnum.FLAT) {return ((List<Object>) value).stream().flatMap(v -> buildReportData(v).stream());}if (tableHeader.labelType() == HeaderLabelTypeEnum.CONFIG) {if (!TableHeaderConfigDTO.class.equals(field.getType())) {throw new ServiceException("导出报告配置错误");}if (value == null) {return Stream.of();}return Stream.of(((TableHeaderConfigDTO) value).getValue());}return Stream.of(Optional.ofNullable(value).map(String::valueOf).orElse(""));}).collect(Collectors.toList());return collectDataList;}private List<List<String>> buildReportHead(Object o) {List<Field> fields = ReflectionUtil.getAllField(o);List<List<String>> collectHeadList = fields.stream().filter(field -> field.isAnnotationPresent(TableHeader.class)).sorted(Comparator.comparingInt(f -> f.getAnnotation(TableHeader.class).index())).flatMap(field -> {TableHeader tableHeader = field.getAnnotation(TableHeader.class);Object value;try {field.setAccessible(true);value = field.get(o);} catch (IllegalAccessException e) {throw new ServiceException("导出报告获取值错误");}if (HeaderTypeEnum.FLAT.equals(tableHeader.headerType())) {if (value == null) {return Stream.of();}if (value instanceof List) {return ((List<Object>) value).stream().flatMap(v -> buildReportHead(v).stream());} else {throw new ServiceException("导出报告配置错误");}}if (HeaderLabelTypeEnum.CONFIG.equals(tableHeader.labelType())) {if (!TableHeaderConfigDTO.class.equals(field.getType())) {throw new ServiceException("导出报告配置错误");}if (value == null) {return Stream.of();}return Stream.of(((TableHeaderConfigDTO) value).getLabels());}return Stream.of(Arrays.asList(tableHeader.label()));}).collect(Collectors.toList());return collectHeadList;}private JSONArray sortCompareRules(JSONArray chooseStandardJsonArray){if(code2Index.size() == 0){List<UniscCommonDictionary> dsaTypes = CommonDictionaryService.searchAll(CommonDictionaryVO.builder().typeLikeRight("device-standard-attribute").build());code2Index.putAll(dsaTypes.stream().collect(Collectors.toMap(CommonDictionary::getCode, CommonDictionary::getIndex, (v1, v2) -> v1)));}// 将JSONArray转换为List后排序List<JSONObject> jsonList = new ArrayList<>();for (int j = 0; j < chooseStandardJsonArray.size(); j++) {jsonList.add(chooseStandardJsonArray.getJSONObject(j));}// 对标规则排序if(jsonList.size() > 0){jsonList.sort((obj1, obj2) -> {Integer r1Index = code2Index.get(obj1.getString("label"));Integer r2Index = code2Index.get(obj2.getString("label"));if (r1Index == null && r2Index == null) {return 0;} else if (r1Index == null) {return 1;} else if (r2Index == null) {return -1;} else {return r1Index.compareTo(r2Index);}});}// 排序后再转回 JSONArrayreturn new JSONArray(Collections.singletonList(jsonList));}private WorkReportDTOT buildWorkReportDTO(WorkManageVO work, boolean offline) {log.info("开始构建buildWorkReportDTO");WorkManageVO detail = workManageService.getDetail(work.getId(), false);List<WorkProcedureVO> procedures = detail.getProcedures();// 不是离线的延时查询结果if(!offline){try {Thread.sleep(2000); // 延时2秒} catch (InterruptedException error) {error.printStackTrace();}}//一次全部查询List<WorkResultVO> ProcedureResultList = WorkResultService.searchAllVO(WorkResultVO.builder().workId(work.getId()).resultMode(WorkResultModeEnum.COMPARE).build());Map<Long, List<WorkResultVO>> procedureIdAndResultMap = ProcedureResultList.stream().collect(Collectors.groupingBy(WorkResultVO::getProcedureId));//工序数据List<WorkReportProcedureDTO> procedureDTOList = new ArrayList<>();// 第一列List<WorkReportConditionDTO> serialNoList = new ArrayList<>();// 第二列List<WorkReportConditionDTO> sequenceList = new ArrayList<>();// 第三列List<WorkReportConditionDTO> binList = new ArrayList<>();//if(procedures != null && procedures.size() > 0){log.info("procedures:" + procedures.size());procedures.forEach(e->{//管子名称String pipeName = e.getPipeName();// 工序参数JSONObject params = e.getParams();//构造条件if(conditionsList.isEmpty()){conditionsList.addAll(Arrays.asList("CreateTime","DataFileName","TestFileName",".","TestIndex","TestPipe","TestMode","condition1","condition2","condition3","condition4","condition5","condition6",".","TestResult","MinLimit","MaxLimit","MinResult","MaxResult","Average","STD DEV","Serial#"));conditionValueList.addAll(Arrays.asList(DateUtil.format(work.getCreateTime(), DateUtils.DATE_FORMAT_19),"",work.getName(),".",Optional.ofNullable(String.valueOf(e.getIdx())).orElse(""),Optional.ofNullable(String.valueOf(e.getTsName())).orElse(""),Optional.ofNullable(String.valueOf(e.getTmName())).orElse(""),Optional.ofNullable(params.getString("T1")).orElse(""),Optional.ofNullable(params.getString("T2")).orElse(""),Optional.ofNullable(params.getString("T3")).orElse(""),Optional.ofNullable(params.getString("correctT1")).orElse(""),Optional.ofNullable(params.getString("targetIntensity")).orElse(""),Optional.ofNullable(params.getString("targetVoltage")).orElse(""),".","","","","","","","","S#"));}if(serialNoList.isEmpty()){XinGanXianWorkReportConditionDTO serialNo = new XinGanXianWorkReportConditionDTO();serialNo.setConditionDTO(TableHeaderConfigDTO.builder().labels(conditionsList).value(".").build());serialNoList.add(serialNo);}if(sequenceList.isEmpty()){XinGanXianWorkReportConditionDTO sequence = new XinGanXianWorkReportConditionDTO();sequence.setConditionDTO(TableHeaderConfigDTO.builder().labels(conditionValueList).value(detail.getSequence()).build());sequenceList.add(sequence);}if(binList.isEmpty()){XinGanXianWorkReportConditionDTO bin = new XinGanXianWorkReportConditionDTO();List<String> binconditionList = new ArrayList<>(Collections.nCopies(conditionsList.size() - 1, ""));binconditionList.add("Bin#");bin.setConditionDTO(TableHeaderConfigDTO.builder().labels(binconditionList).value(String.valueOf(detail.getBinResult())).build());binList.add(bin);}// 对标规则JSONArray chooseStandardJsonArray = new JSONArray();if(params.containsKey("chooseStandardList")){chooseStandardJsonArray.addAll((JSONArray)params.get("chooseStandardList"));log.info("工序 "+ e.getId() + " ,有对标规则");// 排序对标规则JSONArray sortedChooseStandardJsonArray = sortCompareRules(chooseStandardJsonArray);// 结果集合初始化Map<String, List<WorkResultVO>> collectMap = new HashMap<>();// 有结果if(e.getResult() != null){//log.info("结果:" + e.getResult());// 查找工序结果//List<WorkResultVO> ProcedureResults = WorkResultService.searchAllVO(WorkResultVO.builder().procedureId(e.getId()).resultMode(WorkResultModeEnum.COMPARE).build());List<WorkResultVO> ProcedureResults = procedureIdAndResultMap.get(e.getId());if(ProcedureResults != null && ProcedureResults.size() > 0){log.info("工序:"+ e.getId() + "查到结果:" + ProcedureResults.size());collectMap.putAll(ProcedureResults.stream().collect(Collectors.groupingBy(WorkResultVO::getName)));}else{log.info("工序:"+ e.getId()+ "没有查到结果,重新查一次");try {Thread.sleep(2000); // 延时2秒} catch (InterruptedException error) {error.printStackTrace();}List<WorkResultVO> ProcedureResultListAgain = WorkResultService.searchAllVO(WorkResultVO.builder().workId(work.getId()).resultMode(WorkResultModeEnum.COMPARE).build());Map<Long, List<WorkResultVO>> procedureIdAndResultMapAgain = ProcedureResultListAgain.stream().collect(Collectors.groupingBy(WorkResultVO::getProcedureId));List<WorkResultVO> ProcedureResultsAgain = procedureIdAndResultMapAgain.get(e.getId());if(ProcedureResultsAgain != null && ProcedureResultsAgain.size() > 0){log.info("工序:"+ e.getId() + "查到结果:" + ProcedureResultListAgain.size());collectMap.putAll(ProcedureResultsAgain.stream().collect(Collectors.groupingBy(WorkResultVO::getName)));}else{log.info("工序:"+ e.getId()+ "没有查到结果");}}}// 遍历每个对标规则ArrayList jsonArrayList = (ArrayList) sortedChooseStandardJsonArray.get(0);log.info("工序id: "+ e.getId() +" ,对标规则数量: " + jsonArrayList.size());jsonArrayList.forEach(ele->{JSONObject jsonObject = (JSONObject)ele;String unit = jsonObject.getString("unit").replace("(","").replace(")","");String label = jsonObject.getString("label");String maxValue = jsonObject.getString("maxValue");String minValue = jsonObject.getString("minValue");Double actual = 0.0;if(collectMap.size() > 0){List<WorkResultVO> WorkResultVOS = collectMap.get(label);List<WorkResultVO> collectList = WorkResultVOS.stream().sorted(Comparator.comparing(WorkResultVO::getId).reversed()).collect(Collectors.toList());actual = collectList.get(0).getActual();}XinGanXianWorkReportProcedureDTO workReportProcedureDTO = new XinGanXianWorkReportProcedureDTO();ArrayList<String> conditionList = new ArrayList<>(Collections.nCopies(conditionsList.size()-8, ""));List<String> list = Arrays.asList(label, minValue, maxValue, "$$min$$", "$$max$$", "$$avg$$", "$$stddev$$", unit);conditionList.addAll(list);workReportProcedureDTO.setProcedureValue(TableHeaderConfigDTO.builder().labels(conditionList).value(String.valueOf(actual)).build());procedureDTOList.add(workReportProcedureDTO);});}else {log.info("工序 "+ e.getId() + " ,没有对标规则");}});}WorkReportDTOT workReportDTO = new WorkReportDTOT();workReportDTO.setWorkReportProcedureDTOS(procedureDTOList);workReportDTO.setSerialNo(serialNoList);workReportDTO.setSequence(sequenceList);workReportDTO.setBin(binList);return workReportDTO;}}
相关文章:
Java中使用EasyExcel写excel文件
1、公式 package com.web.report.handler;import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.metadata.csv.CsvCellStyle; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.write.handler.CellWriteHandler; import…...
【C语言程序设计】函数程序设计
目录 前言 一、程序阅读 二、程序设计 总结 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于CSDN📚。 📣如需转载&#…...
GDPU 数据结构 天码行空14
实验十四 查找算法的实现 一、【实验目的】 1、掌握顺序排序,二叉排序树的基本概念 2、掌握顺序排序,二叉排序树的基本算法(查找算法、插入算法、删除算法) 3、理解并掌握二叉排序数查找的平均查找长度。 二、【实验内容】 …...
科技提升安全,基于YOLOv5系列模型【n/s/m/l/x】开发构建商超扶梯场景下行人安全行为姿态检测识别系统
在商超等人流量较为密集的场景下经常会报道出现一些行人在扶梯上摔倒、受伤等问题,随着AI技术的快速发展与不断普及,越来越多的商超、地铁等场景开始加装专用的安全检测预警系统,核心工作原理即使AI模型与摄像头图像视频流的实时计算…...
【网络安全】网络防护之旅 - 对称密码加密算法的实现
🌈个人主页:Sarapines Programmer🔥 系列专栏:《网络安全之道 | 数字征程》⏰墨香寄清辞:千里传信如电光,密码奥妙似仙方。 挑战黑暗剑拔弩张,网络战场誓守长。 目录 😈1. 初识网络安…...
鸿蒙arkTs Toast抽取 及使用
Toast抽取,创建一个Utils import promptAction from ohos.promptAction; import display from ohos.display; export function ToastUtils(msg:string){try {promptAction.showToast({message: msg,duration: 1500,bottom:450});} catch (error) {console.error(sh…...
网络安全渗透测试的相关理论和工具
网络安全 一、引言二、网络安全渗透测试的概念1、黑盒测试2、白盒测试3、灰盒测试 三、网络安全渗透测试的执行标准1、前期与客户的交流阶段1.1 渗透测试的目标网络1.2 进行渗透测试所使用的方法1.3 进行渗透测试所需要的条件1.4 渗透测试过程中的限制条件1.5 渗透测试的工期1.…...
C 语言 xml 库的使用
在C语言中,可以使用多种库来处理XML文件,其中最常用的是libxml2库。libxml2是一个用于解析XML和HTML文档的C语言库,它提供了许多功能,包括解析XML文档、创建XML文档、验证XML文档等等。下面是一个简单的示例,演示读取l…...
群晖(Synology)云备份的方案是什么
群晖云备份方案就是在本地的 NAS 如果出现问题,或者必须需要重做整列的时候,保证数据不丢失。 当然,这些是针对有价值的数据,如果只是电影或者不是自己的拍摄素材文件,其实可以不使用云备份方案,因为毕竟云…...
Flask 中的跨域难题:定义、影响与解决方案深度解析
跨域(Cross-Origin)是指在浏览器中,一个页面的脚本试图访问另一个页面的内容时发生的安全限制。Flask 作为一种 Web 应用框架,也涉及到跨域问题。本文将详细介绍跨域的定义、影响以及解决方案,涵盖如何在 Flask 中处理…...
汽车IVI中控开发入门及进阶(十二):V4L2视频
前言 汽车中控也被称为车机、车载多媒体、车载娱乐等,其中音频视频是非常重要的部分,比如播放各种格式的音乐文件、播放蓝牙接口的音乐、播放U盘或TF卡中的音视频文件,看起来很简单。如果说音频来源于振动,那么图片图像就是光反射的一种表象。模拟信号表示在空间上是连续…...
gitlab下载安装
1.下载 官网rpm包 gitlab/gitlab-ce - Results in gitlab/gitlab-ce 国内镜像 Index of /gitlab-ce/yum/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2.安装 rpm -ivh gitlab-ce-16.4.3-ce.0.el7.x86_64.rpm 3.配置 vim /etc/gitlab/gitlab.rb 将 externa…...
Jmeter,提取响应体中的数据:正则表达式、Json提取器
一、正则表达式 1、线程组--创建线程组; 2、线程组--添加--取样器--HTTP请求; 3、Http请求--添加--后置处理器--正则表达式提取器; 4、线程组--添加--监听器--查看结果树; 5、线程组--添加--取样器--调试取样器。 响应体数据…...
【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)
文章目录 🍔什么是缓存穿透🎄解决办法⭐缓存空值处理🎈优点🎈缺点🎍代码实现 ⭐布隆过滤器🎍代码实现 🍔什么是缓存穿透 缓存穿透是指在使用缓存机制时,大量的请求无法从缓存中获取…...
Gitlab基础篇: Gitlab docker 安装部署、Gitlab 设置账号密码
文章目录 1、环境准备2、配置1)、初始化2)、修改gitlab配置文件3)、修改docker配置的gitlab默认端口 gitlab进阶配置gitlab 设置账号密码 1、环境准备 安装docker gitlab前确保docker环境,如果没有搭建docker请查阅“Linux docker 安装文档” docker 下载 gitlab容…...
c++常见函数处理
1、clamp clamp:区间限定函数 int64_t a Clamp(a, MIN_VALUE, MAX_VALUE); #include <iomanip> #include <iostream> #include <sstream>int main() {std::cout << "no setw: [" << 42 << "]\n"<&l…...
MYsql第二次作业
目录 问题 解答 1.显示所有职工的基本信息。 2.查询所有职工所属部门的部门号,不显示重复的部门号。 3.求出所有职工的人数。 4.列出最高工和最低工资。 5.列出职工的平均工资和总工资。 6.创建一个只有职工号、姓名和参加工作的新表,名为工作日…...
SQLAlchemy 第三篇
使用insert语句 from sqlalchemy import Table, Column, Integer, String, MetaDatametadata_obj MetaData() user_table Table("user_account",metadata_obj,Column("id", Integer, primary_keyTrue),Column("name", String(255)),Column(&q…...
交互过程中影响信息质量好坏的因素
人机交互是指人与计算机之间的交流和互动,而人人交流是指人与人之间的交流和互动。在信息质量方面,人机交互通常更为准确和精确,而人人交流可能存在误解、模糊和歧义。 人机交互的信息传递往往通过明确的界面、符号和指令等方式进行。计算机可…...
服务器上配置jupyter,提示Invalid credentials如何解决
我是按照网上教程在服务器上安装的jupyter以及进行的密码配置,我利用 passwd()这个口令生成的转译密码是"argon...."。按照教程配置jupyter notebook配置文件里面的内容,登陆网页提示"Invalid credentials"。我谷歌得到的解答是&…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
