引入
接触数据库的时候,有时候需要将其中的一些数据导出来,生成Excel文件存档;有时候又需要将这Excel文件通过邮件的方式发送到指定的邮箱去。那么,这些需求,都该如何实现呢?
知识点归纳(方法步骤)
1.数据库设计、连接
关于数据库的设计和如何连接,在上一篇实践记录【实践记录】Java操作MySQL数据库——不定条件参数查询中已经有了必要的叙述,这里就不再重复,就以这个数据库为基础,进行进一步功能的实现。
2.通过POI生成Excel文件
要点:
(1)什么是POI:
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
(2)需要POI的JAR包:本人用的是poi-3.14-20160307,可去Apache的网站上下载Apache POI
(3)先初始化整份Excel工作薄workbook,再获得表sheet,再从中获得行row,才能获得单元格cell。根据实际情况使用循环。
(4)数据对应关系:POI类从0开始的,例如Excel的1行对应POI类的0行。
(5)代码实现:
从数据库中获取需要导出的对象user的集合usersList
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import demo.pojo.Users;
import util.DBUtil;
public class UsersDAO {
public static List<Users> getList() throws SQLException{
//获取数据库连接
Connection conn = DBUtil.getConnection();
List<Users> usersList = new ArrayList<Users>();
String sql = "select * from users";
//执行SQL语句
PreparedStatement ps =conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
//提取查询结果
Users user = null;
while(rs.next()){
user = new Users();
user.setId(rs.getInt("u_id"));
user.setName(rs.getString("u_name"));
user.setIntroduce(rs.getString("u_introduce"));
user.setFocusNum(rs.getLong("u_num_focus"));
user.setFansNum(rs.getLong("u_num_fans"));
user.setArticlesNum(rs.getLong("u_num_ariticles"));
user.setWordsNum(rs.getLong("u_num_words"));
user.setLikeNum(rs.getLong("u_num_like"));
usersList.add(user);
}
return usersList;
}
}
编写生成Excel文件的方法write
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import demo.dao.UsersDAO;
import demo.pojo.Users;
public class WriteExcel {
public static void write(OutputStream outputStream) throws SQLException{
//初始一个workbook
HSSFWorkbook workbook = new HSSFWorkbook();
List<Users> usersList = UsersDAO.getList();
//创建单个sheet
HSSFSheet sheet = workbook.createSheet("sheet0");
//创建多行
//创建第一行,设置列名
HSSFRow row0 = sheet.createRow(0);
for(int cellIndex = 0;cellIndex < 8;cellIndex++){
HSSFCell cell = row0.createCell(cellIndex);
switch(cellIndex){
case 0:
cell.setCellValue("ID");
break;
case 1:
cell.setCellValue("姓名");
break;
case 2:
cell.setCellValue("个人简介");
break;
case 3:
cell.setCellValue("关注人数");
break;
case 4:
cell.setCellValue("粉丝数");
break;
case 5:
cell.setCellValue("文章数");
break;
case 6:
cell.setCellValue("字数");
break;
case 7:
cell.setCellValue("收获喜欢数");
break;
}
}
//创建剩余行
for(int rowIndex = 1;rowIndex <= usersList.size();rowIndex++){
HSSFRow row = sheet.createRow(rowIndex);
Users user = usersList.get(rowIndex-1);
//创建多列
for(int cellIndex = 0;cellIndex < 8;cellIndex++){
HSSFCell cell = row.createCell(cellIndex);
switch(cellIndex){
case 0:
cell.setCellValue(user.getId());
break;
case 1:
cell.setCellValue(user.getName());
break;
case 2:
cell.setCellValue(user.getIntroduce());
break;
case 3:
cell.setCellValue(user.getFocusNum());
break;
case 4:
cell.setCellValue(user.getFansNum());
break;
case 5:
cell.setCellValue(user.getArticlesNum());
break;
case 6:
cell.setCellValue(user.getWordsNum());
break;
case 7:
cell.setCellValue(user.getLikeNum());
break;
}
}
}
try {
workbook.write(outputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
调用write方法生成Excel文件
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import util.WriteExcel;
public class POI_Test {
public static void main(String[] args) {
OutputStream out = null;
try {
out = new FileOutputStream(new File("E:\\jianshu.xls"));
WriteExcel.write(out);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
if(out !=null){
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
生成的Excel文件如图:
3.通过JavaMail发送邮件
要点:
(1)JavaMail是由Sun定义的一套收发电子邮件的API。
(2)必要JAR包:本人用的是javax.mail-1.5.6,下载地址:Java Mail API
(3)邮件传输协议有很多种,这里使用smtp简单邮件传输协议
(4)连接邮件服务器的时候得注意,方法trans.connect("smtp.163.com", "xxxxxxxx", "xxxxxxxx");第一个参数是邮件服务器;第二个参数是163邮箱账号,这个账号是不带域名的,即没有@163.com后缀的;第三个参数就是密码。
(5)发件邮箱归属要与邮件服务器归属一致,例如我用163邮箱发邮件,那指定的邮件服务器就为smtp.163.com。发件邮箱就可以随意。
(6)代码实现:
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class SendMailUtil {
/*
* 发送邮件到指定邮箱
*/
public static void send(String fromAddress,String toAddress) throws Exception{
/*
* 第一步:创建Session,包含邮件服务器网络连接信息
*/
Properties props = new Properties();
//指定邮件的传输协议,smtp;同时通过验证
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.auth","true");
Session session = Session.getDefaultInstance(props);
//开启调试模式
session.setDebug(true);
/*
* 第二步:编辑邮件内容
*/
Message message = new MimeMessage(session);
//设置邮件消息头
message.setFrom(new InternetAddress(fromAddress));
message.setRecipients(RecipientType.TO, InternetAddress.parse(toAddress));
message.setSubject("JavaMail邮件测试");
//设置邮件消息内容、包含附件
Multipart msgPart = new MimeMultipart();
message.setContent(msgPart);
MimeBodyPart body = new MimeBodyPart(); //正文
MimeBodyPart attach = new MimeBodyPart(); //附件
msgPart.addBodyPart(body);
msgPart.addBodyPart(attach);
//设置正文内容
body.setContent("JavaMail功能测试", "text/html;charset=utf-8");
//设置附件内容
attach.setDataHandler(new DataHandler(new FileDataSource("E:\\jianshu.xls")));
attach.setFileName("简书用户数据.xls");
message.saveChanges();
/*
* 第三步:发送邮件
*/
Transport trans = session.getTransport();
trans.connect("smtp.163.com", "xxxxxxxx", "xxxxxxxx");
trans.sendMessage(message, message.getAllRecipients());
}
public static void main(String[] args) throws Exception {
SendMailUtil.send("xxxxxxx@163.com","xxxxxxx@163.com");
}
}
注意事项
1.这次实践生成Excel的操作其实只是POI的冰山一角,还可以利用POI对Excel文档进行各种常用操作,但不在本次实践范围内,所以不做拓展,有时间再去深入了解。
2.邮件传输概念也很复杂,深入的话也得花很多时间。JavaMail只是一套开放的API,辅助我们进行邮件传输的相关开发而已。而且,用到邮件服务器,就会受到邮件服务器的很多限制,例如本次实践过程中发送的测试邮件就多次被163误判为垃圾邮件(出错会有错误代码,去163退信规则里面看)。可能是没有遵循163的发信规则吧,后来调了很久,最终改了编辑邮件内容的代码才正常发送邮件。貌似也可以自己搭邮件服务器,不过还没有接触,有兴趣可以多去Google
相关参考
POI操作Excel常用方法总结
超详细POI实例:Java开发MS Excel
POI导出EXCEL经典实现
Java邮件开发(二):使用JMail发送一封图文并茂且包含附件的邮件(下)
JavaMail发送和接收邮件(JavaMailAPI说明)