JAVA后臺(tái)實(shí)現(xiàn)文件批量下載方式
JAVA后臺(tái)實(shí)現(xiàn)文件批量下載
工具類
/** * 本地文件路徑 */ private static final String FILE_PATH = "F:\\test"; /** * 批量下載文件 * * @param list 批量文件集合(前端只傳id集合,后端去查數(shù)據(jù)庫拿到文件信息) * @param request request * @param response response * @param <T> 實(shí)體類 extends BaseEntityPoJo */ public static <T extends BaseEntityPoJo> void batchDownloadFile(List<T> list, HttpServletRequest request, HttpServletResponse response) { //設(shè)置響應(yīng)頭信息 response.reset(); response.setCharacterEncoding("utf-8"); response.setContentType("multipart/form-data"); //設(shè)置壓縮包的名字,date為時(shí)間戳 String date = DateUtil.formatDateTimeSecond(new Date()); String downloadName = "壓縮包" + date + ".zip"; //返回客戶端瀏覽器的版本號(hào)、類型 String agent = request.getHeader("USER-AGENT"); try { //針對(duì)IE或者以IE為內(nèi)核的瀏覽器: if (agent.contains("MSIE") || agent.contains("Trident")) { downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8"); } else { //非IE瀏覽器的處理: downloadName = new String(downloadName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); } } catch (Exception e) { e.printStackTrace(); } response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\""); //設(shè)置壓縮流:直接寫入response,實(shí)現(xiàn)邊壓縮邊下載 ZipOutputStream zipOs = null; //循環(huán)將文件寫入壓縮流 DataOutputStream os = null; //文件 File file; try { zipOs = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream())); //設(shè)置壓縮方法 zipOs.setMethod(ZipOutputStream.DEFLATED); //遍歷文件信息(主要獲取文件名/文件路徑等) for (T t : list) { try { //文件名(包含后綴名,如:測(cè)試.pdf) Field field = t.getClass().getDeclaredField("name"); field.setAccessible(true); String name = field.get(t).toString(); //本地文件路徑(絕對(duì)路徑,包含后綴名,如:F:\\test\\測(cè)試.pdf),這里是在windows上測(cè)試的,路徑是反斜杠 String path = FILE_PATH + File.separator + name; log.info("batchDownloadFile:[filePath:{}]", path); file = new File(path); if (!file.exists()) { throw new RuntimeException("文件不存在"); } //添加ZipEntry,并將ZipEntry寫入文件流 zipOs.putNextEntry(new ZipEntry(name)); os = new DataOutputStream(zipOs); FileInputStream fs = new FileInputStream(file); byte[] b = new byte[100]; int length; //讀入需要下載的文件的內(nèi)容,打包到zip文件 while ((length = fs.read(b)) != -1) { os.write(b, 0, length); } //關(guān)閉流 fs.close(); zipOs.closeEntry(); //==============此處如果是網(wǎng)絡(luò)文件路徑,可按如下方式讀取============= /* //文件名(包含后綴名,如:測(cè)試.pdf) Field field = t.getClass().getDeclaredField("name"); field.setAccessible(true); String name = field.get(t).toString() + ".pdf"; //網(wǎng)絡(luò)文件路徑(瀏覽器可直接訪問的路徑,如:http://192.168.0.12/frame-service-gengbao/document/四川省2022第四季度報(bào)告.pdf) Field urlField = t.getClass().getDeclaredField("url"); urlField.setAccessible(true); URL url = new URL(urlField.get(t).toString()); URLConnection connection = url.openConnection(); InputStream is = connection.getInputStream(); //添加ZipEntry,并將ZipEntry寫入文件流 zipOs.putNextEntry(new ZipEntry(name)); os = new DataOutputStream(zipOs); byte[] b = new byte[100]; int length; //讀入需要下載的文件的內(nèi)容,打包到zip文件 while ((length = is.read(b)) != -1) { os.write(b, 0, length); } is.close(); zipOs.closeEntry(); */ } catch (IllegalAccessException | NoSuchFieldException e) { log.error("下載文件出錯(cuò)![{}]", e.getMessage()); } } } catch (Exception e) { e.printStackTrace(); } finally { //關(guān)閉流 try { if (os != null) { os.flush(); os.close(); } if (zipOs != null) { zipOs.close(); } } catch (IOException e) { e.printStackTrace(); } } }
控制層
/** * 批量下載(測(cè)試時(shí)可改為GET請(qǐng)求,瀏覽器直接調(diào)用接口) * * @param ids 用于查詢相關(guān)表獲取文件信息 * @param request request * @param response response */ @GetMapping("/batchDownloadFile") @ApiOperation("批量下載") public void batchDownloadFile(@RequestParam("ids") final String ids, HttpServletRequest request, HttpServletResponse response) { log.info("downloadPlanFile:批量下載[ids:{},request:{},response:{}]", ids, request, response); List<Integer> idList = ControllerHelper.splitToLong(ids); List<RegulatoryReport> list = service.list(idList); FileUtil.batchDownloadFile(list, request, response); }
上面用到的方法
分割字符串
public static List<Integer> splitToLong(final String str) { return StringUtils.isEmpty(str) ? Collections.emptyList() : Stream.of(str.split(",")).map(Integer::valueOf).collect(Collectors.toList()); }
獲取時(shí)間戳
/** * 將日期解析成yyyyMMddHHmmss的字符串 * * @param date the date * @return the string */ public static String formatDateTimeSecond(Date date) { if (date == null) { return ""; } return new SimpleDateFormat(DATETIME_STAMP_SECOND, Locale.CHINA).format(date); }
注意:
我這里為了對(duì)各種文件通用下載,工具類用的泛型方法,如果不需要泛型的,直接傳入自己需要的實(shí)體類集合就可以了。
測(cè)試接口
其他記錄
在Java中,當(dāng)變量的數(shù)據(jù)類型為File時(shí),值的斜杠都是“\”(new File(filePath), 就會(huì)變成xx\xx\1.txt);
當(dāng)變量的數(shù)據(jù)類型為String 時(shí),斜杠都是“/”(String filePath = “xx/xx/1.txt”);
File f = new File(filePath); String path = (f+“”).replaceAll(“\\”, “/”);
把f轉(zhuǎn)成String類型,然后把里面的“\”替換成“/”就行了。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java ArrayList集合詳解(Java動(dòng)態(tài)數(shù)組)
這篇文章主要介紹了Java ArrayList集合詳解(Java動(dòng)態(tài)數(shù)組),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10String類下compareTo()與compare()方法比較
這篇文章主要介紹了String類下compareTo()與compare()方法比較的相關(guān)資料,需要的朋友可以參考下2017-05-05Spring中配置和讀取多個(gè)Properties文件的方式方法
本篇文章主要介紹了Spring中配置和讀取多個(gè)Properties文件的方式方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04解決Java?properties文件里面如何寫"\"的問題
由于properties使用“\”相當(dāng)于是java的轉(zhuǎn)義符,如果想要寫出\的效果,只需修改相應(yīng)的寫法即可,對(duì)java?properties文件里的"\"寫法感興趣的朋友一起看看吧2022-04-04JAVA實(shí)現(xiàn)基于皮爾遜相關(guān)系數(shù)的相似度詳解
這篇文章主要介紹了JAVA實(shí)現(xiàn)基于皮爾遜相關(guān)系數(shù)的相似度詳解,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11Java實(shí)戰(zhàn)項(xiàng)目 圖書管理系統(tǒng)
這篇文章主要介紹了使用java SSM jsp mysql maven設(shè)計(jì)實(shí)現(xiàn)的精品圖書管理系統(tǒng),是一個(gè)很好的實(shí)例,對(duì)大家的學(xué)習(xí)和工作具有借鑒意義,建議收藏一下2021-09-09Spring security用戶URL權(quán)限FilterSecurityInterceptor使用解析
這篇文章主要介紹了Spring security用戶URL權(quán)限FilterSecurityInterceptor使用解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12