您好,登錄后才能下訂單哦!
這篇“Java如何實現(xiàn)批量導(dǎo)出導(dǎo)入數(shù)據(jù)及附件文件zip包”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Java如何實現(xiàn)批量導(dǎo)出導(dǎo)入數(shù)據(jù)及附件文件zip包”文章吧。
某系統(tǒng)在不同單位使用時存在兩套生產(chǎn)環(huán)境,他們的數(shù)據(jù)不是互通的,所以這些單位的上一級領(lǐng)導(dǎo)部門在統(tǒng)計數(shù)據(jù)的時候希望將A系統(tǒng)的數(shù)據(jù)和附件信息導(dǎo)出到一個壓縮包里,然后把這個壓縮包一鍵導(dǎo)入到B系統(tǒng),這樣B系統(tǒng)就包含了全部的數(shù)據(jù),上級領(lǐng)導(dǎo)就能看到全部的業(yè)務(wù)信息,便于統(tǒng)計分析。
String path = profile + "/temp/" + DateUtils.dateTimeNow(); File file = new File(path); if (file.mkdirs()) { System.out.println("文件夾創(chuàng)建成功!創(chuàng)建后的文件目錄為:" + file.getPath()); } //1. 輸出Excel文件 HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("sheet"); String fileName="XX數(shù)據(jù)導(dǎo)出.xls"; String savePath= file.getPath() + File.separator +fileName; OutputStream os = new FileOutputStream(savePath); //響應(yīng)到客戶端(即瀏覽器端直接彈出下載連接的方式)需要用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); // 處理子表數(shù)據(jù) 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(); // 構(gòu)造URL URL url = new URL(fileUrl); // 打開連接 URLConnection con = url.openConnection(); //設(shè)置請求超時為5s con.setConnectTimeout(5 * 1000); // 輸入流 is = con.getInputStream(); File tempFile = new File(savePath + "/"+file.getFileName()); // 校驗文件夾目錄是否存在,不存在就創(chuàng)建一個目錄 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數(shù)據(jù)導(dǎo)出.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 { //關(guān)閉流 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多層文件夾數(shù)據(jù) if (list != null) { for (File temp : list) { //先去遞歸刪除子文件夾及子文件 deleteDirectory(temp); //注意這里是遞歸調(diào)用 } } if (!file.delete()) { //再刪除自己本身的文件夾 logger.error("文件刪除失敗 : %s%n", file); } }
這里開始想著在不解壓的情況下讀取里面的文件,結(jié)果沒有走通。因為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();// 創(chuàng)建目標(biāo)文件 } // 如果條目是文件直接解壓 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(); }
這里解壓遇到了一個問題,之前導(dǎo)出生成的zip包直接導(dǎo)入沒問題,但是我把導(dǎo)出的包手動解壓后修改了部分?jǐn)?shù)據(jù)重新壓縮后再導(dǎo)入報錯:ZipInputStream解壓遠(yuǎn)程文件報錯,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轉(zhuǎn)換成MultipartFile的方法,因為項目中已經(jīng)有的上傳文件是MultipartFile格式的,轉(zhuǎn)換一下就不用在實現(xiàn)一遍上傳方法了。
我是用EasyExcel導(dǎo)入Excel文件的,代碼很簡單,需要注意用EasyExcel導(dǎo)入的Excel文件如果包含多個sheet頁,需要寫多個導(dǎo)入監(jiān)聽文件。
這一步實現(xiàn)方法跟導(dǎo)出時相同,去掉臨時文件。
以上就是關(guān)于“Java如何實現(xiàn)批量導(dǎo)出導(dǎo)入數(shù)據(jù)及附件文件zip包”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。