0.前言
项目中需要解析用户上传的excel文件,校验单元格格式,并数据入库。在实现的过程中遇到了不少问题,并一一解决了,所以总结一下,希望对大家有所帮助。
1.页面传递文件
这里实现了最简单的形式,注意将enctype设为multipart/form-data,提交方式为post。如果需要在上传时利用控件限制文件类型和大小,可以用前端控件plupload等实现。
<form action="uploadFile" method="post" enctype ="multipart/form-data">
<input type="file" name="fileUpload" label=“上传文件"/>
<input type="submit" value="提交">
</form>
2.struts fileUpload拦截器
<action name="uploadFile" class=“" method="uploadFile">
<!-- 必须配置系统默认的拦截器 -->
<!-- 配置 fileupload 的拦截器 -->
<interceptor-ref name="defaultStack">
<!-- 可以支持上传的文件类型 -->
<param name="fileUpload.allowedTypes">
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
application/octet-stream,
application/x-zip-compressed
</param>
<!-- 设置上传文件的大小不能超过1M -->
<param name="fileUpload.maximumSize">1024000</param>
<!— 文件后缀限制 — >
<param name="fileUpload.allowedExtensions">xlsx</param>
</interceptor-ref>
<interceptor-ref name="loginInterceptor" />
</action>
fileUpload是指org.apache.struts2.interceptor.FileUploadInterceptor拦截器。
我要处理的文件类型是.xlsx文件,本来在allowedTypes中只写了application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,在chrome和firefox中都能正确地传递文件到action中。但在ie8、ie9、ie10点击上传后总是报404错误,没有传递文件都action。在fileUpload拦截器中打断点debug后,发现ie8给我传递过来的类型是application/x-zip-compressed。
经过了解,浏览器对文件类型的判断还依赖于当前的操作系统,office2007的文件会被判断为application/x-zip-compressed,office2003文件会被判断为application/octet-stream。
为了解决ie中的问题,我将application/x-zip-compressed加入到allowedTypes中,并用allowedExtensons限制文件后缀,防止上传了exe等文件格式。这样,就解决了ie中的上传问题。
另外,struts上传文件大小有2M的限制,也需要注意,大家可以在页面上提示用户。
3.获取文件
private File fileUpload; //与页面上属性名相同
private String fileUploadFileName; // 文件名+FileName
private String fileUploadContentType; //文件名+ContentType
以上的属性名不可以随意起,要与页面上属性名一致,具体原因可以看拦截器中源码。
4.apache poi解析excel文件
XSSFWorkbook workbook = getWorkBook(fileUpload);
XSSFSheet sheet = workbook.getSheetAt(0);
int rowNum = sheet.getLastRowNum();
List<StaffInfoVO> staffInfoVOs = new ArrayList<StaffInfoVO>();
XSSFRow row = null;
for (int i=1; i<=rowNum; i++) {
row = sheet.getRow(i);
//getCellValue获取内容
XSSFCell cell = row.getCell(0);
String cellValue = getCellValue(cell);
cell.setCellValue("helloworld");
}
//获取单元格的值
private static String getCellValue(XSSFCell cell){
if (cell == null){
return "";
}
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
return cell.getRawValue().trim();
} else {
return cell.getStringCellValue().trim();
}
}
apache poi处理xls文件的是HSSFWorkbook,处理xlsx文件的是XSSFWorkbook。上面代码展示了基本的获取、修改单元格方法。具体的接口参见:http://poi.apache.org/
public static File output(XSSFWorkbook workbook, String FileName) throws Exception {
File excelFile = new File(FileName);
excelFile.createNewFile();
BufferedOutputStream bf = null;
try {
bf = new BufferedOutputStream(new FileOutputStream(excelFile));
workbook.write(bf);
} catch (Exception e) {
throw e;
} finally {
if (bf != null) {
bf.flush();
bf.close();
}
}
return excelFile;
}
处理完之后,可能需要保存文件到本地。以上是基本的保存文件代码。
5.总结
以上是上传excel文件的主要内容,我隐去了我的业务逻辑,展现了主要的框架,希望对你有用~~