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
版本。
-
引入相关依赖
这里引入了
httpcomponents
jar包,为了进行文件类型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>
-
校验方法
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包。
-
引入相关依赖
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>
-
编写校验方法
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
格式。
来源:https://www.cnblogs.com/lunyu/p/16425192.html
本站部分图文来源于网络,如有侵权请联系删除。