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;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue学习笔记-Vue3中的customRef

作用 创建一个自定义的ref&#xff0c;并对其依赖项的更新和触发进行显式控制 案例 描述&#xff1a;向输入框中输入内容&#xff0c;在下方延迟1秒展示输入内容 代码&#xff1a; <template><input type"text" v-model"keyword"><h3&…

从零开发短视频电商 用Java框架部署模型并推理 - Deep Java Library (DJL)

文章目录 支持引擎模型库示例一 基础模型 图片分类示例二 huggingface模型库 文本嵌入获取Tokenization标记(tokens)的数量官网: https://djl.ai/ 动手学深度学习-中文:https://d2l-zh.djl.ai/ 支持模型 PyTorch TorchScript modelTensorFlow SavedModel bundleApache MXNe…

Spring 使用 MongoDB 时的数据类型转换器

官方文档&#xff1a;自定义类型转换器 是时间戳为例的代码&#xff1a; TimestampReadConverter.java import org.bson.BsonTimestamp; import org.springframework.core.convert.converter.Converter;import java.time.Instant; import java.util.Date;/* * Java类型与 Mo…

网络安全项目实战(四)--报文检测

8. TCP/UDP 段 目标 了解 TCP 段头的组织结构了解 UDP 段头的组织结构掌握 TCP/UDP 段的解析方式 8.1. UDP 段格式 下图是UDP的段格式&#xff08;该图出自[TCPIP]&#xff09;。 8.2. UDP头部 //UDP头部&#xff0c;总长度8字节// /usr/include/linux/udp.h struct udphdr …

uniapp提交带有弹出确认和取消按钮方法提交接口

目录 方法1方法2最后 方法1 submitServie(){let self this;if (!self.resultData.item && !self.resultData.subItem) {uni.showToast({title: 请选择服务分类,duration: 1000,icon: none});return false;}uni.showModal({title: 提示,content: 确定提交&#xff1f;…

自定义Axure元件库及原型图泳道图的绘制(详细不同类的案例)

目录 前言 一.自定义元件库 1.1 自定义元件库的作用 1.2 自定义元件的操作 二.流程图 2.1 流程图的作用 2.2 绘制流程图 2.3 简易流程图案例 三.泳道图 3.1 泳道图的作用 3.2 流程图和泳道图的区别 3.3 绘制泳道图 四.绘制前的准备 五.案例 4.1 门诊模块案例 4.2 …

聚观早报 |iOS17.3引入设备被盗保护;iPhone16或调整设计

【聚观365】12月14日消息 iOS17.3引入设备被盗保护 iPhone16或调整设计 马斯克星链网络使用量飙升 华为鸿蒙智行App正式上线 特斯拉人形机器人Optimus二代上线 iOS17.3引入设备被盗保护 苹果向iPhone用户推送了iOS17.3开发者预览版Beta更新&#xff0c;本次更新距离上次发…

Vue2.x源码:new Vue()做了啥

例子1new Vue做了啥?new Vue做了啥,源码解析 initMixin函数 初始化 – 初始化Vue实例的配置initLifecycle函数 – 初始化生命周期钩子函数initEvents – 初始化事件系统初始化渲染 initRender初始化inject选项 例子1 <div id"app"><div class"home&…

docker安装最新版SQL Server并还原备份的数据库

docker安装数据库 拉取微软官方最新版镜像 docker pull mcr.microsoft.com/mssql/server 拉去镜像并创建容器 docker run -e "ACCEPT_EULAY" -e "SA_PASSWORDsa_password_123456" -p 1433:1433 -v /opt/:/opt --name sqlserver -d mcr.microsoft.com/ms…

前端页面显示的时间格式为:2022-03-18T01:46:08.000+00:00 如何转换为:年-月-日,并根据当前时间判断为几天前

由于后端每条博文的发表时间是以“xxxx—xx—xxxx:xx:xx”的形式显示的&#xff0c; 现在要在前端改成“xxxx年xx月xx日”的形式。 并对10分钟内发表的显示“刚刚”&#xff0c;对24小时内发表的显示“小时前”。 超过24小时&#xff0c;小于48小时&#xff0c;显示“1天前”。…

生产实践:基于K8S的私有化部署解决方案

随着国内数字化转型的加速和国产化进程推动&#xff0c;软件系统的私有化部署已经成为非常热门的话题&#xff0c;因为私有化部署赋予了企业更大的灵活和控制权&#xff0c;使其可以根据自身需求和安全要求定制和管理软件系统。下面分享下我们的基于k8S私有化部署经验。 私有化…

Nginx 服务器安装及配置文件详解

1. 安装nginx 1.1 选择稳定版本 我们编译安装nginx来定制自己的模块&#xff0c;机器CentOS 6.2 x86_64。首先安装缺少的依赖包&#xff1a; # yum -y install gcc gcc-c make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel 这些软件包如果yum上没有的话…

如何使用EXCEL制作一份高效、美观的成绩单

要制作一份高效、美观的成绩单&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 打开Excel软件&#xff0c;创建一个新的工作簿。 2. 在工作簿中创建一个新的工作表&#xff0c;可以点击工作簿底部的""按钮&#xff0c;或者使用快捷键"Shift F11"。…

第一周:AI产品经理跳槽准备工作

一、筛选意向行业 因素1:行业发展情况 因素2:工作经验优势 技术背景:计算机视觉、人工智能、敏捷管理产品背景:2B、2C、跨境电商、平台工具、SAAS领域:国内、跨境行业:教育、新零售、电商相关项目:数据分析工具、在线编程平台OJ、线下新零售系统、订单交易履约、跨境E…

VS2022配置C++ 20解决import std报错

C 20新特征支持用import std来导入std模块&#xff0c;如下&#xff1a; 配置时主要有两个步骤&#xff1a; &#xff08;1&#xff09;项目--属性--常规--C语言标准--预览 - 最新 C 工作草案中的功能 (/std:clatest) 注意选择ISO C20 标准 (/std:c20)也不能正常使用&#xf…

【PgSQL】导出表结构为EXCEL

详细SQL语句&#xff1a; C.relname ‘你的表名’ 直接输入表面即可 PgSQL 打印表结构语句 SELECT C.relname AS "表名",CAST(obj_description(C.oid, pg_class) AS VARCHAR) AS "表名描述",A.attname AS "字段名",CASE WHEN A.attnotnull f …

(C++)无重复字符的最长子串--滑动窗口

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://le…

Oracle存储过程打印输出错误信息、行号,快速排查

测试存储过程如下&#xff1a; create or replace procedure prc_test isp_1 varchar2(2); beginp_1 : lxw测试;exceptionwhen others thendbms_output.put_line(sqlcode); --Oracle内置变量&#xff0c;错误代码dbms_output.put_line(sqlerrm); --Oracle内置变量&#xff0c;…

【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)

文章目录 &#x1f354;什么是缓存穿透&#x1f384;解决办法⭐缓存空值处理&#x1f388;优点&#x1f388;缺点&#x1f38d;代码实现 ⭐布隆过滤器&#x1f38d;代码实现 &#x1f354;什么是缓存穿透 缓存穿透是指在使用缓存机制时&#xff0c;大量的请求无法从缓存中获取…

KylinV10 将项目上传至 Github

KylinV10 将项目上传至 Github 银河麒麟操作系统 V10 是在 Ubuntu 的基础上开发的&#xff0c;所以适用于 Ubuntu 的也适用于 KylinV10 一般上传至 GitHub&#xff0c;有两种方式&#xff0c;一种是 HTTPS&#xff0c;一种是 SSH&#xff0c;但是在 KylinV10 操作系统 HTTPS 的…