Java實(shí)現(xiàn)瀏覽器下載功能

前言:

最近有給分配一個(gè)任務(wù)踢故,實(shí)現(xiàn)一個(gè)下載功能文黎,前提是當(dāng)在指定的目錄下去查找固定名字的文件,如果存在則直接讀取文件流在返回給瀏覽器殿较,如果沒有才去執(zhí)行數(shù)據(jù)庫去查耸峭,然后備份并輸出到瀏覽器進(jìn)行下載.

就這其中一個(gè)簡(jiǎn)單的功能,下面對(duì)這個(gè)部分進(jìn)行實(shí)現(xiàn)淋纲。

JSP頁面:

JSP代碼:

<c:if test="${page.list != null && fn:length(page.list) > 0}">
    <c:forEach var="run" items="${page.list}" varStatus="st">
        <tr>
            <td style="text-align: center">${run.between}</td>
            <td style="text-align: center">${run.typeNo}</td>
            <td style="text-align: center">${run.status}</td>
            <td style="text-align: center">${run.recall}</td>
            <td style="text-align: center">${run.precision}</td>
            <td style="text-align: center">${run.kind}</td>
            <td class="td-manage" style="text-align: center">
                <a title="下載" href="/CategoryTestRunData/downLoad?id=${run.id}">
                    <i class="layui-icon layui-icon-download-circle"></i>
                </a>
            </td>
        </tr>
    </c:forEach>
</c:if>

說明:<font color=red>在測(cè)試的時(shí)候發(fā)現(xiàn)下載這里如果寫Ajax異步請(qǐng)求下載話這個(gè)是無法請(qǐng)求的劳闹,所以這里寫直鏈。</font>

控制器:

控制層代碼:

    /**
     * Excel表下載導(dǎo)出
     * @return
     */
    @ResponseBody
    @RequestMapping("/downLoad")
    public void downLoad(String id, HttpServletResponse response, HttpServletRequest request) throws IOException {
        log.info("Excel表下載導(dǎo)出洽瞬,傳入?yún)?shù):"+id);
        //目標(biāo)路徑
        String dist = "/data/download/";
        //String dist = "F:/operate/download/";
        File fileList = new File(dist);
        if (!fileList.exists()){
            fileList.mkdirs();
        }
        //判斷是否存在ID為名的文件
        String[] list = fileList.list();
        boolean isExist = true;  //默認(rèn)該文件存在標(biāo)志
        for (String name_id : list) {
            String sub_name = StringUtils.substring(name_id,0,name_id.lastIndexOf("."));
            if (StringUtils.equals(sub_name,id)){
                //存在預(yù)下載文件
                //獲取輸入流輸出到瀏覽器
                FileInputStream fileInputStream = new FileInputStream(dist+name_id);
                OutputStream outputStream = response.getOutputStream();
                //設(shè)置Http響應(yīng)頭告訴瀏覽器下載這個(gè)附件,下載的文件名也是在這里設(shè)置的
                //獲得瀏覽器代理信息
                final String userAgent = request.getHeader("USER-AGENT");
                //判斷瀏覽器代理并分別設(shè)置響應(yīng)給瀏覽器的編碼格式
                String finalFileName = null;
                if(StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent,"Trident")){//IE瀏覽器
                    finalFileName = URLEncoder.encode(name_id,"UTF8");
                    System.out.println("IE瀏覽器");
                }else if(StringUtils.contains(userAgent, "Mozilla")){//google,火狐瀏覽器
                    finalFileName = new String(name_id.getBytes(), "ISO8859-1");
                }else{
                    finalFileName = URLEncoder.encode(name_id,"UTF8");//其他瀏覽器
                }
                //設(shè)置HTTP響應(yīng)頭
                response.reset();//重置 響應(yīng)頭
                response.setContentType("application/x-download");//告知瀏覽器下載文件本涕,而不是直接打開,瀏覽器默認(rèn)為打開
                response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName+ "");//下載文件的名稱
                byte[] bytes = new byte[2048];
                int len = 0;
                while ((len = fileInputStream.read(bytes))>0){
                    outputStream.write(bytes,0,len);
                }
                fileInputStream.close();
                outputStream.close();
                return ;
            }
        }
        isExist = false;
        if (!isExist){
            try{
                //輸出寫入到服務(wù)器備份
                ExcelWriter writer = ExcelUtil.getWriter(dist+id+".xlsx");

                List<RecordDown> recordList = categoryTestRunDataService.getDownLoadList(Long.parseLong(id));
                log.info("返回?cái)?shù)據(jù):"+JSON.toJSONString(recordList));
                if (recordList.size() == 0){
                }
                writer.addHeaderAlias("mercNum","商戶編號(hào)");
                writer.addHeaderAlias("triggerTime","風(fēng)險(xiǎn)類別觸發(fā)時(shí)間");
                writer.addHeaderAlias("isRisk","是否風(fēng)險(xiǎn)商戶");
                writer.addHeaderAlias("kind","對(duì)應(yīng)風(fēng)險(xiǎn)種類");
                writer.addHeaderAlias("createHisTime","商戶入網(wǎng)時(shí)間");
                writer.addHeaderAlias("region","商戶所屬地區(qū)");
                for (int i = 0; i < 6; i++) {
                    writer.setColumnWidth(i,35);
                }
                // 一次性寫出內(nèi)容伙窃,使用默認(rèn)樣式菩颖,強(qiáng)制輸出標(biāo)題
                writer.write(recordList, true);
                // 關(guān)閉writer,釋放內(nèi)存
                writer.close();

                //寫入到瀏覽器
                ExcelWriter writerToBrowser = ExcelUtil.getWriter(true);
                writerToBrowser.write(recordList, true);
                OutputStream outputStream = response.getOutputStream();


                //獲得瀏覽器代理信息
                final String userAgent = request.getHeader("USER-AGENT");
                //判斷瀏覽器代理并分別設(shè)置響應(yīng)給瀏覽器的編碼格式
                String finalFileName = null;
                if(StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent,"Trident")){//IE瀏覽器
                    finalFileName = URLEncoder.encode(id+".xlsx","UTF8");
                    System.out.println("IE瀏覽器");
                }else if(StringUtils.contains(userAgent, "Mozilla")){//google,火狐瀏覽器
                    String fileName= id+".xlsx";
                    finalFileName = new String(fileName.getBytes(), "ISO8859-1");
                }else{
                    finalFileName = URLEncoder.encode(id+".xlsx","UTF8");//其他瀏覽器
                }
                //設(shè)置HTTP響應(yīng)頭
                response.reset();//重置 響應(yīng)頭
                response.setContentType("application/x-download");//告知瀏覽器下載文件为障,而不是直接打開晦闰,瀏覽器默認(rèn)為打開
                response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName+ "");//下載文件的名稱
                writerToBrowser.flush(outputStream, true);
                writerToBrowser.close();
                IoUtil.close(outputStream);
            }catch (Exception e){
                e.printStackTrace();
                log.info("錯(cuò)誤信息:"+e);
            }
        }

    }

說明:<font color=green>項(xiàng)目實(shí)現(xiàn)邏輯</font>

  1. 先去指定路徑查找,是否有指定目錄鳍怨,是否有以ID為名的文件呻右。

    //目標(biāo)路徑
            String dist = "/data/download/";
            //String dist = "F:/operate/download/";
            File fileList = new File(dist);
            if (!fileList.exists()){
                fileList.mkdirs();
            }
            //判斷是否存在ID為名的文件
            String[] list = fileList.list();
            boolean isExist = true;  //默認(rèn)該文件存在標(biāo)志
            for (String name_id : list) {
                String sub_name = StringUtils.substring(name_id,0,name_id.lastIndexOf("."));
                //這里對(duì)循環(huán)拿到的文件名和目標(biāo)文件名匹配
                if (StringUtils.equals(sub_name,id)){
                    //這里對(duì)匹配到的文件讀取并輸出到瀏覽器
                }
            }
    
  2. 如果存在以ID為名的文件。

                 //存在預(yù)下載文件
                    //獲取輸入流輸出到瀏覽器
                    FileInputStream fileInputStream = new FileInputStream(dist+name_id);
                    OutputStream outputStream = response.getOutputStream();
                    //設(shè)置Http響應(yīng)頭告訴瀏覽器下載這個(gè)附件,下載的文件名也是在這里設(shè)置的
                    //獲得瀏覽器代理信息
                    final String userAgent = request.getHeader("USER-AGENT");
                    //判斷瀏覽器代理并分別設(shè)置響應(yīng)給瀏覽器的編碼格式,部分瀏覽器編碼格式不同鞋喇,這里的操作防止下載是防止文件名亂碼
                    String finalFileName = null;
                    if(StringUtils.contains(userAgent, "MSIE")||StringUtils.contains(userAgent,"Trident")){//IE瀏覽器
                        finalFileName = URLEncoder.encode(name_id,"UTF8");
                        System.out.println("IE瀏覽器");
                    }else if(StringUtils.contains(userAgent, "Mozilla")){//google,火狐瀏覽器
                        finalFileName = new String(name_id.getBytes(), "ISO8859-1");
                    }else{
                        finalFileName = URLEncoder.encode(name_id,"UTF8");//其他瀏覽器
                    }
                    //設(shè)置HTTP響應(yīng)頭
                    response.reset();//重置 響應(yīng)頭
                    response.setContentType("application/x-download");//告知瀏覽器下載文件声滥,而不是直接打開,瀏覽器默認(rèn)為打開
                    response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName);//下載文件的名稱
                    byte[] bytes = new byte[2048];
                    int len = 0;
                    while ((len = fileInputStream.read(bytes))>0){
                        //寫入到輸出流
                        outputStream.write(bytes,0,len);
                    }
                    fileInputStream.close();
                    outputStream.close();
                    return ;
    
  3. 當(dāng)指定文件目錄沒有目標(biāo)文件名時(shí)去查詢相關(guān)數(shù)據(jù)确徙,進(jìn)行指定路徑備份醒串。

    //輸出寫入到服務(wù)器備份
    ExcelWriter writer = ExcelUtil.getWriter(dist+id+".xlsx");
    //數(shù)據(jù)庫查詢結(jié)果
    List<RecordDown> recordList = categoryTestRunDataService.getDownLoadList(Long.parseLong(id));
    log.info("返回?cái)?shù)據(jù):"+JSON.toJSONString(recordList));
    if (recordList.size() == 0){
        //id下沒有數(shù)據(jù)集合
    }
    //第一個(gè)參數(shù)是實(shí)體類屬性,第二個(gè)參數(shù)是Excel對(duì)應(yīng)的屬性注釋
    writer.addHeaderAlias("me**Num","商**號(hào)");
    writer.addHeaderAlias("tr**rTime","風(fēng)險(xiǎn)****時(shí)間");
    writer.addHeaderAlias("is**sk","是否**商戶");
    writer.addHeaderAlias("k**d","對(duì)應(yīng)**種類");
    writer.addHeaderAlias("cre****sTime","商戶**時(shí)間");
    writer.addHeaderAlias("re**on","商戶**地區(qū)");
    //設(shè)置列的寬度
    for (int i = 0; i < 6; i++) {
     writer.setColumnWidth(i,35);
    }
    // 一次性寫出內(nèi)容鄙皇,使用默認(rèn)樣式芜赌,強(qiáng)制輸出標(biāo)題
    writer.write(recordList, true);
    // 關(guān)閉writer,釋放內(nèi)存
    writer.close();
    
  4. 備份完成后再將輸出到瀏覽器伴逸,具體代碼和上方(2.如果存在以ID為名的文件缠沈。)的邏輯相同。這里不再贅述。

  5. 下載結(jié)果洲愤。

    | 商號(hào) | 風(fēng)險(xiǎn)*時(shí)間 | 是否商戶 | 對(duì)應(yīng)種類 | 商戶時(shí)間 | 商戶*地區(qū) |
    | ——: | ————————-: | ————: | ————: | ————————-: | ————: |
    | 123 | 2020-04-10 11:31:32 | 是 | ** | 2020-04-10 11:31:32 | 商戶 |

補(bǔ)充:一般情況下颓芭,我們?cè)谶M(jìn)行下載功能的時(shí)候需要告訴瀏覽器他的類型。

response.setContentType("application/x-download")

是文件而不是頁面柬赐,設(shè)置瀏覽器自帶下載功能添加文件名亡问。

response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName+ "")

實(shí)現(xiàn)方式:

實(shí)現(xiàn)瀏覽器下載可以有兩種方式:

方法一:
<action name="toauctionExcelAction"class="theauctionaction"method="Excel Theauctioninfo">
    <result name="success"type="stream">
        <param name="contentType">application/vnd.ms-excel;charset=UTF-8</param>
        <param name="contentoisposition">attachment肛宋;filename="${auctionName}"</param>
        <param name="inputName">excelTheauctioninfo</param>
    </result>
</action>

? 從這個(gè)配置可以看出來這個(gè)是Struts2里面的寫法州藕,Struts2每一個(gè)方法都會(huì)有一個(gè)action作為配置信息,這樣子使得配置文件更為方法和繁瑣酝陈。

方法二:
//設(shè)置HTTP響應(yīng)頭
response.reset();//重置 響應(yīng)頭
response.setContentType("application/x-download");//告知瀏覽器下載文件床玻,而不是直接打開,瀏覽器默認(rèn)為打開
response.addHeader("Content-Disposition" ,"attachment;filename=" +finalFileName);//下載文件的名稱

? 直接在控制層中傳入?yún)?shù)HttpServletResponse response利用response設(shè)置頭信息和文件類型下載沉帮,這樣做的好處是只對(duì)這一個(gè)方法有效锈死,不會(huì)對(duì)其他請(qǐng)求造成影響。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末穆壕,一起剝皮案震驚了整個(gè)濱河市待牵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌粱檀,老刑警劉巖洲敢,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異茄蚯,居然都是意外死亡压彭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門渗常,熙熙樓的掌柜王于貴愁眉苦臉地迎上來壮不,“玉大人,你說我怎么就攤上這事皱碘⊙唬” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵癌椿,是天一觀的道長(zhǎng)健蕊。 經(jīng)常有香客問我,道長(zhǎng)踢俄,這世上最難降的妖魔是什么缩功? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮都办,結(jié)果婚禮上嫡锌,老公的妹妹穿的比我還像新娘虑稼。我一直安慰自己,他們只是感情好势木,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布蛛倦。 她就那樣靜靜地躺著,像睡著了一般啦桌。 火紅的嫁衣襯著肌膚如雪溯壶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天震蒋,我揣著相機(jī)與錄音茸塞,去河邊找鬼躲庄。 笑死查剖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的噪窘。 我是一名探鬼主播笋庄,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼倔监!你這毒婦竟也來了直砂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤浩习,失蹤者是張志新(化名)和其女友劉穎静暂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谱秽,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洽蛀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疟赊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郊供。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖近哟,靈堂內(nèi)的尸體忽然破棺而出驮审,到底是詐尸還是另有隱情,我是刑警寧澤吉执,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布疯淫,位于F島的核電站,受9級(jí)特大地震影響戳玫,放射性物質(zhì)發(fā)生泄漏熙掺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一量九、第九天 我趴在偏房一處隱蔽的房頂上張望适掰。 院中可真熱鬧颂碧,春花似錦、人聲如沸类浪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽费就。三九已至诉瓦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間力细,已是汗流浹背睬澡。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留眠蚂,地道東北人煞聪。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像逝慧,于是被迫代替她去往敵國和親昔脯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

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

  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,811評(píng)論 0 11
  • 先創(chuàng)建服務(wù)端的APP 1.官網(wǎng)下載Winrun4j静陈。http://winrun4j.sourceforge.net...
    Alex_1799閱讀 1,726評(píng)論 1 2
  • 姓名:楊新玲【廈門神州駱駝服飾有限公司】 【日精進(jìn)打卡第47天】 【知~學(xué)習(xí)】 《六項(xiàng)精進(jìn)》誦讀1遍共54遍 《大...
    楊馨菱閱讀 49評(píng)論 0 0
  • 常言道,人間最美四月天诞丽。的確鲸拥,進(jìn)入四月,無論是傳統(tǒng)節(jié)日率拒,還是人為的紀(jì)念日崩泡,一個(gè)接著一個(gè)。 四月也正是草長(zhǎng)鶯飛猬膨、花紅...
    西風(fēng)戲語閱讀 1,092評(píng)論 6 10
  • 咨詢心得勃痴。 今天又感冒了谒所,發(fā)燒,打針沛申。對(duì)象一直埋怨我劣领,說我不請(qǐng)假休息,非要上班不可铁材。 我覺得班得上尖淘,活得干奕锌,病得治...
    生活記錄閱讀 127評(píng)論 0 1