java-企业邮箱批量发送工具

来源:互联网 发布:土耳其修宪 知乎 编辑:程序博客网 时间:2024/06/01 09:08
背景:
由于公司每个月发送薪资邮件工具存在异常,接任务自主开发一个工具。通过读取Excel来发送邮件。内容相对简单,通过两天编码基本实现功能。我想过程分享给大家。
之前工具采用的是163邮箱,但是163邮箱的批量发送会遇到问题,诸如451、530等一系列关于发送多封邮件,或则每天不能超过多少封,端口会被禁止,导致无法继续发送(得到反馈大约每天30-50封左右)。而公司人员往往远远大于这个数,所以采用公司自己的企业邮箱是最安全可靠的。
由于是做web应用的,对于awt与swing的使用有不当的地方,也会继续加强。
企业邮箱批量发送工具 - 饶为 - 饶为的博客
 该功能设计到的编码思路:
1、界面构造(awt,swing)
2、读取excel文件(poi)
3、发送邮件(javamail)
那么界面构造采用最基本的Frame,我上代码:
1、界面构造
Frame f = new Frame("邮件群发工具");
f.setLayout(new GridLayout(5, 2));
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension framesize = f.getSize();
//用于整个框居中
int x = (int) screensize.getWidth() / 2 - 250;
int y = (int) screensize.getHeight() / 2 - 200;
f.setLocation(x, y);

final TextField id = new TextField(20);
final TextField pw = new TextField(20);
pw.setEchoChar('*');
f.add(new Label("邮箱名(xxx@gotop.net.cn):", Label.CENTER));
f.add(id);
f.add(new Label("密码(默认gotop@123):", Label.CENTER));
f.add(pw);
final TextField pwdField = new TextField();
pwdField.setEditable(false);
f.add(pwdField);
Button pwd = new Button("选择文件路径");
f.add(pwd);
Button b1 = new Button("确定");
对b1按钮进行监听

// 确定监听
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {

try {
String aString = pwdField.getText().replace("\\", "/");
//System.out.println(aString+"=====");
Youhua aYouhua = new Youhua();
if (aYouhua.run("xx科技有限公司", id.getText(),pw.getText(), aString)==1) {
JOptionPane.showMessageDialog(null, "发送成功");
}
} catch (Exception e1) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, "账号密码错误或是excel文件下有空白内容或选择的文件不是excel文件");
}

//}
}
});

PS:由于时间赶,工作内容多,我忽律了校验。可以根据自己需要添加相应校验。采用 try ..cach获取到异常使用JoptionPane进行抛出错误提示是最有效的办法。
界面构造中有个文件选择器,这个功能如果选择的是文件,则返回文件的路劲,如果是文件夹,返回文件夹路劲,可以同时使用。(文件夹路劲的作用,我一般拿来读取文件夹内所有文件上传到数据库中。只能用于本机的工具,不能用于上传服务器的数据库
企业邮箱批量发送工具 - 饶为 - 饶为的博客
 

// 选择文件监听
pwd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 打开文件夹选择器
JFileChooser jfc = new JFileChooser();
jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
jfc.showDialog(new JLabel(), "选择");
File file = jfc.getSelectedFile();
if (file.isDirectory()) {
System.out.println("文件夹:" + file.getAbsolutePath());
} else if (file.isFile()) {
System.out.println("文件:" + file.getAbsolutePath());
// 将文件路径显示在text中
pwdField.setText(file.getAbsolutePath());
}
System.out.println(jfc.getSelectedFile().getName());
}
});

退出

// 退出监听
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});

System.exit(0); 是最基本的关闭窗口方法。不要采用setVisibled这个是隐藏,会导致进程仍在。

2、读取Excel
采用POI 3.7版本。

FileInputStream fileInputStream = new FileInputStream("C:/Users/Administrator/Desktop/工资明细邮件发送工具/邮件发送工具/2017年1月份工资明细发放.xls");
POIFSFileSystem fs =new POIFSFileSystem(fileInputStream);
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);

HSSFCellStyle textStyle = wb.createCellStyle();
HSSFDataFormat format = wb.createDataFormat();
textStyle.setDataFormat(format.getFormat("@"));//设置单元格格式为"文本"

StringBuffer tableheader = new StringBuffer();

//文件的行数
int rows = sheet.getPhysicalNumberOfRows();

HSSFCell cell = null;//临时存放cell

//获取总列数
int columnNum=sheet.getRow(0).getPhysicalNumberOfCells();

for( int i = 1;i < rows; i++){
HSSFRow row = sheet.getRow(i);
StringBuffer theMessage = new StringBuffer();
//如果整行为空,跳过
if(row == null){
continue;
}
//第1列 客户姓名
theMessage.append("<tr>");
for (int j = 0; j < (columnNum-1); j++) {
cell = row.getCell(j);
if (cell!=null) {
tempString = getCellValue(cell).trim();
theMessage.append("<td>"+tempString+"</td>");
}
}
theMessage.append("</tr>");
//获取邮箱信息
cell = row.getCell((columnNum-1));

//发送邮件

sendEmail(getCellValue(cell).trim(),"邮件测试","<table border=2>"+tableheader.toString()+theMessage.toString()+"</table>");//收件人

这里采用获取总列数的办法,进行嵌套循环,可以使得邮件内容列数增长。那么最后一列是邮箱地址。样式如下:
企业邮箱批量发送工具 - 饶为 - 饶为的博客

 3、发送邮件
发送邮件有两个要求,一个就是要知道自己邮箱的smtp服务器地址和端口,另一个就是要得到许可。
第一个可以百度下,smtp服务器与端口 作为Keyword。第二个只需要在邮箱上做设置。但又如前面所说,如果不是自己公司的企业邮箱,那么发送的邮件是有限定的。我上代码:

//端口号

static int port = 25;
//公司的服务器端口号 或则 其他的。
static String server = "smtp.qq.com";//邮件服务器mail.cpip.net.cn

static String from = "饶为";//发送者,显示的发件人名字

static String user = "1973267302@qq.com";//发送者邮箱地址

static String password = "";//密码


public static void sendEmail(String email, String subject, String body) throws UnsupportedEncodingException {
try {
Properties props = new Properties();
props.put("mail.smtp.host", server);
props.put("mail.smtp.port", String.valueOf(port));
props.put("mail.smtp.auth", "true");
Transport transport = null;
Session session = Session.getDefaultInstance(props, null);
transport = session.getTransport("smtp");
transport.connect(server, user, password);
MimeMessage msg = new MimeMessage(session);
msg.setSentDate(new Date());
//设置后出现html格式,有了这个设置才能使用html格式。
msg.setContent(body, "text/html;charset=gb2312");

InternetAddress fromAddress = new InternetAddress(user,from,"UTF-8");
msg.setFrom(fromAddress);
InternetAddress[] toAddress = new InternetAddress[1];
toAddress[0] = new InternetAddress(email);
msg.setRecipients(Message.RecipientType.TO, toAddress);
msg.setSubject(subject, "UTF-8");
// msg.setText(body, "UTF-8");
msg.saveChanges();
transport.sendMessage(msg, msg.getAllRecipients());
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}

我提供的核心代码,完全可以发送信息,那么如果真的使用,建议把邮箱开关先打开,再里面做循环。而不要写死这个邮箱方法,不然对于运行效率会很慢。这个开销问题需要自己去研究下,要注意的是msg.setContent(body, "text/html;charset=gb2312");如果邮件要有html格式要记得加这个,比如字体颜色,表格方框什么的。

经过测试,200封邮件1秒内能全部发送完毕。
企业邮箱批量发送工具 - 饶为 - 饶为的博客
 

1 0
原创粉丝点击