项目架构:spring+struts2+hibernate4+oracle

需求:用户导入excel文件,导入到相应的数据表中,要求提供导入模板,支持xls和xlsx文件

思路分析:

1、提供一个下载链接,点击下载,可以使超链接,src直接是项目路径加文件名。

2、通过上传文件,服务器接收上传,返回一个上传后的服务器本地路径,通过ajax异步赋值到jsp的路径隐藏域。

3、ajax异步提交导入请求,后台处理,将路径转换成File,File转换成MultipartFile,将文件读取转换成一个数组类型的集合。

4、循环集合这种的数据,每一行excel数据,是一个元素,将元素转换成相应的java对象进行保存。

一、所需jar包

一共是6个jar包。

二、前端jsp代码部分

<input type="hidden" id="excelFilePath" name="excelFilePath" value="" />
<tr>
<td>选择文件:</td>
<td><input type="file" name="uploadFile" id="excelFile"></input></input>
<span id="uploadMsg"></span></td>
</tr>
<tr>
<td></td>
<td> <input type="button" value="上传" onclick="fileUpload()">
&nbsp;
<input type="button" value="导入" id="btnOk" disabled="true" onclick="importEmp()"/>
</td>
</tr>
<script type="text/javascript">
// 文件上传
function fileUpload(){
$("#fileTypeError").html("");
$("#btnOk").attr("disabled",true);
var fileName = $("#excelFile").val();
var fileType = fileName.substr(fileName.length-4,fileName.length);
if(fileType == ".xls" || fileType == "xlsx"){ var uploadFileUrl = "${basePath}/public/uploadFile.action";
var formData = new FormData($("#mainForm")[0]);
$.ajax({
type: "POST",
url: uploadFileUrl,
data: formData,
cache: false,
processData: false,
contentType: false,
dataType : "json",
success: function(data){
if(null != data){
if (data.dataStatus == "1") {
$("#uploadMsg").html("<font color='green'>上传成功!</font>");
$("#btnOk").attr("disabled",false);
$("#excelFilePath").attr("value",data.dataMain);
//alert($("#excelFilePath").val());
} else {
if (data.errorMsg != null
&& data.errorMsg.length > 0) {
alert(data.errorMsg);
$("#uploadMsg").html("<font color='red'>" +data.errorMsg + "请仔细阅读操作说明!</font>");
}
}
}
},
error : function(XMLHttpRequest, textStatus,
errorThrown) {
alert("系统异常[" + textStatus + "]:" + errorThrown);
}
});
}else{
$("#uploadMsg").html("<font color='red'>上传文件类型错误,支持类型: .xls .xlsx</font>"); }
}
//Excel文件导入到数据库中
function importEmp(){
var importExcelURL = "${basePath}/public/importResultExaminee.action";
var excelFilePath = $("#excelFilePath").val();
$.ajax({
type: "POST",
url: importExcelURL,
data: {"excelFilePath":excelFilePath},
cache: false,
dataType : "json",
success: function(data){
if(null != data){
if (data.dataStatus == "1") {
$("#btnOk").attr("disabled",false);
alert("本次成功导入数量:" + data.dataMain);
}else{
if (data.errorMsg != null
&& data.errorMsg.length > 0) {
alert(data.errorMsg);
}
}
}
},
error : function(XMLHttpRequest, textStatus,
errorThrown) {
alert("系统异常[" + textStatus + "]:" + errorThrown);
} })
}
</script>

三、核心处理类POIUtils代码:

package com.sinotn.utils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile; /**
* excel导出导入工具类
* Copyright (c) 2018 by Sinotn
* @author Libin
* @date 2018年4月8日 上午9:39:50
*/
public class POIUtils { private static Logger logger = Logger.getLogger(POIUtils.class);
private final static String XLS = "xls";
private final static String XLSX = "xlsx";
/**
* 读取excel文件
* @param formFile
* @return
* @throws IOException
*/
public static List<String[]> readExcel(MultipartFile formFile) throws IOException {
// 检查文件
checkFile(formFile);
//获得Workbook工作薄对象
Workbook workbook = getWorkBook(formFile);
//创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回
List<String[]> list = new ArrayList<String[]>();
if (null != workbook) {
for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets();sheetNum++) {
//获得当前sheet工作表
Sheet sheet = workbook.getSheetAt(sheetNum);
if (null == sheet) {
continue;
}
//获得当前sheet的开始行
int firstRowNum = sheet.getFirstRowNum();
//获得当前sheet的结束行
int lastRowNum = sheet.getLastRowNum();
//循环除了第一行的所有行
for (int rowNum = firstRowNum + 1;rowNum <= lastRowNum;rowNum++) {
//获得当前行
Row row = sheet.getRow(rowNum);
if(row == null){
continue;
}
//获得当前行的开始列
int firstCellNum = row.getFirstCellNum();
//获得当前行的列数
int lastCellNum = row.getPhysicalNumberOfCells();
String[] cells = new String[row.getPhysicalNumberOfCells()];
//循环当前行
for (int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++) {
Cell cell = row.getCell(cellNum);
cells[cellNum] = getCellValue(cell);
}
list.add(cells);
}
}
workbook.close();
}
return list; } /**
* 获取当前行数据
* @param cell
* @return
*/
@SuppressWarnings("deprecation")
private static String getCellValue(Cell cell) {
String cellValue = "";
if(cell == null){
return cellValue;
}
//把数字当成String来读,避免出现1读成1.0的情况
if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
cell.setCellType(Cell.CELL_TYPE_STRING);
}
//判断数据的类型
switch (cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC: //数字
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING: //字符串
cellValue = String.valueOf(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN: //Boolean
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA: //公式
cellValue = String.valueOf(cell.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK: //空值
cellValue = "";
break;
case Cell.CELL_TYPE_ERROR: //故障
cellValue = "非法字符";
break;
default:
cellValue = "未知类型";
break;
}
return cellValue;
} /**
* 获得Workbook工作薄对象
* @param formFile
* @return
*/
private static Workbook getWorkBook(MultipartFile formFile) {
//获得文件名
String fileName = formFile.getName();
//创建Workbook工作薄对象,表示整个excel
Workbook workbook = null;
try {
//获取excel文件的io流
InputStream is = formFile.getInputStream();
//根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
if(fileName.endsWith(XLS)){
//2003
workbook = new HSSFWorkbook(is);
}else if(fileName.endsWith(XLSX)){
//2007
workbook = new XSSFWorkbook(is);
}
} catch (IOException e) {
logger.info(e.getMessage());
}
return workbook;
}
/**
* 检查文件
* @param formFile
* @throws IOException
*/
private static void checkFile(MultipartFile formFile) throws IOException {
//判断文件是否存在
if(null == formFile){
logger.error("文件不存在!");
throw new FileNotFoundException("文件不存在!");
}
//获得文件名
String fileName = formFile.getName();
//判断文件是否是excel文件
if(!fileName.endsWith(XLS) && !fileName.endsWith(XLSX)){
logger.error(fileName + "不是excel文件");
throw new IOException(fileName + "不是excel文件");
} } }

四、action层代码

POIUtil.readExcel方法读取excel文件后,把一行中的值按先后顺序组成一个数组,所有的行作为一个集合返回。我们可以在代码中循环这个集合,把数组赋值到实体类对象中。

我在前台用form表单提交file文件,因为用的SpringMVC框架,后台用MultipartFile接收,代码如下:

/**
* 读取excel文件中的用户信息,保存在数据库中
* @param excelFile
*/
@RequestMapping("/readExcel")
public void readExcel(@RequestParam(value = "excelFile") MultipartFile excelFile,HttpServletRequest req,HttpServletResponse resp){
Map<String, Object> param = new HashMap<String, Object>();
List<User> allUsers = new ArrayList<User>();
try {
List<String[]> userList = POIUtil.readExcel(excelFile);
for(int i = 0;i<userList.size();i++){
String[] users = userList.get(i);
User user = new User();
user.setUserName(users[0]);
user.setPassword(users[1]);
user.setAge(Integer.parseInt(users[2]));
allUsers.add(user);
}
} catch (IOException e) {
logger.info("读取excel文件失败", e);
}
param.put("allUsers", allUsers);
this.userService.insertUsers(param);
}

调用的service层方法就不贴代码了,下面就是往数据库插入数据了。

excel文件内容:

POI异步导入Excel兼容xsl和xlsx的更多相关文章

  1. poi批量导入excel文件

    package com.practice.util; import java.io.File; import java.io.FileInputStream; import java.io.FileN ...

  2. java 使用POI批量导入excel数据

    一.定义 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能. 二.所需jar包: 三.简单的一个读取e ...

  3. NPOI导入excel为datatable (xls xlsx xlsm)

    使用NPOI导入导出Excel(xls/xlsx)数据到DataTable中 http://www.cnblogs.com/songrun/p/3547738.html NPOI 2.0教程 – 自动 ...

  4. Asp.Net异步导入Excel

    故事:用户在页面上传一个excel文件,程序把excel里的内容入库. 技术方案:保存文件在服务器,jquey Ajax 异步读取文件中的记录到数据库,在页面实时刷新导入情况 页面前端 <%@ ...

  5. MVC异步 导入excel文件

    View页面 js文件.封装到一个js文件里面 (function ($) { //可以忽略 var defaultSettings = { url: "http://upload.zhtx ...

  6. Java入门开发POI读取导入Excel文件

    Apache POI是Apache开发的开源的跨平台的 Java API,提供API给Java程序对Microsoft Office格式档案进行各种操作. POI中Excel操作很简单,主要类有 HS ...

  7. C#:导入Excel通用类(Xlsx格式)

    一.引用插件EPPlus.dll   插件下载地址:https://pan.baidu.com/s/1jEl7iu1H_C7-j9Wq37xIRQ  提取密码:pdy6 二.定义通用类XlsxExce ...

  8. java poi 导入excel

    最近项目需要导入excel,网上有很多例子,自己整合记录下,兼容2003和2007,暂时没有添加图片处理功能. 所需jar包  http://pan.baidu.com/s/1sjPuWDR pack ...

  9. Java POI导入Excel文件

    今天在公司需要做个导入Excel文件的功能,所以研究了一下,参考网上的一些资料总算是做出来了,在此记录一下防止以后忘记怎么弄. 本人用的是poi3.8,所以需要的JAR包如下: poi-3.8.jar ...

随机推荐

  1. 【linux 06】 linux中的用户权限、文件权限与目录权限

    1.用户及用户组的概念: 1.文件所有者 2.用户组 3.用户 以root登录Linux之后,执行ls -al,会看到有关文件属性的信息 -rw-r--r--,第1个字符代表这个文件是“目录,文件或链 ...

  2. wap学习记录

    针对移动端浏览器: 大部分的浏览器内核都是webkit内核,对h5和c3的支持非常好 库 国内比较流行的框架 : 妹子UI bootstrap中解决ie8以及以下的h5标签和媒体查询兼容问题的两个库分 ...

  3. SpringBoot log4j2 异常

    log4j 配置 <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g ...

  4. 【HDU 3336】Count the string(KMP+DP)

    Problem Description It is well known that AekdyCoin is good at string problems as well as number the ...

  5. 【Codeforces 1108E1】Array and Segments (Easy version)

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 枚举最大值和最小值在什么地方. 显然,只要包含最小值的区间,都让他减少. 因为就算那个区间包含最大值,也无所谓,因为不会让答案变小. 但是那些 ...

  6. 把以100000+4位随机码的登录账号(比如1000001234),赋予制单页面的权限,怎么写sql啊

    insert into sys_user_role (user_id,role_id,office_id)  select id,'000101100000000004UP',company_id f ...

  7. CodeForces - 586D Phillip and Trains

    这道题是一道搜索题 但是 如果没有读懂或者 或者拐过弯 就很麻烦 最多26个火车 那么每一个周期 (人走一次 车走一次) 就要更改地图 的状态 而且操作复杂 容易超时 出错 利用相对运动 计周期为 人 ...

  8. 【BZOJ2006】超级钢琴(RMQ,priority_queue)

    题意: 思路: 用三元组(i, l, r)表示右端点为i,左端点在[l, r]之间和最大的区间([l, r]保证是对于i可行右端点区间的一个子区间),我们用堆维护一些这样的三元组. 堆中初始的元素为每 ...

  9. 【SPOJ694&705】Distinct Substrings(后缀数组)

    题意:求一个字符串的不相同的子串个数 n<=1000 思路:这是一道论文题 ..]of longint; n,i,m,ans,v,cas:longint; ch:ansistring; proc ...

  10. MongoDB学习day09--Mongoose aggregate 多表关联查询

    Mongodb的aggregate应用之前已经说过了. 可以参考day06 Mongoose的aggregate函数应用 var mongoose=require('./db.js'); var Or ...