日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

Java多格式文件下载及解压处理

發(fā)布時(shí)間:2023/12/4 综合教程 21 生活家
生活随笔 收集整理的這篇文章主要介紹了 Java多格式文件下载及解压处理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

工作中遇到很多多格式文件下載壓縮及解壓處理,現(xiàn)將通用文件下載工具類(lèi)做一個(gè)總結(jié)。包含格式(doc/docx、xls/xlsx、lrm/lrmx、txt、zip/rar等)。

一、解壓處理

文件解壓主要處理rar及zip兩種格式壓縮文件。其中rar5.0及以上版本需采用命令行方式解壓,所以rar格式解壓直接使用命令行方式(需注意程序運(yùn)行環(huán)境windows/linux命令行方式不同)。zip格式解壓使用jar包。

解壓所需jar包:

<!-- 解壓zip -->
<dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.9.4</version>
</dependency>
<!-- io流 -->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version>
</dependency>

通用解壓方法:

/*** 解壓zip文件* @param zipFile* @param outDir* @throws IOException*/
public static void unZip(File zipFile, String outDir) throws IOException {File outFileDir = new File(outDir);if (!outFileDir.exists()) {boolean isMakDir = outFileDir.mkdirs();if (isMakDir) {System.out.println("創(chuàng)建壓縮目錄成功");}}ZipFile zip = new ZipFile(zipFile);for (Enumeration enumeration = zip.getEntries(); enumeration.hasMoreElements(); ) {ZipEntry entry = (ZipEntry) enumeration.nextElement();String zipEntryName = entry.getName();InputStream in = zip.getInputStream(entry);if (entry.isDirectory()) {      //處理壓縮文件包含文件夾的情況File fileDir = new File(outDir + zipEntryName);fileDir.mkdir();continue;}File file = new File(outDir, zipEntryName);file.createNewFile();OutputStream out = new FileOutputStream(file);byte[] buff = new byte[1024];int len;while ((len = in.read(buff)) > 0) {out.write(buff, 0, len);}in.close();out.close();}
}/*** 采用命令行方式解壓文件* 解決rar5.0及以上版本壓縮包解壓不了問(wèn)題* @param rarFile 壓縮文件流* @param destDir 解壓結(jié)果路徑* @param cmdPath 命令所在路徑* @return*/
public static boolean unRar(File rarFile, String destDir, String cmdPath) throws Exception {boolean bool = false;if (!rarFile.exists()) {return false;}File destDirPath = new File(destDir);if (!destDirPath.exists()) {destDirPath.mkdirs();}// 開(kāi)始調(diào)用命令行解壓,參數(shù)-o+是表示覆蓋的意思// String cmdPath = "C:\\Program Files\\WinRAR\\WinRAR.exe"; // windows中的路徑// String cmdPath = "/usr/local/bin/unrar"; 如果linux做了軟連接 不需要這里配置路徑String cmd = cmdPath + " X -o+ " + rarFile + " " + destDir;Process proc = Runtime.getRuntime().exec(cmd);if (proc.waitFor() != 0) {if (proc.exitValue() == 0) {bool = false;}} else {bool = true;}return bool;
}

需注意的是:

方法僅可以解壓一層壓縮文件,壓縮文件套壓縮文件格式本方法不適用。多層壓縮文件解壓思路:解壓外層壓縮包后依次判斷文件類(lèi)型,如果檢測(cè)到有壓縮包則進(jìn)行解壓,整個(gè)過(guò)程可迭代進(jìn)行。(僅提供思路)

二、文件下載

文件下載在日常工作中很常見(jiàn),常見(jiàn)的下載格式:doc/docx、xls/xlsx、txt、json、zip等。下載方法都大同小異。

下載使用說(shuō)明:

  • Word:使用的是freemarker生成固定模板進(jìn)行下載導(dǎo)出。
  • Excel:poi導(dǎo)出
  • 其他格式:使用io流導(dǎo)出

具體怎么使用freemarker生成模板、poi導(dǎo)出文件本篇不做深入討論(百度一大堆)。

涉及到的jar包(按需添加即可):

<!-- io流 -->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version>
</dependency><!-- poi -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.7</version><scope>compile</scope>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.7</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.7</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>3.7</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.3</version>
</dependency>
<dependency><groupId>org.apache.xmlbeans</groupId><artifactId>xmlbeans</artifactId><version>2.6.0</version>
</dependency><!-- freemarker -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

通用文件名格式處理工具代碼:

public static String checkEncode(HttpServletRequest request, String value) throws UnsupportedEncodingException {String agent = request.getHeader("USER-AGENT");if (null != agent){if (-1 != agent.indexOf("Chrome") || -1 != agent.indexOf("Firefox") || -1 != agent.indexOf("Safari")) {value = new String(value.getBytes("utf-8"), "ISO8859-1");} else {//IE7+value = java.net.URLEncoder.encode(value, "UTF-8");}}return value;
}
使用io流下載文件

使用io流下載文件適用于很多文件格式,需注意的是字符編碼集。出現(xiàn)文件下載下來(lái)中文亂碼的十有八九都是編碼集的問(wèn)題。

  1. 示例1:zip文件下載
/*** 根據(jù)文件,進(jìn)行壓縮,批量下載* @throws Exception*/
public static void downloadBatchByFile(List<FileDocDTO> files, HttpServletResponse response, HttpServletRequest request) {ZipOutputStream zos = null;BufferedOutputStream bos = null;try {response.setCharacterEncoding("utf-8");response.setContentType("applicatoin/octet-stream");response.addHeader("Content-Disposition", "attachment; filename=" + checkEncode(request, "cadre.zip"));zos = new ZipOutputStream(response.getOutputStream());bos = new BufferedOutputStream(zos);for (FileDocDTO entry : files) {String fileName = entry.getName();            //每個(gè)zip文件名File file = entry.getFile();            //這個(gè)zip文件的字節(jié)BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));zos.putNextEntry(new ZipEntry(fileName));int len = 0;byte[] buf = new byte[10 * 1024];while ((len = bis.read(buf, 0, buf.length)) != -1) {bos.write(buf, 0, len);}bis.close();bos.flush();}zos.flush();} catch (Exception e) {e.printStackTrace();}finally {try {if (zos != null){zos.close();}if (bos != null){bos.close();}response.getOutputStream().close();}catch (Exception e){e.printStackTrace();}}
}

FileDocDTO類(lèi):用于存放需要壓縮的文件名及文件流

@Data
public class FileDocDTO {private String name;private File file;
}

這種壓縮下載方式可壓縮各種格式文件。

  1. 示例2:lrm/lrmx文件下載(格式為任免表格式)
/*** lrm lrmx下載    --  瀏覽器下載* @param dataInfoStr  數(shù)據(jù)信息字符串* @param fileName  文件名稱(chēng)* @param exportType  文件下載格式 lrm lrmx* @param response* @param request* @return*/
public static boolean singleDataLRMOrLRMXExport(String dataInfoStr, String fileName, String exportType, HttpServletResponse response, HttpServletRequest request){Writer out = null;boolean flag = false;ServletOutputStream servletOutputStream = null;try {String dataName = fileName + "." + exportType;response.setCharacterEncoding("utf-8");response.setContentType("applicatoin/octet-stream");response.addHeader("Content-Disposition", "attachment; filename=" + checkEncode(request, dataName));servletOutputStream = response.getOutputStream();out = new BufferedWriter(new OutputStreamWriter(servletOutputStream));if (exportType.equals("lrmx")){out = new BufferedWriter(new OutputStreamWriter(servletOutputStream, "UTF-8"));}else {out = new BufferedWriter(new OutputStreamWriter(servletOutputStream, "GB2312"));}out.write(dataInfoStr);flag = true;} catch (Exception e){e.printStackTrace();} finally {try {if (out != null){out.close();}if (servletOutputStream != null){servletOutputStream.close();}}catch (Exception e){e.printStackTrace();}}return flag;
}/*** lrm lrmx下載    --  下載到指定文件夾* @param dataInfoStr 數(shù)據(jù)信息字符串* @param fileName 文件名稱(chēng)* @param exportType 文件下載格式 lrm lrmx* @param index 處理下載有多個(gè)同名文件   例如: xx(1).lrm* @param filePath 文件指定下載位置* @return*/
public static FileDocDTO singleDataLRMOrLRMXExport(String dataInfoStr, String fileName, String exportType, String index, String filePath){Writer out = null;String sourceFilePath = "";FileDocDTO fileDoc = new FileDocDTO();try {String dataName = fileName + index + "." + exportType;sourceFilePath = filePath + dataName;File file = new File(sourceFilePath);if (!file.exists()) {// 先得到文件的上級(jí)目錄,并創(chuàng)建上級(jí)目錄,在創(chuàng)建文件file.getParentFile().mkdir();file.createNewFile();}if (exportType.equals("lrmx")){out = new PrintWriter(file, "UTF-8");}else {out = new PrintWriter(file,"GB2312");}out.write(dataInfoStr);fileDoc.setName(dataName);fileDoc.setFile(new File(sourceFilePath));} catch (Exception e){e.printStackTrace();} finally {try {if (out != null){out.close();}}catch (Exception e){e.printStackTrace();}}return fileDoc;
}

提供兩種下載方式,一種直接下載到瀏覽器,另一種下載到指定文件夾。

需注意的是:

這種方式下載也適用于txt、json等格式下載,只需更改文件后綴名和對(duì)應(yīng)的字符編碼。

Word/Excel文件下載

Word/Excel文件下載主要區(qū)別在于數(shù)據(jù)存入形式不一樣。Word需提前固定格式并進(jìn)行占位符數(shù)據(jù)替換,Excel可通過(guò)代碼自定義數(shù)據(jù)格式。當(dāng)然word也可以通過(guò)內(nèi)置代碼進(jìn)行表格合并等樣式處理。(具體實(shí)現(xiàn)操作請(qǐng)百度。內(nèi)容太多這里不做討論。)

  1. Word文件下載
/*** word下載  單個(gè)下載   -- 瀏覽器下載* @param fileMap* @param wordName 文件名稱(chēng)* @param templateFilePath 模板位置* @return*/
public static boolean singleDataWordExport(Map fileMap, String wordName, String templateFilePath, HttpServletResponse response, HttpServletRequest request){String fileName = "無(wú)效";boolean flag = false;Writer out = null;Template template = null;ServletOutputStream servletOutputStream = null;try {fileName = wordName + ".docx";Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);configuration.setDefaultEncoding("UTF-8");String ftlPath = templateFilePath.substring(0, templateFilePath.lastIndexOf("/"));configuration.setDirectoryForTemplateLoading(new File(ftlPath)); // FTL文件所存在的位置String ftlFile = templateFilePath.substring(templateFilePath.lastIndexOf("/")+1);template = configuration.getTemplate(ftlFile); // 模板文件名response.setCharacterEncoding("utf-8");response.setContentType("applicatoin/octet-stream");response.addHeader("Content-Disposition", "attachment; filename=" + checkEncode(request, fileName));servletOutputStream = response.getOutputStream();out = new BufferedWriter(new OutputStreamWriter(servletOutputStream));template.process(fileMap, out);flag = true;} catch (Exception e) {e.printStackTrace();} finally {try {if (out != null){out.close();}if (servletOutputStream != null){servletOutputStream.close();}}catch (Exception e){e.printStackTrace();}}return flag;
}/*** word下載  單個(gè)下載   -- 下載到指定位置* @param fileMap* @param wordName 文件名稱(chēng)* @param templateFilePath 模板位置* @param index 處理下載有多個(gè)同名文件   例如: xx簡(jiǎn)歷(1).docx* @param filePath 文件指定下載位置* @return*/
public static FileDocDTO singleDataWordExport(Map fileMap, String wordName, String templateFilePath, String index, String filePath){String fileName = "無(wú)效";String sourceFilePath = "";FileOutputStream outPut = null;Writer out = null;Template template = null;FileDocDTO fileDoc = new FileDocDTO();try {fileName = wordName + index + ".docx";Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);configuration.setDefaultEncoding("UTF-8");String ftlPath = templateFilePath.substring(0, templateFilePath.lastIndexOf("/"));configuration.setDirectoryForTemplateLoading(new File(ftlPath)); // FTL文件所存在的位置String ftlFile = templateFilePath.substring(templateFilePath.lastIndexOf("/")+1);template = configuration.getTemplate(ftlFile); // 模板文件名File file = new File(filePath + fileName);if (!file.exists()) {// 先得到文件的上級(jí)目錄,并創(chuàng)建上級(jí)目錄,在創(chuàng)建文件file.getParentFile().mkdir();file.createNewFile();}outPut = new FileOutputStream(file);out = new BufferedWriter(new OutputStreamWriter(outPut));template.process(fileMap, out);outPut.flush();fileDoc.setName(fileName);fileDoc.setFile(new File(sourceFilePath));} catch (Exception e) {e.printStackTrace();} finally {try {if (outPut != null){outPut.close();}if (out != null){out.close();}}catch (Exception e){e.printStackTrace();}}return fileDoc;
}
  1. Excel文件下載

excel下載還需導(dǎo)入jar包:

<dependency><groupId>net.sourceforge.jexcelapi</groupId><artifactId>jxl</artifactId><version>2.6.10</version>
</dependency>

示例代碼:

/*** excel格式下載* @param dataList 下載數(shù)據(jù)* @param cl 數(shù)據(jù)類(lèi)* @param fileName 下載文件名稱(chēng)* @param table_head 表頭數(shù)據(jù)* @param table_field 表格數(shù)據(jù)對(duì)應(yīng)字段* @param response* @param request* @return*/
public static boolean excelExport(List dataList, Class cl, String fileName, String[] table_head, String[] table_field, HttpServletResponse response, HttpServletRequest request){boolean flag = false;WritableWorkbook workbook = null;try {// 導(dǎo)出excelresponse.setContentType("application/x-download");response.setCharacterEncoding("utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + checkEncode(request, fileName + ".xls"));workbook = Workbook.createWorkbook(response.getOutputStream());WritableSheet workSheet = workbook.createSheet("first sheet", 0);// 表頭樣式  單元格樣式暫不涉及WritableFont wf_title = new WritableFont(WritableFont.ARIAL, 11, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.WHITE);WritableCellFormat wcf_title = new WritableCellFormat(wf_title);Color color = Color.decode("#1f4e78");workbook.setColourRGB(Colour.ORANGE, color.getRed(), color.getGreen(), color.getBlue());wcf_title.setBackground(Colour.ORANGE);wcf_title.setAlignment(Alignment.CENTRE);wcf_title.setVerticalAlignment(VerticalAlignment.CENTRE);wcf_title.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);wcf_title.setWrap(true);//構(gòu)造excel 表頭for (int i = 0; i < table_head.length; i++) {workSheet.addCell(new jxl.write.Label(i, 0, table_head[i], wcf_title));}//填充表格內(nèi)容Field[] fields = cl.getDeclaredFields();for (int i = 1; i <= dataList.size(); i++) {for (int j = 0; j < table_field.length; j++) {for (int k = 0; k < fields.length; k++) {if (table_field[j].equals(fields[k].getName())) {CellView cellView = new CellView();cellView.setAutosize(true); //設(shè)置自動(dòng)大小fields[k].setAccessible(true);workSheet.setColumnView(j, cellView);if (dataList.get(i - 1) == null) {workSheet.addCell(new jxl.write.Label(j, i, "暫無(wú)"));} else {String str = (fields[k].get(dataList.get(i - 1)) + "");if (CommonUtil.isEmpty(str)){str = "";}workSheet.addCell(new jxl.write.Label(j, i, str));}}}}}workbook.write();flag = true;}catch (Exception e){e.printStackTrace();}finally {try {if (workbook != null){workbook.close();}response.getOutputStream().close();}catch (Exception e){e.printStackTrace();}}return flag;
}

好了 暫時(shí)總結(jié)就這么多。

-------------------------------------------分隔線-------------------------------------------------
2021年2月使用zip解壓遇到一些新問(wèn)題,問(wèn)題如下:
1.解壓后文件出現(xiàn)亂碼問(wèn)題。
2.解壓文件報(bào)錯(cuò)(文件路徑不存在)。
3.解壓文件之后控制臺(tái)出現(xiàn): Cleaning up unclosed ZipFile for archive。

出現(xiàn)問(wèn)題后經(jīng)過(guò)一系列調(diào)試解決結(jié)果如下:
1.文件亂碼問(wèn)題:在解壓時(shí)添加字符編碼集

ZipFile zip = new ZipFile(zipFile, "gbk");

2.控制臺(tái)出現(xiàn): Cleaning up unclosed ZipFile for archive;
解決方式:解壓后關(guān)閉文件流即可
3.解壓文件報(bào)文件路徑不存在:
這是最有意思的一個(gè)bug,值得記錄;

場(chǎng)景
壓縮文件內(nèi)包含文件夾,文件夾內(nèi)文件存在數(shù)字順序(例:1.學(xué)習(xí).docx、2.學(xué)習(xí).docx等)。

過(guò)程:通過(guò)debug一步步調(diào)試可看到zip解壓之后出現(xiàn)順序?yàn)?#xff1a;文件夾/1.學(xué)習(xí).docx、文件夾/2.學(xué)習(xí).docx、文件夾/;而之前代碼邏輯順序應(yīng)為:文件夾/、文件夾/1.學(xué)習(xí).docx、文件夾/2.學(xué)習(xí).docx;解析出來(lái)的順序不一致從而導(dǎo)致問(wèn)題出現(xiàn)。

問(wèn)題結(jié)論:在做解壓文件時(shí)需先做判定文件的上級(jí)文件夾是否存在,如不存在需先創(chuàng)建上級(jí)文件夾。解壓代碼優(yōu)化調(diào)整如下:

public static void unZip(File zipFile, String outDir) throws IOException {File outFileDir = new File(outDir);if (!outFileDir.exists()) {boolean isMakDir = outFileDir.mkdirs();if (isMakDir) {System.out.println("創(chuàng)建壓縮目錄成功");}}ZipFile zip = new ZipFile(zipFile, "gbk");for (Enumeration enumeration = zip.getEntries(); enumeration.hasMoreElements(); ) {ZipEntry entry = (ZipEntry) enumeration.nextElement();String zipEntryName = entry.getName();InputStream in = zip.getInputStream(entry);if (entry.isDirectory()) {      //處理壓縮文件包含文件夾的情況File fileDir = new File(outDir + zipEntryName);fileDir.mkdir();continue;}File file = new File(outDir, zipEntryName);if (!file.getParentFile().exists()){file.getParentFile().mkdir();}file.createNewFile();OutputStream out = new FileOutputStream(file);byte[] buff = new byte[1024];int len;while ((len = in.read(buff)) > 0) {out.write(buff, 0, len);}in.close();out.close();}zip.close();zipFile.delete();}

-------------------------------------------分隔線-------------------------------------------------
補(bǔ)充:Excel單元格合并操作

Excel單元格合并

WritableSheet mergeCells(a,b,c,d)單元格合并函數(shù)

參數(shù)含義

  • a 單元格的列號(hào)
  • b 單元格的行號(hào)
  • c 從單元格[a,b]起,向左合并到c列
  • b 從單元格[a,b]起,向下合并到d行

注:單元格的列號(hào)和行號(hào)都是從0開(kāi)始計(jì)算

總結(jié)

以上是生活随笔為你收集整理的Java多格式文件下载及解压处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。