Java导出通过Word模板导出docx文件并通过QQ邮箱发送

一、创建Word模板

java 复制代码
{{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文件夹下

二、编写代码

java 复制代码
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 {
    @Autowired
    private WordTemplateConfig wordTemplateConfig;



    /**
     * 告警服务接口
     */
    @Autowired
    private IAlarmService alarmService;

    @Autowired
    private IMonitorInstanceDao monitorInstanceDao;

    @Autowired
    private IMonitorAlarmRecordDao monitorAlarmRecordDao;

    @Autowired
    private IMonitorDbDao monitorDbDao;

    @Autowired
    private IMonitorTcpDao monitorTcpDao;

    @Autowired
    private IMonitorHttpDao monitorHttpDao;

    @Autowired
    private 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);
    }
    // 将导出的信息填充给word
    private void thisWordInfo(HttpServletResponse response, Integer flag, String Date, Map<String, String> data, String filename) {

        // 查询所有IP
        List<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;
    }

    // 查询所有IP
    private 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模板内

java 复制代码
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() : "");
                    }
                    // 清空原有 runs
                    for (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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

三、发送邮箱

java 复制代码
@RequestMapping("/SendWord")
@RestController
public class SendWordReportController {


    @Autowired
    private EmailSender emailSender;

    @Autowired
    private 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();
        }
    }
   }
  }
java 复制代码
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;


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


    }
}
相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔3 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社4 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖5 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区7 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大8 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai8 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说8 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json