您好,登錄后才能下訂單哦!
這篇“Java如何實現批量導出導入數據及附件文件zip包”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Java如何實現批量導出導入數據及附件文件zip包”文章吧。
某系統在不同單位使用時存在兩套生產環境,他們的數據不是互通的,所以這些單位的上一級領導部門在統計數據的時候希望將A系統的數據和附件信息導出到一個壓縮包里,然后把這個壓縮包一鍵導入到B系統,這樣B系統就包含了全部的數據,上級領導就能看到全部的業務信息,便于統計分析。
String path = profile + "/temp/" + DateUtils.dateTimeNow(); File file = new File(path); if (file.mkdirs()) { System.out.println("文件夾創建成功!創建后的文件目錄為:" + file.getPath()); } //1. 輸出Excel文件 HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("sheet"); String fileName="XX數據導出.xls"; String savePath= file.getPath() + File.separator +fileName; OutputStream os = new FileOutputStream(savePath); //響應到客戶端(即瀏覽器端直接彈出下載連接的方式)需要用response獲取流 //this.setResponseHeader(response, filename); //OutputStream os = response.getOutputStream(); List<HashMap> dataList = new ArrayList<>(); try{ // 表頭 this.createExcelTitle(workbook, sheet); // 查詢條件 HashMap param = this.buildQueryParams(params); dataList = shareRegisterMapper.shareList(param); if (CollectionUtils.isEmpty(dataList)){ return; } this.dealAssetData(dataList, sheet); // 處理子表數據 this.dealAssetDetailData(dataList,workbook); workbook.write(os); os.flush(); os.close(); }catch(Exception e) { e.printStackTrace(); }finally { if (os != null) { os.flush(); os.close(); } workbook.close(); }
在上一步生成的Excel文件路徑下新建files文件夾,里面存放附件
public void downloadFile(List<HashMap> dataList) throws Exception { String urlPrefix = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath(); String savePath = file.getPath() + File.separator + "/files"; OutputStream os = null; InputStream is = null; int i=0; try { for (HashMap data : dataList) { if (data == null || data.get("FILES") == null){ continue; } List<ZsglFileEntity> entityList = new ArrayList<>(); String[] fileArray = data.get("FILES").toString().split(","); List idList = Arrays.asList(fileArray); entityList.addAll(fileMapper.selectByIds(idList)); if (CollectionUtils.isNotEmpty(entityList)){ for (ZsglFileEntity file : entityList){ if ( file.getFssFileId() == null){ continue; } String fileUrl = urlPrefix + "/fss/download/" + file.getFssFileId(); // 構造URL URL url = new URL(fileUrl); // 打開連接 URLConnection con = url.openConnection(); //設置請求超時為5s con.setConnectTimeout(5 * 1000); // 輸入流 is = con.getInputStream(); File tempFile = new File(savePath + "/"+file.getFileName()); // 校驗文件夾目錄是否存在,不存在就創建一個目錄 if (!tempFile.getParentFile().exists()) { tempFile.getParentFile().mkdirs(); } os = new FileOutputStream(tempFile); is = con.getInputStream(); con.getHeaderFields(); IOUtils.copy(is, os); System.out.println("下載完成"); } entityList.clear(); } } }catch (IOException e){ System.err.println(e); }finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); } }
response.setCharacterEncoding("UTF-8"); response.setContentType("multipart/form-data"); response.setHeader("content-disposition", "attachment;filename=" + "XX數據導出.zip"); ZipOutputStream zos = new ZipOutputStream(response.getOutputStream()); try { File[] sourceFiles = file.listFiles(); if (null == sourceFiles || sourceFiles.length < 1) { System.out.println("待壓縮的文件目錄:" + "里面不存在文件,無需壓縮."); } else { for (int i = 0; i < sourceFiles.length;i++){ File srcFile = sourceFiles[i]; if (srcFile.isDirectory()){ File[] imageSourceFiles = srcFile.listFiles(); if (null == imageSourceFiles || imageSourceFiles.length < 1){ continue; } for (File imageFile : imageSourceFiles){ compress(zos,imageFile,srcFile.getName()+"/"); } } else { compress(zos,srcFile,""); } } } }catch (Exception e){ e.printStackTrace(); } finally { //關閉流 try { if(null != zos) { zos.close(); } } catch (IOException e){ e.printStackTrace(); } }
其中的壓縮方法如下:
public void compress(ZipOutputStream out,File sourceFile,String base) throws Exception { out.putNextEntry( new ZipEntry(base+sourceFile.getName()) ); FileInputStream fos = new FileInputStream(sourceFile); BufferedInputStream bis = new BufferedInputStream(fos); int tag; System.out.println(base); //將源文件寫入到zip文件中 while((tag=bis.read())!=-1) { out.write(tag); out.flush(); } out.closeEntry(); bis.close(); fos.close(); }
public void deleteDirectory(File file) { File[] list = file.listFiles(); //無法做到list多層文件夾數據 if (list != null) { for (File temp : list) { //先去遞歸刪除子文件夾及子文件 deleteDirectory(temp); //注意這里是遞歸調用 } } if (!file.delete()) { //再刪除自己本身的文件夾 logger.error("文件刪除失敗 : %s%n", file); } }
這里開始想著在不解壓的情況下讀取里面的文件,結果沒有走通。因為zip里面包含了子文件夾里面的附件信息需要解析。不解壓直接解析文件適用于只需要解析zip包中第一層文件的場景,如果子文件夾下的文件也需要處理的話,最好解壓后再處理。
public void unzip(ZipInputStream zipIn, String destDirectory) throws IOException { File destDir = new File(destDirectory); if (!destDir.exists()) { destDir.mkdirs(); } ZipEntry entry = zipIn.getNextEntry(); // 遍歷Zip文件中的條目 while (entry != null) { String filePath = destDirectory + File.separator + entry.getName(); if (!entry.isDirectory()) { int index = entry.getName().indexOf("/"); if (index > -1 && entry.getName().length() > index){ File tempFile = new File(destDirectory + File.separator +entry.getName().substring(0,index)); if (!tempFile.exists()){ tempFile.mkdir(); } } File checkFile = new File(filePath); if (!checkFile.exists()) { checkFile.createNewFile();// 創建目標文件 } // 如果條目是文件直接解壓 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); byte[] bytesIn = new byte[1024]; int read = 0; while ((read = zipIn.read(bytesIn)) != -1) { bos.write(bytesIn, 0, read); } bos.close(); } else { File dir = new File(filePath); if (!dir.exists()){ dir.mkdirs(); } } zipIn.closeEntry(); entry = zipIn.getNextEntry(); } zipIn.close(); }
這里解壓遇到了一個問題,之前導出生成的zip包直接導入沒問題,但是我把導出的包手動解壓后修改了部分數據重新壓縮后再導入報錯:ZipInputStream解壓遠程文件報錯,java.lang.IllegalArgumentException: MALFORMED
原因:文件名含有中文,zip解析出錯
解決方案,如下行代碼,在生成ZipInputStream的時候指定編碼格式。
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(inputStream), Charset.forName(“GBK”));
public List<HashMap> readLocalFile() throws Exception { File file= new File(destDirectory+"/files"); List<HashMap> fssList = new ArrayList<>(); if (file.exists()) { File[] sourceFiles = file.listFiles(); if (null == sourceFiles || sourceFiles.length < 1) { System.out.println(file.getName()+"目錄里面不存在文件,無需處理."); return fssList; } else { for (int i = 0; i < sourceFiles.length;i++){ File srcFile = sourceFiles[i]; FileItemFactory factory = new DiskFileItemFactory(16, null); FileItem item = factory.createItem(srcFile.getName(), "text/plain", true, srcFile.getName()); int bytesRead = 0; byte[] buffer = new byte[8192]; try { FileInputStream fis = new FileInputStream(srcFile); OutputStream os = item.getOutputStream(); while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) { os.write(buffer, 0, bytesRead); } os.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } MultipartFile mfile = new CommonsMultipartFile(item); AjaxResult fileResult = this.fssFileService.uploadFile(mfile); String filePath = fileResult.get("url") == null ? "" : fileResult.get("url").toString(); if (fileResult.get("fileId") != null){ HashMap tempMap = new HashMap(); String fileId = this.fileService.saveFileInfo(fileResult.get("fileId").toString(),mfile, filePath, ""); tempMap.put(srcFile.getName(), fileId); fssList.add(tempMap); } } } } return fssList; }
注意:這里有個小難點就是File轉換成MultipartFile的方法,因為項目中已經有的上傳文件是MultipartFile格式的,轉換一下就不用在實現一遍上傳方法了。
我是用EasyExcel導入Excel文件的,代碼很簡單,需要注意用EasyExcel導入的Excel文件如果包含多個sheet頁,需要寫多個導入監聽文件。
這一步實現方法跟導出時相同,去掉臨時文件。
以上就是關于“Java如何實現批量導出導入數據及附件文件zip包”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。