【實(shí)踐記錄】數(shù)據(jù)庫(kù)數(shù)據(jù)通過(guò)POI生成Excel,并用JavaMail將此文件發(fā)送到指定郵箱


引入

接觸數(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)。

數(shù)據(jù)庫(kù)示例.png

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)歼跟。

Excel對(duì)象與POI類對(duì)應(yīng)關(guān)系.png

(4)數(shù)據(jù)對(duì)應(yīng)關(guān)系:POI類從0開始的和媳,例如Excel的1行對(duì)應(yīng)POI類的0行。

數(shù)據(jù)對(duì)應(yīng)關(guān)系.png

(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文件如圖:


Excel示例.png
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ō)明)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末够庙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抄邀,更是在濱河造成了極大的恐慌耘眨,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件境肾,死亡現(xiàn)場(chǎng)離奇詭異剔难,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)奥喻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門偶宫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人环鲤,你說(shuō)我怎么就攤上這事纯趋。” “怎么了冷离?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵吵冒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我西剥,道長(zhǎng)痹栖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任瞭空,我火速辦了婚禮揪阿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咆畏。我一直安慰自己南捂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布旧找。 她就那樣靜靜地躺著溺健,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钦讳。 梳的紋絲不亂的頭發(fā)上矿瘦,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音愿卒,去河邊找鬼缚去。 笑死,一個(gè)胖子當(dāng)著我的面吹牛琼开,可吹牛的內(nèi)容都是我干的易结。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼搞动!你這毒婦竟也來(lái)了躏精?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鹦肿,失蹤者是張志新(化名)和其女友劉穎矗烛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箩溃,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞭吃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涣旨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歪架。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖霹陡,靈堂內(nèi)的尸體忽然破棺而出和蚪,到底是詐尸還是另有隱情,我是刑警寧澤烹棉,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布攒霹,位于F島的核電站,受9級(jí)特大地震影響峦耘,放射性物質(zhì)發(fā)生泄漏剔蹋。R本人自食惡果不足惜旅薄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一辅髓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧少梁,春花似錦洛口、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至妨马,卻和暖如春挺举,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烘跺。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工湘纵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滤淳。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓梧喷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子铺敌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容