引入
接觸數(shù)據(jù)庫(kù)的時(shí)候钝荡,有時(shí)候需要將其中的一些數(shù)據(jù)導(dǎo)出來(lái)羊初,生成Excel文件存檔蠢挡;有時(shí)候又需要將這Excel文件通過(guò)郵件的方式發(fā)送到指定的郵箱去。那么凳忙,這些需求业踏,都該如何實(shí)現(xiàn)呢?
知識(shí)點(diǎn)歸納(方法步驟)
1.數(shù)據(jù)庫(kù)設(shè)計(jì)涧卵、連接
關(guān)于數(shù)據(jù)庫(kù)的設(shè)計(jì)和如何連接勤家,在上一篇實(shí)踐記錄【實(shí)踐記錄】Java操作MySQL數(shù)據(jù)庫(kù)——不定條件參數(shù)查詢中已經(jīng)有了必要的敘述,這里就不再重復(fù)柳恐,就以這個(gè)數(shù)據(jù)庫(kù)為基礎(chǔ)伐脖,進(jìn)行進(jìn)一步功能的實(shí)現(xiàn)。
2.通過(guò)POI生成Excel文件
要點(diǎn):
(1)什么是POI:
Apache POI是Apache軟件基金會(huì)的開放源碼函式庫(kù)乐设,POI提供API給Java程序?qū)icrosoft Office格式檔案讀和寫的功能讼庇。
(2)需要POI的JAR包:本人用的是poi-3.14-20160307,可去Apache的網(wǎng)站上下載Apache POI
(3)先初始化整份Excel工作薄workbook近尚,再獲得表sheet蠕啄,再?gòu)闹蝎@得行row,才能獲得單元格cell。根據(jù)實(shí)際情況使用循環(huán)歼跟。
(4)數(shù)據(jù)對(duì)應(yīng)關(guān)系:POI類從0開始的和媳,例如Excel的1行對(duì)應(yīng)POI類的0行。
(5)代碼實(shí)現(xiàn):
從數(shù)據(jù)庫(kù)中獲取需要導(dǎo)出的對(duì)象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{
//獲取數(shù)據(jù)庫(kù)連接
Connection conn = DBUtil.getConnection();
List<Users> usersList = new ArrayList<Users>();
String sql = "select * from users";
//執(zhí)行SQL語(yǔ)句
PreparedStatement ps =conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
//提取查詢結(jié)果
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{
//初始一個(gè)workbook
HSSFWorkbook workbook = new HSSFWorkbook();
List<Users> usersList = UsersDAO.getList();
//創(chuàng)建單個(gè)sheet
HSSFSheet sheet = workbook.createSheet("sheet0");
//創(chuàng)建多行
//創(chuàng)建第一行哈街,設(shè)置列名
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("個(gè)人簡(jiǎn)介");
break;
case 3:
cell.setCellValue("關(guān)注人數(shù)");
break;
case 4:
cell.setCellValue("粉絲數(shù)");
break;
case 5:
cell.setCellValue("文章數(shù)");
break;
case 6:
cell.setCellValue("字?jǐn)?shù)");
break;
case 7:
cell.setCellValue("收獲喜歡數(shù)");
break;
}
}
//創(chuàng)建剩余行
for(int rowIndex = 1;rowIndex <= usersList.size();rowIndex++){
HSSFRow row = sheet.createRow(rowIndex);
Users user = usersList.get(rowIndex-1);
//創(chuàng)建多列
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();
}
}
}
調(diào)用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.通過(guò)JavaMail發(fā)送郵件
要點(diǎn):
(1)JavaMail是由Sun定義的一套收發(fā)電子郵件的API留瞳。
(2)必要JAR包:本人用的是javax.mail-1.5.6,下載地址:Java Mail API
(3)郵件傳輸協(xié)議有很多種骚秦,這里使用smtp簡(jiǎn)單郵件傳輸協(xié)議
(4)連接郵件服務(wù)器的時(shí)候得注意她倘,方法trans.connect("smtp.163.com", "xxxxxxxx", "xxxxxxxx");第一個(gè)參數(shù)是郵件服務(wù)器;第二個(gè)參數(shù)是163郵箱賬號(hào)作箍,這個(gè)賬號(hào)是不帶域名的硬梁,即沒有@163.com后綴的;第三個(gè)參數(shù)就是密碼蒙揣。
(5)發(fā)件郵箱歸屬要與郵件服務(wù)器歸屬一致靶溜,例如我用163郵箱發(fā)郵件开瞭,那指定的郵件服務(wù)器就為smtp.163.com懒震。發(fā)件郵箱就可以隨意。
(6)代碼實(shí)現(xiàn):
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 {
/*
* 發(fā)送郵件到指定郵箱
*/
public static void send(String fromAddress,String toAddress) throws Exception{
/*
* 第一步:創(chuàng)建Session嗤详,包含郵件服務(wù)器網(wǎng)絡(luò)連接信息
*/
Properties props = new Properties();
//指定郵件的傳輸協(xié)議个扰,smtp;同時(shí)通過(guò)驗(yàn)證
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.auth","true");
Session session = Session.getDefaultInstance(props);
//開啟調(diào)試模式
session.setDebug(true);
/*
* 第二步:編輯郵件內(nèi)容
*/
Message message = new MimeMessage(session);
//設(shè)置郵件消息頭
message.setFrom(new InternetAddress(fromAddress));
message.setRecipients(RecipientType.TO, InternetAddress.parse(toAddress));
message.setSubject("JavaMail郵件測(cè)試");
//設(shè)置郵件消息內(nèi)容、包含附件
Multipart msgPart = new MimeMultipart();
message.setContent(msgPart);
MimeBodyPart body = new MimeBodyPart(); //正文
MimeBodyPart attach = new MimeBodyPart(); //附件
msgPart.addBodyPart(body);
msgPart.addBodyPart(attach);
//設(shè)置正文內(nèi)容
body.setContent("JavaMail功能測(cè)試", "text/html;charset=utf-8");
//設(shè)置附件內(nèi)容
attach.setDataHandler(new DataHandler(new FileDataSource("E:\\jianshu.xls")));
attach.setFileName("簡(jiǎn)書用戶數(shù)據(jù).xls");
message.saveChanges();
/*
* 第三步:發(fā)送郵件
*/
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");
}
}
注意事項(xiàng)
1.這次實(shí)踐生成Excel的操作其實(shí)只是POI的冰山一角葱色,還可以利用POI對(duì)Excel文檔進(jìn)行各種常用操作递宅,但不在本次實(shí)踐范圍內(nèi),所以不做拓展苍狰,有時(shí)間再去深入了解办龄。
2.郵件傳輸概念也很復(fù)雜,深入的話也得花很多時(shí)間淋昭。JavaMail只是一套開放的API俐填,輔助我們進(jìn)行郵件傳輸?shù)南嚓P(guān)開發(fā)而已。而且翔忽,用到郵件服務(wù)器英融,就會(huì)受到郵件服務(wù)器的很多限制,例如本次實(shí)踐過(guò)程中發(fā)送的測(cè)試郵件就多次被163誤判為垃圾郵件(出錯(cuò)會(huì)有錯(cuò)誤代碼歇式,去163退信規(guī)則里面看)驶悟。可能是沒有遵循163的發(fā)信規(guī)則吧材失,后來(lái)調(diào)了很久痕鳍,最終改了編輯郵件內(nèi)容的代碼才正常發(fā)送郵件。貌似也可以自己搭郵件服務(wù)器龙巨,不過(guò)還沒有接觸额获,有興趣可以多去Google
相關(guān)參考
POI操作Excel常用方法總結(jié)
超詳細(xì)POI實(shí)例:Java開發(fā)MS Excel
POI導(dǎo)出EXCEL經(jīng)典實(shí)現(xiàn)
Java郵件開發(fā)(二):使用JMail發(fā)送一封圖文并茂且包含附件的郵件(下)
JavaMail發(fā)送和接收郵件(JavaMailAPI說(shuō)明)