Java导出通过Word模板导出docx文件并通过QQ邮箱发送
一、创建Word模板
{{company}}{{Date}}服务器运行情况报告一、服务器:总告警次数:{{ServerTotal}}
服务器IP:{{IPA}},总共告警次数:{{ServerATotal}}
服务器IP:{{IPB}},总共告警次数:{{ServerBTotal}}
服务器IP:{{IPC}},总共告警次数:{{ServerCTotal}} 二、应用程序:总告警次数{{ApplicationTotal}}
服务器IP:{{IPA}},包含{{ApplicationAName}}应用程序服务,总共告警次数:{{ApplicationATotal}}
服务器IP:{{IPB}},包含{{ApplicationBName}}应用程序服务,总共告警次数:{{ApplicationBTotal}}
服务器IP:{{IPC}},包含{{ApplicationCName}}应用程序服务,总共告警次数:{{ApplicationCTotal}}三、数据库:总告警次数{{DBTotal}}
服务器IP:{{IPA}},包含{{DBAName}}数据库,总共告警次数:{{DBATotal}}
服务器IP:{{IPB}},包含{{DBBName}}数据库,总共告警次数:{{DBBTotal}}
服务器IP:{{IPC}},包含{{DBCName}}数据库,总共告警次数:{{DBCTotal}}四、中间件:总告警次数{{MiddleWareTotal}}
服务器IP:{{IPA}},包含{{MiddleWareAName}}中间件,总共告警次数:{{MiddleWareATotal}}
服务器IP:{{IPB}},包含{{MiddleWareBName}}中间件,总共告警次数:{{MiddleWareBTotal}}
服务器IP:{{IPC}},包含{{MiddleWareCName}}中间件,总共告警次数:{{MiddleWareCTotal}} 五、接口:总告警次数{{InterfaceTotal}}
服务器IP:{{IPA}},包含{{InterfaceAName}}接口服务,总共告警次数:{{InterfaceATotal}}
服务器IP:{{IPB}},包含{{InterfaceBName}}接口服务,总共告警次数:{{InterfaceBTotal}}
服务器IP:{{IPC}},包含{{InterfaceCName}}接口服务,总共告警次数:{{InterfaceCTotal}}
将上述内容存入一个docx文件中,放到resources文件夹下
二、编写代码
package com.gitee.pifeng.monitoring.server.business.server.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gitee.pifeng.monitoring.server.business.server.dao.*;
import com.gitee.pifeng.monitoring.server.business.server.entity.*;
import com.gitee.pifeng.monitoring.server.business.server.service.IAlarmService;
import com.gitee.pifeng.monitoring.server.config.WordTemplateConfig;import com.gitee.pifeng.monitoring.server.util.db.SelectEmailsService;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.util.StringUtils;import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;/*** description 导出word版本的报表** @author yhj* @date 2025-01-06 17:08:15*/@RequestMapping("/ExportWord")
@RestController
public class ExportWordReportController {@Autowiredprivate WordTemplateConfig wordTemplateConfig;/*** 告警服务接口*/@Autowiredprivate IAlarmService alarmService;@Autowiredprivate IMonitorInstanceDao monitorInstanceDao;@Autowiredprivate IMonitorAlarmRecordDao monitorAlarmRecordDao;@Autowiredprivate IMonitorDbDao monitorDbDao;@Autowiredprivate IMonitorTcpDao monitorTcpDao;@Autowiredprivate IMonitorHttpDao monitorHttpDao;@Autowiredprivate SelectEmailsService emailsService;public void exportWordTemplate(HttpServletResponse response, Map<String, String> data, String filename) {String companyName = emailsService.selectCompanyName();data.put("company", companyName);try {String filePath = URLDecoder.decode(getClass().getClassLoader().getResource("templates/static/WordReportTemplete.docx").getPath(), "UTF-8");// 读取Word模板FileInputStream fis = new FileInputStream(filePath);XWPFDocument document = new XWPFDocument(fis);// 将填充后的文档写入响应输出流wordTemplateConfig.replaceTextInDocument(document, data);// 设置响应头,指定下载文件类型和名称response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + filename + ".docx");document.write(response.getOutputStream());// 关闭资源document.close();fis.close();} catch (IOException e) {e.printStackTrace();}}private void exportEmptyWordTemplate(HttpServletResponse response, Map<String, String> data) {String companyName = emailsService.selectCompanyName();String filename = URLEncoder.encode(String.valueOf(new StringBuilder(companyName).append("现场暂无数据"))).replaceAll("\\+", "%20");data.put("company", companyName);try {String filePath = URLDecoder.decode(getClass().getClassLoader().getResource("templates/static/EmptyWordReportTemplete.docx").getPath(), "UTF-8");// 读取Word模板FileInputStream fis = new FileInputStream(filePath);XWPFDocument document = new XWPFDocument(fis);// 将填充后的文档写入响应输出流wordTemplateConfig.replaceTextInDocument(document, data);// 设置响应头,指定下载文件类型和名称response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + filename + ".docx");document.write(response.getOutputStream());// 关闭资源document.close();fis.close();} catch (IOException e) {e.printStackTrace();}}/*** 本日服务器报错信息word导出** @param response*/@GetMapping("/getThisDayWordReport")public void getDayWordReport(HttpServletResponse response) {String companyName = emailsService.selectCompanyName();Map<String, String> data = new HashMap<>();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");Date date = new Date();String TodayDay = simpleDateFormat.format(date);data.put("Date", TodayDay);Integer flag = 0; // 0代表今日//文件名,以下方法用于防止中文编码错误String name = String.valueOf(new StringBuilder(companyName).append(TodayDay).append("服务器报错信息"));String filename = URLEncoder.encode(name).replaceAll("\\+", "%20");thisWordInfo(response, flag, TodayDay, data, filename);}// 将导出的信息填充给wordprivate void thisWordInfo(HttpServletResponse response, Integer flag, String Date, Map<String, String> data, String filename) {// 查询所有IPList<String> IpList = getIpList();if (IpList.size() == 0) {exportEmptyWordTemplate(response, data);} else {List<ExportWordReport> listA = new ArrayList<>();if (!IpList.get(0).isEmpty()) {String IPA = IpList.get(0);if (flag == 0) {// 当日报错个数listA = alarmService.selectWordDayAlarmTotal(IPA, Date);} else if (flag == 1) {// 本周报错个数listA = alarmService.selectWordWeekAlarmTotal(IPA, Date);} else if (flag == 2) {// 本月报错个数listA = alarmService.selectWordMonthAlarmTotal(IPA, Date);} else if (flag == 3) {// 本年报错个数listA = alarmService.selectWordYearAlarmTotal(IPA, Date);}// 汇总各项报错个数Map<String, Integer> mapA = listA.stream().collect(Collectors.toMap(ExportWordReport::getName, ExportWordReport::getTotal));// 查询该IP下所有应用程序的名称String applicationName = getApplicationNameList(IPA);// 查询该IP下所有数据库名字String DBName = getDBNameList(IPA);// 查询该IP下所有中间件名字String MiddleWareName = getMiddleNameList(IPA);// 查询该IP下所有接口名称String InterfaceName = getInterfaceNameList(IPA);// 填充word里面的字段data.put("IPA", IPA);data.put("ApplicationAName", !applicationName.isEmpty() ? applicationName : "0个");data.put("DBAName", !DBName.isEmpty() ? DBName : "0个");data.put("MiddleWareAName", !MiddleWareName.isEmpty() ? MiddleWareName : "0个");data.put("InterfaceAName", !InterfaceName.isEmpty() ? InterfaceName : "0个");// 服务器data.put("ServerATotal", mapA.get("SERVER") != null ? String.valueOf(mapA.get("SERVER")) : "0");// 应用data.put("ApplicationATotal", mapA.get("INSTANCE") != null ? String.valueOf(mapA.get("INSTANCE")) : "0");// 数据库data.put("DBATotal", mapA.get("DATABASE") != null ? String.valueOf(mapA.get("DATABASE")) : "0");// 中间件data.put("MiddleWareATotal", mapA.get("TCP4SERVICE") != null ? String.valueOf(mapA.get("TCP4SERVICE")) : "0");// 接口data.put("InterfaceATotal", mapA.get("HTTP4SERVICE") != null ? String.valueOf(mapA.get("HTTP4SERVICE")) : "0");}if (!IpList.get(1).isEmpty()) {List<ExportWordReport> listB = new ArrayList<>();String IPB = IpList.get(1);if (flag == 0) {listB = alarmService.selectWordDayAlarmTotal(IPB, Date);} else if (flag == 1) {// 本周报错信息listB = alarmService.selectWordWeekAlarmTotal(IPB, Date);} else if (flag == 2) {// 本月报错个数listB = alarmService.selectWordMonthAlarmTotal(IPB, Date);} else if (flag == 3) {// 本年报错个数listB = alarmService.selectWordYearAlarmTotal(IPB, Date);}// 汇总各项报错个数Map<String, Integer> mapB = listB.stream().collect(Collectors.toMap(ExportWordReport::getName, ExportWordReport::getTotal));// 查询该IP下所有应用程序的名称String applicationName = getApplicationNameList(IPB);// 查询该IP下所有数据库名字String DBName = getDBNameList(IPB);// 查询该IP下所有中间件名字String MiddleWareName = getMiddleNameList(IPB);// 查询该IP下所有接口名称String InterfaceName = getInterfaceNameList(IPB);data.put("IPB", IPB);data.put("ApplicationBName", !applicationName.isEmpty() ? applicationName : "0个");data.put("DBBName", !DBName.isEmpty() ? DBName : "0个");data.put("MiddleWareBName", !MiddleWareName.isEmpty() ? MiddleWareName : "0个");data.put("InterfaceBName", !InterfaceName.isEmpty() ? InterfaceName : "0个");// 服务器data.put("ServerBTotal", mapB.get("SERVER") != null ? String.valueOf(mapB.get("SERVER")) : "0");// 应用data.put("ApplicationBTotal", mapB.get("INSTANCE") != null ? String.valueOf(mapB.get("INSTANCE")) : "0");// 数据库data.put("DBBTotal", mapB.get("DATABASE") != null ? String.valueOf(mapB.get("DATABASE")) : "0");// 中间件data.put("MiddleWareBTotal", mapB.get("TCP4SERVICE") != null ? String.valueOf(mapB.get("TCP4SERVICE")) : "0");// 接口data.put("InterfaceBTotal", mapB.get("HTTP4SERVICE") != null ? String.valueOf(mapB.get("HTTP4SERVICE")) : "0");}if (!IpList.get(2).isEmpty()) {List<ExportWordReport> listC = new ArrayList<>();String IPC = IpList.get(2);if (flag == 0) {listC = alarmService.selectWordDayAlarmTotal(IPC, Date);} else if (flag == 1) {// 本周报错个数listC = alarmService.selectWordWeekAlarmTotal(IPC, Date);} else if (flag == 2) {// 本月报错个数listC = alarmService.selectWordMonthAlarmTotal(IPC, Date);} else if (flag == 3) {// 本年报错个数listC = alarmService.selectWordYearAlarmTotal(IPC, Date);}// 汇总各项报错个数Map<String, Integer> mapC = listC.stream().collect(Collectors.toMap(ExportWordReport::getName, ExportWordReport::getTotal));// 查询该IP下所有应用程序的名称String applicationName = getApplicationNameList(IPC);// 查询该IP下所有数据库名字String DBName = getDBNameList(IPC);// 查询该IP下所有中间件名字String MiddleWareName = getMiddleNameList(IPC);// 查询该IP下所有接口名称String InterfaceName = getInterfaceNameList(IPC);data.put("IPC", IPC);data.put("ApplicationCName", !applicationName.isEmpty() ? applicationName : "0个");data.put("DBCName", DBName);data.put("MiddleWareCName", !MiddleWareName.isEmpty() ? MiddleWareName : "0个");data.put("InterfaceCName", !InterfaceName.isEmpty() ? InterfaceName : "0个");// 服务器data.put("ServerCTotal", mapC.get("SERVER") != null ? String.valueOf(mapC.get("SERVER")) : "0");// 应用data.put("ApplicationCTotal", mapC.get("INSTANCE") != null ? String.valueOf(mapC.get("INSTANCE")) : "0");// 数据库data.put("DBCTotal", mapC.get("DATABASE") != null ? String.valueOf(mapC.get("DATABASE")) : "0");// 中间件data.put("MiddleWareCTotal", mapC.get("TCP4SERVICE") != null ? String.valueOf(mapC.get("TCP4SERVICE")) : "0");// 接口data.put("InterfaceCTotal", mapC.get("HTTP4SERVICE") != null ? String.valueOf(mapC.get("HTTP4SERVICE")) : "0");}// 所有服务器报错信息条数总和int ServerTotal = Integer.parseInt(data.get("ServerATotal")) + Integer.parseInt(data.get("ServerBTotal")) + Integer.parseInt(data.get("ServerCTotal"));data.put("ServerTotal", String.valueOf(ServerTotal));// 所有应用程序报错信息总和int ApplicationTotal = Integer.parseInt(data.get("ApplicationATotal")) + Integer.parseInt(data.get("ApplicationBTotal")) + Integer.parseInt(data.get("ApplicationCTotal"));data.put("ApplicationTotal", String.valueOf(ApplicationTotal));//所有数据库报错信息总和int DBTotal = Integer.parseInt(data.get("DBATotal")) + Integer.parseInt(data.get("DBBTotal")) + Integer.parseInt(data.get("DBCTotal"));data.put("DBTotal", String.valueOf(DBTotal));//所有中间件报错信息总和int MiddleWareTotal = Integer.parseInt(data.get("MiddleWareATotal")) + Integer.parseInt(data.get("MiddleWareBTotal")) + Integer.parseInt(data.get("MiddleWareCTotal"));data.put("MiddleWareTotal", String.valueOf(MiddleWareTotal));//所有接口报错信息总和int InterfaceTotal = Integer.parseInt(data.get("InterfaceATotal")) + Integer.parseInt(data.get("InterfaceBTotal")) + Integer.parseInt(data.get("InterfaceCTotal"));data.put("InterfaceTotal", String.valueOf(InterfaceTotal));exportWordTemplate(response, data, filename);}}// 查询所有接口名称private String getInterfaceNameList(String IP) {LambdaQueryWrapper<MonitorHttp> queryInterfaceNameWrapper = new LambdaQueryWrapper<>();queryInterfaceNameWrapper.select(MonitorHttp::getDescr).ne(MonitorHttp::getDescr,null).ne(MonitorHttp::getDescr,"").eq(MonitorHttp::getHostnameSource, IP).groupBy(MonitorHttp::getDescr);List<String> InterfaceList = monitorHttpDao.selectList(queryInterfaceNameWrapper).stream().filter(item -> item!=null).map(MonitorHttp::getDescr).collect(Collectors.toList());String InterfaceName = InterfaceList.stream().map(String::toString).collect(Collectors.joining("、"));return InterfaceName;}// 查询所有IPprivate List<String> getIpList() {LambdaQueryWrapper<MonitorAlarmRecord> queryIPWrapper = new LambdaQueryWrapper<>();queryIPWrapper.select(MonitorAlarmRecord::getIp).groupBy(MonitorAlarmRecord::getIp);List<String> IpList = monitorAlarmRecordDao.selectList(queryIPWrapper).stream().filter(item -> item != null).map(MonitorAlarmRecord::getIp).collect(Collectors.toList());return IpList;}// 查询该IP下所有中间件的名称private String getMiddleNameList(String IP) {LambdaQueryWrapper<MonitorTcp> queryMiddleNameWrapper = new LambdaQueryWrapper<>();queryMiddleNameWrapper.select(MonitorTcp::getDescr).ne(MonitorTcp::getDescr,"").ne(MonitorTcp::getDescr,null).eq(MonitorTcp::getHostnameSource, IP).groupBy(MonitorTcp::getDescr);List<String> MiddleWareList = monitorTcpDao.selectList(queryMiddleNameWrapper).stream().filter(item -> item != null).map(MonitorTcp::getDescr).collect(Collectors.toList());String MiddleWareName = MiddleWareList.stream().map(String::toString).collect(Collectors.joining("、"));return MiddleWareName;}// 查询该IP下所有应用程序的名称private String getApplicationNameList(String IP) {// 查询该IP下所有应用程序的名称LambdaQueryWrapper<MonitorInstance> queryInstanceNameWrapper = new LambdaQueryWrapper<>();queryInstanceNameWrapper.select(MonitorInstance::getInstanceName) // 指定查询字段.ne(MonitorInstance::getInstanceName,"").ne(MonitorInstance::getInstanceName,null).eq(MonitorInstance::getIp, IP) // 添加 IP 条件.groupBy(MonitorInstance::getInstanceName); // 去重(相当于 DISTINCT)List<String> ApplicationNameList = monitorInstanceDao.selectList(queryInstanceNameWrapper).stream().map(MonitorInstance::getInstanceName) // 提取字段值.distinct().collect(Collectors.toList());// 确保去重String applicationName = ApplicationNameList.stream().map(String::toString).collect(Collectors.joining("、"));return applicationName;}// 查询所有数据库名字公共方法private String getDBNameList(String IP) {LambdaQueryWrapper<MonitorDb> queryDBListWrapper = new LambdaQueryWrapper<>();queryDBListWrapper.select(MonitorDb::getDbType).ne(MonitorDb::getDbType,"").ne(MonitorDb::getDbType,null).eq(MonitorDb::getIp, IP).groupBy(MonitorDb::getDbType);List<String> DBList = monitorDbDao.selectList(queryDBListWrapper).stream().filter(item -> item != null).map(MonitorDb::getDbType).collect(Collectors.toList());String DBName = DBList.stream().map(String::toString).collect(Collectors.joining("、"));return DBName;}}
工具类,主要读取信息并写入word模板内
package com.gitee.pifeng.monitoring.server.config;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;@Component
public class WordTemplateConfig {public void replaceTextInDocument(XWPFDocument document, Map<String, String> data) {// 替换段落中的占位符for (XWPFParagraph paragraph : document.getParagraphs()) {StringBuilder paragraphText = new StringBuilder();List<XWPFRun> runs = paragraph.getRuns();if (runs != null) {// 收集段落中的所有文本for (XWPFRun run : runs) {paragraphText.append(run.getText(0) != null ? run.getText(0) : "");}// 替换占位符String replacedText = paragraphText.toString();for (Map.Entry<String, String> entry : data.entrySet()) {replacedText = replacedText.replace("{{" + entry.getKey() + "}}", entry.getValue() != null ? entry.getValue() : "");}// 清空原有 runsfor (int i = runs.size() - 1; i >= 0; i--) {paragraph.removeRun(i);}// 重新设置替换后的文本XWPFRun newRun = paragraph.createRun();newRun.setText(replacedText);}}// 替换表格中的占位符for (XWPFTable table : document.getTables()) {for (XWPFTableRow row : table.getRows()) {for (XWPFTableCell cell : row.getTableCells()) {for (XWPFParagraph paragraph : cell.getParagraphs()) {for (XWPFRun run : paragraph.getRuns()) {String text = run.getText(0);if (text != null) {for (Map.Entry<String, String> entry : data.entrySet()) {if (text.contains("{{" + entry.getKey() + "}}")) {text = text.replace("{{" + entry.getKey() + "}}", entry.getValue());run.setText(text, 0);}}}}}}}}}
}
三、发送邮箱
@RequestMapping("/SendWord")
@RestController
public class SendWordReportController {@Autowiredprivate EmailSender emailSender;@Autowiredprivate SelectEmailsService emailsService;SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");String date = simpleDateFormat.format(new Date());/*** 发送日报表*/@PostMapping("/sendDayWordReport")public void sendDayWordReport() {List<String> emails = emailsService.findEmail();String companyName = emailsService.selectCompanyName();String name = companyName+new StringBuilder(date).append("日服务器报错信息汇总");try {// 调用接口下载 Excel 文件String apiUrl = "http://localhost:16000/phoenix-server/ExportWord/getThisDayWordReport";File wordFile = FileDownloader.downloadWordFile(apiUrl);// 接收邮件的邮箱for (String email: emails) {emailSender.sendEmailWithAttachment(email,wordFile,name);}
// emailSender.sendEmailWithAttachment(toEmail,wordFile,name);} catch (IOException | MessagingException e) {e.printStackTrace();}}}}
package com.gitee.pifeng.monitoring.server.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.io.IOException;
import java.util.Properties;/*** description 发送报表数据** @author yhj* @date 2025-01-02 15:39:08*/@Component
public class EmailSender {@Value("${spring.mail.username}")private String username;@Value("${spring.mail.password}")private String password;@Autowiredprivate JavaMailSender sender;public void sendEmailWithAttachment(String toEmail,File attachmentFile,String name) throws MessagingException, IOException {// 设置邮件属性Properties properties = new Properties();properties.put("mail.smtp.host","smtp.exmail.qq.com");properties.put("mail.smtp.port",465);properties.put("mail.smtp.auth","true");properties.put("mail.smtp.starttls.enable","true");// 获取邮件会话
// Session session = Session.getInstance(properties, new Authenticator() {
// @Override
// protected PasswordAuthentication getPasswordAuthentication() {
// // 填写发送者邮箱和授权码
// return new PasswordAuthentication(username, password);
// }
// });//创建邮件内容// 创建MimeMessage对象MimeMessage message = sender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true); // true表示支持附件helper.setFrom("249@qq.com");helper.setTo(toEmail);
// String subject = String.valueOf(new StringBuilder(companyName).append("服务器运行状况报表"));message.setSubject(name);// 创建一个Multipart对象,包含邮件正文和附件Multipart multipart = new MimeMultipart();// 邮件正文部分
// MimeBodyPart messageBodyPart = new MimeBodyPart();
// messageBodyPart.setText(name);
// multipart.addBodyPart(messageBodyPart);// 邮件附件部分MimeBodyPart attachmentPart = new MimeBodyPart();attachmentPart.attachFile(attachmentFile);attachmentPart.setFileName(name+".docx");multipart.addBodyPart(attachmentPart);// 附加附件文件message.setContent(multipart);// 发送邮件sender.send(message);System.out.println("邮件发送成功!");}
}
相关文章:

Java导出通过Word模板导出docx文件并通过QQ邮箱发送
一、创建Word模板 {{company}}{{Date}}服务器运行情况报告一、服务器:总告警次数:{{ServerTotal}} 服务器IP:{{IPA}},总共告警次数:{{ServerATotal}} 服务器IP:{{IPB}},总共告警次数:{{ServerBTotal}} 服务器IP:{{IPC}}&#x…...

ESP8266 MQTT服务器+阿里云
MQTT私有平台搭建(EMQX 阿里云) 阿里云服务器 EMQX 搭建私有MQTT平台 1、搜索EMQX开源版本 2、查看各版本EMQX支持的UBUNTU版本 3、查看服务器Ubuntu版本 4、使用APT安装模式 5、按照官网指示安装并启动 6、下载安装MQTTX测试工具 7、设置云服务…...

css动画水球图
由于echarts水球图动画会导致ios卡顿,所以纯css模拟 展示效果 组件 <template><div class"water-box"><div class"water"><div class"progress" :style"{ --newProgress: newProgress % }"><…...

【设计模式-行为型】状态模式
一、什么是状态模式 什么是状态模式呢,这里我举一个例子来说明,在自动挡汽车中,挡位的切换是根据驾驶条件(如车速、油门踏板位置、刹车状态等)自动完成的。这种自动切换挡位的过程可以很好地用状态模式来描述。状态模式…...

2024.1.22 安全周报
政策/标准/指南最新动态 01 工信部印发《关于加强互联网数据中心客户数据安全保护的通知》 原文: https://www.secrss.com/articles/74673 互联网数据中心作为新一代信息基础设施,承载着千行百业的海量客户数据,是关系国民经济命脉的重要战略资源。…...

idea修改模块名导致程序编译出错
本文简单描述分别用Idea菜单、pom.xml文件管理项目模块module 踩过的坑: 通过idea菜单创建模块,并用idea菜单修改模块名,结构程序编译报错,出错的代码莫名奇妙。双击maven弹窗clean时,还是报错。因为模块是新建的&am…...

root用户Linux银河麒麟服务器安装vnc服务
安装必要桌面环境组件 yum install mate-session-manager -y mate-session #确定是否安装成功安装vnc服务器 yum install tigervnc-server -y切换到root为root得vnc设置密码 su root vncpasswd给root用户设置vnc服务器文件 vi /etc/systemd/system/vncserver:1.service [Un…...

CentOS 7使用RPM安装MySQL
MySQL是一个开源的关系型数据库管理系统(RDBMS),允许用户高效地存储、管理和检索数据。它被广泛用于各种应用,从小型的web应用到大型企业解决方案。 MySQL提供了丰富的功能,包括支持多个存储引擎、事务能力、数据完整…...

OpenCV imread函数读取图像__实例详解
OpenCV imread函数读取图像__实例详解 本文目录: 零、时光宝盒 一、imread函数定义 二、imread函数支持的文件格式 三、imread函数flags参数详解 (3.1)、Flags-1时,样返回加载的图像(使用alpha通道,否…...

激光线扫相机无2D图像的标定方案
方案一:基于运动控制平台的标定 适用场景:若激光线扫相机安装在可控运动平台(如机械臂、平移台、旋转台)上,且平台的运动精度已知(例如通过编码器或高精度步进电机控制)。 步骤: 标…...

【安当产品应用案例100集】034-安当KSP支持密评中存储数据的机密性和完整性
安当KSP是一套获得国密证书的专业的密钥管理系统。KSP的系统功能扩展图示如下: 我们知道商用密码应用安全性评估中,需要确保存储的数据不被篡改、删除或者破坏,必须采用合适的安全方案来确保存储数据的机密性和完整性。KSP能否满足这个需求呢…...

08.七种排序算法实现(C语言)
目录 一.排序的基本概念 1.1 排序的概念 1.2 常见的排序算法 二.常见排序算法的实现 2.1 插入排序(直接) 1.基本思想 2.直接插入排序的特性 3.代码实现 2.2 希尔排序 1.基本思想 2.希尔插入排序的特性 3.代码实现 2.3 选择排序 1.基本思想 2…...

Alibaba Spring Cloud 一 核心组件、特性
Alibaba Spring Cloud 是 Alibaba 基于 Spring Cloud 的分布式微服务解决方案,提供了一套高性能、高可靠的微服务开发和运维工具。它扩展了 Spring Cloud 的功能,并优化了许多在生产环境中的实践场景,例如服务发现、配置管理、熔断限流等。 …...

kafka学习笔记7 性能测试 —— 筑梦之路
kafka 不同的参数配置对 kafka 性能都会造成影响,通常情况下集群性能受分区、磁盘和线程等影响因素,因此需要进行性能测试,找出集群性能瓶颈和最佳参数。 # 生产者和消费者的性能测试工具 kafka-producer-perf-test.sh kafka-consumer-perf-t…...

HQChart使用教程30-K线图如何对接第3方数据45- DRAWRADAR数据结构
HQChart使用教程30-K线图如何对接第3方数据45- DRAWRADAR数据结构 效果图DRAWRADARHQChart代码地址后台数据对接说明示例数据数据结构说明效果图 DRAWRADAR DRAWRADAR是hqchart插件独有的绘制雷达图函数,可以通过麦语法脚本来绘制一个简单的雷达图数据。 雷达图显示的位置固定…...

Java集合学习:HashMap的原理
一、HashMap里的Hash是什么? 首先,我们先要搞清楚HashMap里的的Hash是啥意思。 当我们在编程过程中,往往需要对线性表进行查找操作。 在顺序表中查找时,需要从表头开始,依次遍历比较a[i]与key的值是否相等ÿ…...

ETLCloud在iPaas中的是关键角色?
在当今的数字化时代,企业越来越依赖于其处理和分析数据的能力。为了实现这一目标,企业需要将各种异构的应用和数据源集成在一起,形成一个统一的数据视图。在这一过程中,ETL(Extract, Transform, Load)和iPa…...

Docker Hub 全面解析及应对策略
在现代 DevOps 和容器化应用开发中,Docker Hub 是一个不可或缺的工具。然而,一些地区或企业对 Docker Hub 的访问受到限制,甚至全面禁止。这种现象引发了开发者和运维人员的广泛关注。那么,为什么 Docker Hub 会被禁用?…...

第五天 Labview数据记录(5.1 INI配置文件读写)
5.1 INI配置文件读写 INI配置文件是一种简单的文本文件,通常用于存储软件的配置信息。它具有以下作用: 存储软件配置参数方便软件的维护和更新提高软件的灵活性和可扩展性便于用户修改和共享配置 5.1.1 前面板 1)新建项目SaveData_Exampl…...

【算法】经典博弈论问题——巴什博弈 python
目录 前言巴什博弈(Bash Game)小试牛刀PN分析实战检验总结 前言 博弈类问题大致分为: 公平组合游戏、非公平组合游戏(绝大多数的棋类游戏)和 反常游戏 巴什博弈(Bash Game) 一共有n颗石子,两个人轮流拿,每次可以拿1~m颗…...

ES6语法
一、Let、const、var变量定义 1.let 声明的变量有严格局部作用域 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&g…...

窥探QCC518x-308x系列与手机之间的蓝牙HCI记录与分析 - 耳机篇
上一篇是介绍如何窥探手机端Bluetooth的HCI log, 本次介绍是如何窥探Bluetooth的HCI log-耳机篇. 这次跟QCC518x/QCC308x测试的手机是Samsung S23 Ultra. QCC518x/QCC308x透过HCI界面取得Log教学. 步骤1: 开启QMDE -> 选择ADK r1102 QCC3083 Headset workspace.步骤2: 点…...

ubuntu k8s 1.31
ubuntu 系统 设置 更新源 apt-get upgradeapt upgradeapt update apt-get update释放root sudo passwd root密码su - 密码设置root可以登录 cd /etc/ssh/sshd_config.d && vi ssh.confPermitRootLogin yes PasswordAuthentication yes:wq 保存退出 systemctl resta…...

Prometheus+grafana实践:Doris数据库的监控
文章来源:乐维社区 Doris数据库背景 Doris(Apache Doris)是一个现代化的MPP(Massive Parallel Processing,大规模并行处理)数据库,主要用于在线分析处理(OLAP)场景。 D…...

【豆包MarsCode蛇年编程大作战】花样贪吃蛇
目录 引言 展示效果 prompt提示信息 第一次提示(实现基本功能) 初次实现效果 第二次提示(美化UI) 第一次美化后的效果 第二次美化后的效果 代码展示 实现在线体验链接 码上掘金使用教程 体验地址: 花样贪吃蛇…...

企业级流程架构设计思路-基于价值链的流程架构
获取更多企业流程资料 纸上得来终觉浅,绝知此事要躬行 一.企业流程分级规则定义 1.流程分类分级的总体原则 2.完整的流程体系需要体现出流程的分类分级 03.通用的流程分级方法 04.流程分级的标准 二.企业流程架构设计原则 1.流程架构设计原则 流程框架是流程体…...

AI编程工具使用技巧:在Visual Studio Code中高效利用阿里云通义灵码
AI编程工具使用技巧:在Visual Studio Code中高效利用阿里云通义灵码 前言一、通义灵码介绍1.1 通义灵码简介1.2 主要功能1.3 版本选择1.4 支持环境 二、Visual Studio Code介绍1.1 VS Code简介1.2 主要特点 三、安装VsCode3.1下载VsCode3.2.安装VsCode3.3 打开VsCod…...

钉钉群机器人设置——python版本
钉钉群机器人设置——python版本 应用场景钉钉界面操作程序开发效果展示 应用场景 由于工作需要,很多项目执行程序后出现报错信息无法第一时间收到,因此实时预警对于监控程序还是有必要。(仅个人观点) 参考文档及博客:…...

细说STM32F407单片机电源低功耗StandbyMode待机模式及应用示例
目录 一、待机模式基础知识 1、进入待机模式 2、待机模式的状态 3、退出待机模式 二、待机模式应用示例 1、示例功能和CubeMX项目设置 (1) 时钟 (2) DEBUG、LED1、KeyRight、USART6、CodeGenerator (3&#x…...

IOS 安全机制拦截 window.open
摘要 在ios环境,在某些情况下执行window.open不生效 一、window.open window.open(url, target, windowFeatures) 1. url:「可选参数」,表示你要加载的资源URL或路径,如果不传,则打开一个url地址为about:blank的空…...