设为首页收藏本站
查看: 143|回复: 0

[高级语言] [Java]《批量邮件发送》

[复制链接]
  • TA的每日心情
    奋斗
    5 小时前
  • 签到天数: 1063 天

    [LV.10]以坛为家III

    发表于 2026-3-5 17:47:47 | 显示全部楼层 |阅读模式
    1. package com.example.demo;

    2. import javafx.application.Application;
    3. import javafx.geometry.Insets;
    4. import javafx.scene.Scene;
    5. import javafx.scene.control.*;
    6. import javafx.scene.layout.GridPane;
    7. import javafx.stage.FileChooser;
    8. import javafx.stage.Stage;
    9. import org.apache.poi.ss.usermodel.*;
    10. import org.apache.poi.ss.usermodel.Cell;
    11. import org.apache.poi.xssf.usermodel.XSSFWorkbook;

    12. import jakarta.mail.*;
    13. import jakarta.mail.internet.InternetAddress;
    14. import jakarta.mail.internet.MimeMessage;

    15. import java.io.File;
    16. import java.io.FileInputStream;
    17. import java.util.ArrayList;
    18. import java.util.List;
    19. import java.util.Properties;

    20. public class HelloApplication extends Application {

    21.     private File excelFile;

    22.     public static class Recipient {
    23.         public String email;
    24.         public String name;

    25.         public Recipient(String email, String name) {
    26.             this.email = email;
    27.             this.name = name;
    28.         }
    29.     }

    30.     @Override
    31.     public void start(Stage primaryStage) {
    32.         primaryStage.setTitle("Excel 批量发邮件");

    33.         // SMTP 配置
    34.         TextField hostField = new TextField("smtp.example.com");
    35.         TextField portField = new TextField("465");
    36.         CheckBox sslCheck = new CheckBox("SSL");
    37.         sslCheck.setSelected(true);
    38.         CheckBox tlsCheck = new CheckBox("TLS"); // 一般只用一个,示例都给出

    39.         TextField fromField = new TextField("your_email@example.com");
    40.         PasswordField passwordField = new PasswordField();

    41.         // 邮件内容
    42.         TextField subjectField = new TextField("测试邮件主题");
    43.         TextArea bodyArea = new TextArea("您好,${name},这是一封测试邮件。");

    44.         // Excel 选择
    45.         Label excelLabel = new Label("未选择文件");
    46.         Button chooseExcelBtn = new Button("选择 Excel");
    47.         chooseExcelBtn.setOnAction(e -> {
    48.             FileChooser fileChooser = new FileChooser();
    49.             fileChooser.getExtensionFilters().add(
    50.                     new FileChooser.ExtensionFilter("Excel 文件", "*.xlsx", "*.xls")
    51.             );
    52.             File file = fileChooser.showOpenDialog(primaryStage);
    53.             if (file != null) {
    54.                 excelFile = file;
    55.                 excelLabel.setText(file.getName());
    56.             }
    57.         });

    58.         Button sendBtn = new Button("发送");
    59.         TextArea logArea = new TextArea();
    60.         logArea.setEditable(false);

    61.         sendBtn.setOnAction(e -> {
    62.             if (excelFile == null) {
    63. //                showAlert("错误", "请先选择 Excel 文件");
    64.                 return;
    65.             }
    66.             String host = hostField.getText().trim();
    67.             String port = portField.getText().trim();
    68.             String from = fromField.getText().trim();
    69.             String password = passwordField.getText();
    70.             String subject = subjectField.getText().trim();
    71.             String bodyTemplate = bodyArea.getText();

    72.             new Thread(() -> {
    73.                 try {
    74.                     List<Recipient> recipients = readRecipientsFromExcel(excelFile);
    75.                     logArea.appendText("共读取到 " + recipients.size() + " 个收件人\n");

    76.                     Session session = createMailSession(host, port, from, password,
    77.                             sslCheck.isSelected(), tlsCheck.isSelected());

    78.                     for (Recipient r : recipients) {
    79.                         String body = bodyTemplate.replace("${name}",
    80.                                 r.name != null ? r.name : "");
    81.                         try {
    82.                             sendEmail(session, from, r.email, subject, body);
    83.                             appendLog(logArea, "发送成功:" + r.email);
    84.                         } catch (Exception ex) {
    85.                             appendLog(logArea, "发送失败:" + r.email + ",错误:" + ex.getMessage());
    86.                         }
    87.                     }
    88.                 } catch (Exception ex) {
    89.                     appendLog(logArea, "总体错误:" + ex.getMessage());
    90.                 }
    91.             }).start();
    92.         });

    93.         // 布局
    94.         GridPane grid = new GridPane();
    95.         grid.setPadding(new Insets(10));
    96.         grid.setHgap(8);
    97.         grid.setVgap(8);

    98.         int row = 0;
    99.         grid.add(new Label("SMTP 主机:"), 0, row);
    100.         grid.add(hostField, 1, row++);

    101.         grid.add(new Label("端口:"), 0, row);
    102.         grid.add(portField, 1, row++);

    103.         grid.add(sslCheck, 0, row);
    104.         grid.add(tlsCheck, 1, row++);

    105.         grid.add(new Label("发件邮箱:"), 0, row);
    106.         grid.add(fromField, 1, row++);

    107.         grid.add(new Label("密码/授权码:"), 0, row);
    108.         grid.add(passwordField, 1, row++);

    109.         grid.add(new Label("主题:"), 0, row);
    110.         grid.add(subjectField, 1, row++);

    111.         grid.add(new Label("正文模板:"), 0, row);
    112.         grid.add(bodyArea, 1, row++);

    113.         grid.add(new Label("Excel 文件:"), 0, row);
    114.         grid.add(excelLabel, 1, row++);
    115.         grid.add(chooseExcelBtn, 1, row++);

    116.         grid.add(sendBtn, 1, row++);

    117.         grid.add(new Label("日志:"), 0, row);
    118.         grid.add(logArea, 1, row++);

    119.         primaryStage.setScene(new Scene(grid, 700, 600));
    120.         primaryStage.show();
    121.     }

    122.     private void appendLog(TextArea logArea, String text) {
    123.         javafx.application.Platform.runLater(() -> {
    124.             logArea.appendText(text + "\n");
    125.         });
    126.     }

    127.     /**
    128.      * 创建邮件 Session,支持 SSL / TLS
    129.      */
    130.     private Session createMailSession(String host,
    131.                                       String port,
    132.                                       String username,
    133.                                       String password,
    134.                                       boolean useSSL,
    135.                                       boolean useTLS) {
    136.         Properties props = new Properties();
    137.         props.put("mail.smtp.auth", "true");
    138.         props.put("mail.smtp.host", host);
    139.         props.put("mail.smtp.port", port);

    140.         if (useSSL) {
    141.             // SSL 通道(常见 465 端口)
    142.             props.put("mail.smtp.ssl.enable", "true");
    143.         }

    144.         if (useTLS) {
    145.             // TLS/STARTTLS(常见 587 端口)
    146.             props.put("mail.smtp.starttls.enable", "true");
    147.         }

    148.         return Session.getInstance(props, new Authenticator() {
    149.             @Override
    150.             protected PasswordAuthentication getPasswordAuthentication() {
    151.                 return new PasswordAuthentication(username, password);
    152.             }
    153.         });
    154.     }

    155.     /**
    156.      * 发送单封邮件
    157.      */
    158.     private void sendEmail(Session session,
    159.                            String from,
    160.                            String to,
    161.                            String subject,
    162.                            String body) throws Exception {
    163.         Message message = new MimeMessage(session);
    164.         message.setFrom(new InternetAddress(from));
    165.         message.setRecipients(Message.RecipientType.TO,
    166.                 InternetAddress.parse(to));
    167.         message.setSubject(subject);
    168.         message.setContent(body, "text/html;charset=UTF-8");
    169. //        message.setText(body); // 如需 HTML 可改为 setContent(body, "text/html;charset=UTF-8");
    170.         Transport.send(message);
    171.     }

    172.     /**
    173.      * 从 Excel 读取收件人列表
    174.      * 默认:第一行为表头,A列= email, B列= name
    175.      */
    176.     private List<Recipient> readRecipientsFromExcel(File file) throws Exception {
    177.         List<Recipient> list = new ArrayList<>();
    178.         try (FileInputStream fis = new FileInputStream(file);
    179.              Workbook workbook = new XSSFWorkbook(fis)) {

    180.             Sheet sheet = workbook.getSheetAt(0);
    181.             boolean isFirstRow = true;

    182.             for (Row row : sheet) {
    183.                 if (isFirstRow) {
    184.                     isFirstRow = false; // 跳过表头
    185.                     continue;
    186.                 }
    187.                 if (row == null) continue;

    188.                 Cell emailCell = row.getCell(0);
    189.                 if (emailCell == null) continue;

    190.                 String email = emailCell.toString().trim();
    191.                 if (email.isEmpty()) continue;

    192.                 String name = null;
    193.                 Cell nameCell = row.getCell(1);
    194.                 if (nameCell != null) {
    195.                     name = nameCell.toString().trim();
    196.                 }

    197.                 list.add(new Recipient(email, name));
    198.             }
    199.         }
    200.         return list;
    201.     }

    202.     public static void main(String[] args) {
    203.         launch(args);
    204.     }
    205. }
    复制代码


    打包exe
    1. cmd.exe /X /C "C:\Users\YTZS-D1\.jdks\corretto-18.0.2\bin\jpackage.exe --name EmailSender --dest C:\Users\YTZS-D1\Desktop\test\demo\target --app-version 1.0 --input C:\Users\YTZS-D1\Desktop\test\demo\target --main-class com.example.demo.Launcher --main-jar demo-1.0-SNAPSHOT.jar --win-dir-chooser --win-menu --win-shortcut"
    复制代码

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    红盟社区--红客联盟 

    Processed in 0.060985 second(s), 23 queries.

    站点统计| 举报| Archiver| 手机版| 黑屋 |   

    备案号:冀ICP备20006029号-1 Powered by HUC © 2001-2021 Comsenz Inc.

    手机扫我进入移动触屏客户端

    关注我们可获取更多热点资讯

    Honor accompaniments. theme macfee

    快速回复 返回顶部 返回列表