Java解析上传的zip文件--包含Excel解析与图片上传

Java解析上传的zip文件--包含Excel解析与图片上传

前言:今天遇到一个需求:上传一个zip格式的压缩文件,该zip中包含人员信息的excel以及excel中每行对应的人的图片,现在需要将该zip压缩包中所有内容解析导入到数据库中,包括图片,并将图片与excel内容对应。

代码演示:

/**
* 信息导入Controller
*/
@RestController
@RequestMapping("/import")
public class ImportController {
    
    
   @AutoWired
   private IExcelService excelService

    /**
    * 接收zip
    * zip中包含了人员excel以及excel中每行对应的人员图片--默认每个人员图片的名称为number号
    */
    @PostMapping(value = "/zip")
    @Transactional
    public void sendRequest(@RequestParam("file") MultipartFile zipFile) throws IOException {
        //通过zip名称创建一个file文件-该文件无具体路径
          File file = new File(Objects.requireNonNull(zipFile.getOriginalFilename()));
        //将zip写入到file中
          FileUtils.writeByteArrayToFile(file, zipFileFile.getBytes());
        //设定字符集编码--这一步必须,否则放到linux服务器中会有字符集报错
          Charset charset = Charset.forName("GBK");
          ZipFile zipFile = new ZipFile(file, charset);
        //开始读取zip中文件
          Enumeration<? extends ZipEntry> entries = zipFile.entries();
        //创建excelZip存放zip中的excel文件内容
          List<ZipEntry> excelZip = new ArrayList<ZipEntry>();
        //创建imgZip存放zip中的图片文件
          List<ZipEntry> imgZip = new ArrayList<ZipEntry>();
        
        //开始读取zip文件
    	  while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
              //通过文件名称去过滤出excel
            if (entry.getName().contains("/excel表格名称.xlsx")) {
                excelZip.add(entry);
            }
              //获取包含图片目录下所有的图片信息
            if (!entry.isDirectory() && entry.getName().contains("图片目录的名称")) {
                imgZip.add(entry);
            }
        }
        //创建文件输入流,将excel变为流
         InputStream excelInputStream = zipFile.getInputStream(excelZip.get(0));
        //创建EasyExcel中的监听器
         ExcelListener excelListener = new ExcelListener();
        //调用EasyExcel中的EasyExcelFactory方法去读取输入流
        EasyExcelFactory.read(excelInputStream,Excel.class,excelListener).sheet().doRead();
        //到此完成获取压缩包中excel的人员信息
        List<Excel> excelList = excelListener.getDataList();
        
        //遍历读取图片
        imgZip.stream().forEach(zip -> {
        try {
             //创建压缩图片的输入流
               InputStream imgInputStream = zipFile.getInputStream(zip);
             //调用流转文件的方法
               File img = stream2file(imgInputStream);
               for (Excel excel : excelList) 
               {
                //将去除后缀的压缩图片名称与excel中的人员号码字段做比较
                if (removeExtension(zip.getName()).contains(excel.getNum())) {
                    //调用文件上传接口,上传到服务器目录下,并返回文件存储路径
                    //这边FileUpload.upload为自己写的一个上传接口,此处省略。。。
                    //如果接受对象为MultipartFile,还需调用fileToMultipartFile转换
                        String urlPath =FileUpload.upload(fileToMultipartFile(img));
                    //进行对象的保存
                        Excel e=new Excel();
                    //设置存储的图片地址
                        e.setPath(urlPath);
                    //调用存储接口存储图片与excel信息
                        excelService.insert(e);
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
    }

   //设置文件名前缀;必须至少三个字符
    static final String PREFIX = "stream2file";
    //设置定义文件的后缀扩展名;如果为null,则将使用后缀".tmp"
    //这边为图片格式,所以默认给的后缀为jpg格式
    static final String SUFFIX = ".jpg";
    
   /**
    * 输入流转文件
    * 该方法为在内存中创建临时文件,不进行磁盘存储
    */
    public static File stream2file(InputStream in) throws IOException {
        //创建临时文件
        final File tempFile = File.createTempFile(PREFIX, SUFFIX);
        tempFile.deleteOnExit();
        try (FileOutputStream out = new FileOutputStream(tempFile)) {
            IOUtils.copy(in, out);
        }
        return tempFile;
    }
    
   /**
    * 截取文件名称--去除后缀名(.jpg等)
    */
    public static String removeExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex == -1) {
            // 如果文件名中没有后缀,则返回原文件名
            return fileName;
        } else {
            // 截取从开头到最后一个`.`字符之前的部分
            return fileName.substring(0, lastDotIndex);
        }
    }
    
     /**
     * file转MultipartFile
     *
     * @param file file
     * @return MultipartFile
     */
    public static MultipartFile fileToMultipartFile(File file) {
        MultipartFile result = null;
        if (null != file) {
            try (FileInputStream input = new FileInputStream(file)) {
                result = new MockMultipartFile(file.getName().concat("temp"), file.getName(), "text/plain", input);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
   }  
}

回顾:

博主解答思路为:

  1. 接收压缩文件
  2. 解析压缩文件,并区分excel与图片文件
  3. 将excel与图片进行匹配,将匹配成功的数据存储到数据库中

要点:

  1. 本次读取几乎都是内存读取,将数据读取到内存中,也在磁盘中建立了临时文件
  2. 解析时需要进行多次类型转换
  3. new ZipFile(file, charset)这一步一定要设定字符集编码,并查看window与linux字符集编码的区别,否则会因为字符集编码问题报错而无法运行
posted @   ProsperousEnding  阅读(634)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
  1. 1 原来你也在这里 周笔畅
  2. 2 世间美好与你环环相扣 柏松
  3. 3 起风了 吴青峰
  4. 4 极恶都市 夏日入侵企划
  5. 5 所念皆星河 CMJ
  6. 6 所念皆星河-歌词版 房东的猫
  7. 7 卡农-钢琴版 dylanf
  8. 8 The truth that you leave Pianoboy高至豪
  9. 9 虹之间 米叔啊
起风了 - 吴青峰
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 米果

作曲 : 高橋優

编曲 : 刘胡轶/貢多杰

制作人 : 刘胡轶/吴青峰

配唱制作人 : 刘胡轶

乐器监制 : 刘胡轶

吉他 : 胡晨

贝斯 : 甯子达

弦乐录音棚 : 中国剧院录音棚

录音工程师 : 倪涵文/李游/李杨/邢铜/韩宽/李巍

录音监制 : 倪涵文/李游

混音&母带工作室 : OKmastering studio

混音&母带工程师 : 全相彦

制作协力 : 刘西洋

制作发行 : 智慧大狗 × 天才联盟

出品人 : 张葛

监制 : 崔恕/王明宇

弦乐监制 : 李朋

弦乐 : 国际首席爱乐乐团

鼓(打击乐):祁大为

和音编写&演唱:鱼椒盐

人声&吉他&鼓(打击乐)录音棚:55Tec studio

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

这一路上走走停停

这一路上走走停停

顺着少年漂流的痕迹

迈出车站的前一刻

竟有些犹豫

不禁笑这近乡情怯

不禁笑这近乡情怯

仍无可避免

而长野的天

依旧那么暖

风吹起了从前

从前初识这世间

从前初识这世间

万般流连

看着天边似在眼前

也甘愿赴汤蹈火去走它一遍

如今走过这世间

如今走过这世间

万般流连

翻过岁月不同侧脸

措不及防闯入你的笑颜

我曾难自拔于世界之大

我曾难自拔于世界之大

也沉溺于其中梦话

不得真假 不做挣扎 不惧笑话

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

逆着光行走 任风吹雨打

短短的路走走停停

短短的路走走停停

也有了几分的距离

不知抚摸的是故事 还是段心情

也许期待的不过是 与时间为敌

再次看到你

微凉晨光里

笑得很甜蜜

从前初识这世间

从前初识这世间

万般流连

看着天边似在眼前

也甘愿赴汤蹈火去走它一遍

如今走过这世间

如今走过这世间

万般流连

翻过岁月不同侧脸

措不及防闯入你的笑颜

我曾难自拔于世界之大

我曾难自拔于世界之大

也沉溺于其中梦话

不得真假 不做挣扎 不惧笑话

我曾将青春翻涌成她

我曾将青春翻涌成她

也曾指尖弹出盛夏

心之所动 且就随缘去吧

晚风吹起你鬓间的白发

晚风吹起你鬓间的白发

抚平回忆留下的疤

你的眼中 明暗交杂 一笑生花

我仍感叹于世界之大

我仍感叹于世界之大

也沉醉于儿时情话

不剩真假 不做挣扎 无谓笑话

我终将青春还给了她

连同指尖弹出的盛夏

心之所动 就随风去了

以爱之名 你还愿意吗

点击右上角即可分享
微信分享提示