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("邮件发送成功!");}
}

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

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

相关文章

【22】Word:小李-高新技术企业政策❗

目录 题目​ NO1.2 NO3 NO4 NO5.6 NO7.8 NO9.10 若文章中存在删除空白行等要求&#xff0c;可以到最后来完成。注意最后一定要检查此部分&#xff01;注意&#xff1a;大多是和事例一样即可&#xff0c;不用一摸一样&#xff0c;但也不要差太多。 题目 NO1.2 F12Fn&a…

自动化部署(三):项目管理平台

一、项目管理平台作用 帮助团队高效规划、执行和监控项目进度&#xff0c;确保任务按时完成并实现目标 敏捷开发&#xff1a;提供标准敏捷研发管理&#xff0c;支持Scrum 与 Kanban 规模化敏捷&#xff1a;支持大型研发团队跨项目协同&#xff0c;实现多项目路线图规划和资源管…

常用集合-数据结构-MySql

目录 java核心&#xff1a; 常用集合与数据结构: 单例集合: 双列集合: 线程安全的集合: ConcurrentHashMap集合: HashTable集合: CopyOnWriteArrayList集合: CopyOnWriteArraySet集合: ConcurrentLinkedQueue队列: ConcurrentSkipListMap和ConcurrentSkipListSet&…

IP属地与视频定位位置不一致:现象解析与影响探讨

在数字化时代&#xff0c;IP属地和视频定位位置已成为我们获取网络信息、判断内容真实性的重要依据。然而&#xff0c;有时我们会发现&#xff0c;某些视频内容中展示的定位位置与其发布者的IP属地并不一致。这种不一致现象引发了广泛的关注和讨论。本文旨在深入剖析IP属地与视…

计算机毕业设计hadoop+spark股票基金推荐系统 股票基金预测系统 股票基金可视化系统 股票基金数据分析 股票基金大数据 股票基金爬虫

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

机器学习-数据集划分

文章目录 一. 为什么要划分数据集二. 数据集划分的方法1. 留出法&#xff1a;2. 交叉验证&#xff1a;将数据集划分为训练集&#xff0c;验证集&#xff0c;测试集3. 留一法&#xff1a;4. 自助法&#xff1a; 一. 为什么要划分数据集 为了能够评估模型的泛化能力&#xff0c;可…

Vue 拦截监听原理

Vue 渐进式JavaScript 框架 学习笔记 - Vue 拦截监听原理 目录 拦截监听原理 如何跟踪变化 拦截监听示例 观察者 注意:vue3的变化 总结 拦截监听原理 如何跟踪变化 当你把一个普通的Javascript 对象传入 Vue 实例作为data选项&#xff0c;Vue 将遍历此对象所有的proper…

全面评测 DOCA 开发环境下的 DPU:性能表现、机器学习与金融高频交易下的计算能力分析

本文介绍了我在 DOCA 开发环境下对 DPU 进行测评和计算能力测试的一些真实体验和记录。在测评过程中&#xff0c;我主要关注了 DPU 在高并发数据传输和深度学习场景下的表现&#xff0c;以及基本的系统性能指标&#xff0c;包括 CPU 计算、内存带宽、多线程/多进程能力和 I/O 性…

基于JAVA的校园二手商品交易平台的设计与开发

摘 要&#xff1a;政府政策引导与社会观念的转变使得国内大学生的创业意识逐渐提高&#xff0c;很多高校大学生开始自主创业。目前我国各大高校暂且还没有较为成型的针对校内学生创业者的校园网络服务平台。本文首先主要是介绍了关于java语言以及web开发的相关技术&#xff0c;…

HarmonyOS Next 应用UI生成工具介绍

背景 HarmonyOS Next适配开发过程中难买难要参考之前逻辑&#xff0c;但是可能时间较长文档不全&#xff0c;只能参考Android或iOS代码&#xff0c;有些逻辑较重的场景还可以通过AI工具将Android 的Java代码逻辑转成TS完成部分复用。对于一些UI场景只能手动去写&#xff0c;虽…

总结6..

背包问题的解决过程 在解决问题之前&#xff0c;为描述方便&#xff0c;首先定义一些变量&#xff1a;Vi表示第 i 个物品的价值&#xff0c;Wi表示第 i 个物品的体积&#xff0c;定义V(i,j)&#xff1a;当前背包容量 j&#xff0c;前 i 个物品最佳组合对应的价值&#xff0c;同…

【数据结构篇】顺序表 超详细

目录 一.顺序表的定义 1.顺序表的概念及结构 1.1线性表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 二.动态顺序表的实现 1.准备工作和注意事项 2.顺序表的基本接口&#xff1a; 2.0 创建一个顺序表 2.1 顺序表的初始化 2.2 顺序表的销毁 2.3 顺序表的打印 3.顺序…

上位机工作感想-2024年工作总结和来年计划

随着工作年限的增增长&#xff0c;发现自己越来越不喜欢在博客里面写一些掺杂自己感想的东西了&#xff0c;或许是逐渐被工作逼得“成熟”了吧。2024年&#xff0c;学到了很多东西&#xff0c;做了很多项目&#xff0c;也帮别人解决了很多问题&#xff0c;唯独没有涨工资。来这…

阿里云-银行核心系统转型之业务建模与技术建模

业务领域建模包括业务建模和技术建模&#xff0c;整体建模流程图如下&#xff1a; 业务建模包括业务流程建模和业务对象建模 业务流程建模&#xff1a;通过对业务流程现状分析&#xff0c;结合目标核心系统建设能力要求&#xff0c;参考行业建 模成果&#xff0c;形成结构化的…

【C++笔记】红黑树封装map和set深度剖析

【C笔记】红黑树封装map和set深度剖析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】红黑树封装map和set深度剖析前言一. 源码及框架分析1.1 源码框架分析 二. 模拟实现map和set2.1封装map和set 三.迭代器3.1思路…

win32汇编环境,怎么得到磁盘的盘符

;运行效果 ;win32汇编环境,怎么得到磁盘的盘符 ;以下代码主要为了展示一下原理&#xff0c;应用GetLogicalDrives、GetLogicalDriveStrings函数、屏蔽某些二进制位、按双字节复制内容等。以下代码最多查8个盘&#xff0c;即返回值中的1个字节的信息 ;直接抄进RadAsm可编译运行。…

mybatis(19/134)

大致了解了一下工具类&#xff0c;自己手敲了一边&#xff0c;java的封装还是真的省去了很多麻烦&#xff0c;封装成一个工具类就可以不用写很多重复的步骤&#xff0c;一个工厂对应一个数据库一个environment就好了。 mybatis中调用sql中的delete占位符里面需要有字符&#xf…

重学SpringBoot3-WebClient配置与使用详解

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞??收藏评论 重学SpringBoot3-WebClient配置与使用详解 1. 简介2. 环境准备 2.1 依赖配置 3. WebClient配置 3.1 基础配置3.2 高级配置3.3 retrieve()和exchange()区别 4. 使用示例 4.1 基本请求操…

.Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…

深度学习系列75:sql大模型工具vanna

1. 概述 vanna是一个可以将自然语言转为sql的工具。简单的demo如下&#xff1a; !pip install vanna import vanna from vanna.remote import VannaDefault vn VannaDefault(modelchinook, api_keyvanna.get_api_key(my-emailexample.com)) vn.connect_to_sqlite(https://va…