目录

  • 前言-应用场景
  • 一、导出ZIP包
    • 1. 列表数据导出到本地excel文件
    • 2. 下载附件信息
    • 3. 生成压缩文件(浏览器下载)
    • 4. 删除临时目录
  • 二、导入ZIP包
    • 1. 上传zip包,解压到临时目录
    • 2. 读取附件信息上传到文件服务器
    • 3. 读取Excel文件存入数据库
    • 4. 删除临时文件

前言-应用场景

某系统在不同单位使用时存在两套生产环境,他们的数据不是互通的,所以这些单位的上一级领导部门在统计数据的时候希望将A系统的数据和附件信息导出到一个压缩包里,然后把这个压缩包一键导入到B系统,这样B系统就包含了全部的数据,上级领导就能看到全部的业务信息,便于统计分析。

一、导出ZIP包

1. 列表数据导出到本地excel文件

     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();}

2. 下载附件信息

在上一步生成的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();// 构造URLURL url = new URL(fileUrl);// 打开连接URLConnection con = url.openConnection();//设置请求超时为5scon.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);}}

3. 生成压缩文件(浏览器下载)

        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();}

4. 删除临时目录

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包

1. 上传zip包,解压到临时目录

这里开始想着在不解压的情况下读取里面的文件,结果没有走通。因为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”));

2. 读取附件信息上传到文件服务器

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格式的,转换一下就不用在实现一遍上传方法了。

3. 读取Excel文件存入数据库

我是用EasyExcel导入Excel文件的,代码很简单,需要注意用EasyExcel导入的Excel文件如果包含多个sheet页,需要写多个导入监听文件。

4. 删除临时文件

这一步实现方法跟导出时相同,去掉临时文件。

批量导出导入数据及附件文件ZIP包相关推荐

  1. mysql workbench批量导出导入sql文件

    mysql workbench批量导出导入sql文件 前序:其实关于workbench导入导出很多教程了,我写这个主要是总结下,然后特别提醒大家导入之后一定记得刷新!导入之后一定记得刷新!导入之后一定 ...

  2. 如何使用 MySQL 的 IDE 导出导入数据表文件(以 Navicat for MySQL 导出导入 Excel 文件为例)

    系列文章目录 关于更多 MySQL 数据库以及数据库 IDE 的问题大家可以移步本人专栏--MySQL 数据库. 文章目录 系列文章目录 前言 一.使用 Navicat 导出数据表 1.1.使用&qu ...

  3. 通过Java批量导出带有图片的Excel文件数据

    批量导出带有图片的Excel文件 一.思路解析 二.关键源码 三.总结 Java通过POI或者一些常见的Excel工具类能够轻易导出后台的结构化数据,但是最近面临一个新需求,需要将对应记录数据和图片网 ...

  4. phpmyadmin批量导出导入的方法步骤

    描述:phpmyadmin批量导出导入的方法步骤 步骤: phpmyadmin选择相应的表,点击导出,格式选择csv 打开导出的csv格式,按照格式输入需要批量导入的数据 phpmyadmin选择相应 ...

  5. 使用GreenPlum/postgres的copy命令导出/导入数据

    1. COPY命令 1.1 postgres postgres的COPY命令可以快速的导出/导入数据到postgresql数据库中,支持常用的文件格式,如:txt.sql.csv.压缩文件.二进制格式 ...

  6. mysql 软件导出导入数据_MySQL 之 导出导入数据

    mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u root -p --databases db_name > test_db.sql       ...

  7. mysql 导入导出 csv_mysql 导出导入数据 -csv

    MySql数据库导出csv文件命令: mysql> select first_name,last_name,email from account into outfile 'e://output ...

  8. oracle11g 使用数据泵导出导入数据

    oracle11g 使用数据泵导出导入数据 终于搞定了 快写个笔记 记录下. 删除用户的时候提示已经登录了不能删除,这个需要把登录的session结束掉. select username,sid,se ...

  9. PLSQL批量导出导入存储过程

    日常工作中,经常会遇到批量导出导入存储过程 一.批量导出存储过程 1.路径:工具>>>导出用户对象 2.一定要选单个文件呦,要不然导入会报错的. 二.批量导入存储过程 1.工具> ...

最新文章

  1. 使用restTemplate报400或者415错误
  2. 使用数字万用表判断三极管管脚!
  3. 怎么获取一个类型的所有字段的名字 和获取给予数据相应的值
  4. 小程序app is not defined
  5. var_dump() 与 print_r()的异同
  6. docker 时区_centos7.X上部署docker并运行常用的应用
  7. Exchange Server 2007邮箱服务器失败规划和恢复
  8. Python中的jquery PyQuery库使用小结
  9. 《Web漏洞防护》读书笔记——第6章,XXE防护
  10. 基于HTTP协议的Java文件传输
  11. Python实现SIFT算法,附详细公式推导和代码
  12. 51单片机汇编学习笔记1——内部结构
  13. 如何退出企业微信?退出之后,企业微信的聊天记录还在吗?
  14. 电脑计算机硬盘格式化,教你电脑怎么格式化本地磁盘
  15. 准备移民澳洲的你,为何改移加拿大?
  16. [bbk5148] 第51集 - 第五章 管理内存 06
  17. 04 数组习题的整理
  18. 精益生产与ERP水火不容?(转)
  19. 网络教育专科计算机考试试题电子科大,电子科技大学网络教育专科英语(理)入学考试模拟题及答案...
  20. robots里屏蔽百度和GG以外的蜘蛛

热门文章

  1. 帅呆了,sancho+mldonkey
  2. 媒体中心软件专题:XBMC
  3. LeetCode 326. Power of Three (算法,换底公式)
  4. [收藏]白话初级会计基础知识,从头讲到尾
  5. Mandiant发布的恶意软件报告(恶意软件已经转移到了WMI和powershell)
  6. java基于http协议客户端与服务器端的交互,通俗易懂客户端与服务器端交互原理(HTTP数据请求与HTTP响应,包括Servlet部分...
  7. 【3D目标检测】SECOND: Sparsely Embedded Convolutional Detection
  8. 小米R3G路由器Breed控制台刷OpenWrt固件
  9. 新ICT时代下,看华为OneAir行业无线专网如何引领工业物联新风尚
  10. ThinkPad全系列恢复光盘(官方链接)(转)