Excel文件校验

excel文件校验

工作中,经常存在excel文件的导入导出的相关工作,因此正确的文件格式校验成为必须。
不合适的文件校验方式会导致非法文件跳过校验,从而产生不必要的麻烦。
比如,通过文件后缀名的方式进行校验,这种方式其实是存在问题的,因为后缀名可自定义。
正确的校验方式,则应该根据文件流相关属性进行判断。

下面,根据个人工作和参考其他人的经验,逐一进行说明。

一、excel文件两种格式

正常excel存在两种常见的格式,分别是 2003 和 2007格式,
其文件后缀名分别是.xls.xlsx。2007版相对与2003版最大的变动是它的文件格式,使用xml语言的压缩方式,更规范也更适合新的需求。

两种格式,都仍有人在同时使用,我个人推荐 2007 格式。

序号 名称 后缀名 文件格式 兼容性
1 2003 .xls bin 不向上兼容
2 2007 .xlsx xml 向下兼容

二、 excel文件校验

2.1 文件后缀名校验

这种方式其实也可以用来校验,但只属于初验。用户通过修改文件后缀名,可以绕过这种校验方式。
比如,demo.txt文件,我们可以强制修改文件后缀名,让它变成demo.xls文件。

通常校验的方式是文件名后缀截取,只截取最后一个. 字符后的内容, 或者使用正则表达式。

2.2 apache poi 3.xx 版本校验excel

处理excel的开源jar包有两个,一个是jxl, 一个是 apache poi,现在主流的是后者。

apache poi 3.xx 版本校验excel跟 4.xx版本存在不同,这里仅就本人遇到的情况进行说明。
这里3.xx版本使用的是3.10.1版本。

  1. 引入相关依赖

    这里引入了httpcomponentsjar包,为了进行文件类型File -> MultipartFile的转换,毕竟web项目经常使用的是MultipartFile格式的入参文件。

    dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi</artifactId>
       <version>3.10.1</version>
     </dependency>
    
     <dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-ooxml</artifactId>
       <version>3.10.1</version>
     </dependency>
    
     <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
       <version>4.5.9</version>
     </dependency>
    
     <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
       <version>5.3.19</version>
       <scope>compile</scope>
     </dependency>
    
  2. 校验方法

    package com.lunyu.tools.poi.excel;
    
     import java.io.File;
     import java.io.FileInputStream;
     import java.io.IOException;
     import java.io.InputStream;
     import java.io.PushbackInputStream;
     import org.apache.http.entity.ContentType;
     import org.apache.poi.POIXMLDocument;
     import org.apache.poi.poifs.filesystem.POIFSFileSystem;
     import org.springframework.mock.web.MockMultipartFile;
     import org.springframework.web.multipart.MultipartFile;
    
     /**
     * Excel 校验
     * @author lunyu
     * @since 2022/6/25
     */
     public class ExcelPoi3Main {
    
         public static void main(String[] args) throws IOException {
    
             File file = new File("poi/excel/demo.xls");
    
             FileInputStream fileInputStream = new FileInputStream(file);
    
             //转成MultipartFile
             MultipartFile mf = new MockMultipartFile(file.getName(), file.getName(),
                 ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
    
             // 执行校验
             boolean checkResult = checkExcelValid(mf);
    
             System.out.println("excel = " + file.getName() +  "校验结果: " + checkResult);
    
             // TODO: 进一步要做的操作
         }
    
         /**
         * 检验excel合法性
         * @param mf
         * @return
         * @throws IOException
         */
         private static boolean checkExcelValid(MultipartFile mf) throws IOException {
    
             InputStream is = mf.getInputStream();
             if(! is.markSupported()) {
             is = new PushbackInputStream(is, 8);
             }
    
             // 校验excel格式
         return POIFSFileSystem.hasPOIFSHeader(is) || POIXMLDocument.hasOOXMLHeader(is);
         }
     }
    
    

    需要进行说明的是,在3.xx 版本中,POIFSFileSystem.hasPOIFSHeader(InputStream is)方法用于校验excel文件是否符合xls格式,而POIXMLDocument.hasOOXMLHeader(InputStream is)方法则用于校验excel文件是否符合xlsx格式。

2.3 apache poi 4.xx 版本校验excel

同上,我们先引入需要的jar包。

  1. 引入相关依赖

    dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi</artifactId>
       <version>4.1.2</version>
     </dependency>
    
     <dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-ooxml</artifactId>
       <version>4.1.2</version>
     </dependency>
    
     <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
       <version>4.5.9</version>
     </dependency>
    
     <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
       <version>5.3.19</version>
       <scope>compile</scope>
     </dependency>
    
  2. 编写校验方法

    package com.lunyu.tools.poi.excel;
    
     import java.io.File;
     import java.io.FileInputStream;
     import java.io.IOException;
     import java.io.InputStream;
     import org.apache.http.entity.ContentType;
     import org.apache.poi.EmptyFileException;
     import org.apache.poi.poifs.filesystem.FileMagic;
     import org.springframework.mock.web.MockMultipartFile;
     import org.springframework.web.multipart.MultipartFile;
    
     /**
     * Excel 校验
     * @author lunyu
     * @since 2022/6/25
     */
     public class ExcelPoi4Main {
    
         public static void main(String[] args) throws IOException {
    
             File file = new File("poi/excel/demo.txt");
    
             FileInputStream fileInputStream = new FileInputStream(file);
    
             //转成MultipartFile
             MultipartFile mf = new MockMultipartFile(file.getName(), file.getName(),
                 ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
    
             // 执行校验
             boolean checkResult = checkExcelValid(mf);
    
             System.out.println("excel = " + file.getName() +  "校验结果: " + checkResult);
    
             // TODO: 进一步要做的操作
         }
    
         /**
         * 检验excel合法性
         * @param mf
         * @return
         * @throws IOException
         */
         private static boolean checkExcelValid(MultipartFile mf) throws IOException {
    
             InputStream is = mf.getInputStream();
    
             is = FileMagic.prepareToCheckMagic(is);
    
             FileMagic fm;
             try {
             fm = FileMagic.valueOf(is);
             }catch (EmptyFileException e) {
             System.out.println(e.getMessage());
             return false;
             }
    
             return FileMagic.OLE2.equals(fm) || FileMagic.OOXML.equals(fm);
         }
    
    
     }
    
    

    4.xx 版本中,方法FileMagic.OLE2.equals(FileMagic fm)用于校验excel是否是xls格式,方法FileMagic.OOXML.equals(FileMagic fm) 用于校验excel是否是xlsx格式。

posted on 2022-06-29 22:41  论语  阅读(727)  评论(0编辑  收藏  举报

导航