最近在做一个项目,需要对数据进行导入导出,实现之后,自己也做了一个总结,总体来说还是比较容易的。第一次的话肯定有许多坑的,细节真的很重要,当你踏过一个又一个坑,一路路走来,你会发现自己的信心越来越强。
对于数据的导入导出,我们首先写一个工具类(数据导入导出是excel结构)
1、先来看看导入代码
public static List<User> importExcel(File file,String fileName) throws IOException{
// 判断一下表单Excel是03版本还是07版本
Workbook workbook = getWork(fileName);
List<User> userList = new ArrayList<User>();
// 获取第一个表单
Sheet sheet = workbook.getSheetAt(0);
// 获取第一个表单的迭代器
Iterator<Row> rows = sheet.rowIterator();
while (rows.hasNext()) {
// 获取行数据
Row row = rows.next();
// 获取第一行的迭代器
Iterator<Cell> cells = row.cellIterator();
User user = null;
if (row.getRowNum() > 0) {
user = new User();
System.out.println("第几行" + row.getRowNum());
}
while(cells.hasNext()) {
Cell cell = cells.next();
int i = cell.getColumnIndex();// 获取每一行的列索引
System.out.println("Cell==" + cell.getColumnIndex());
if (user != null) {
switch (i) {
case 0:
// 用户名称
//row.getCell(i).setCellType(Cell.CELL_TYPE_STRING);
user.setName(String.valueOf(cell.getStringCellValue()));
break;
case 1:
// 用户账号
// // 账户是String类型 传进来的是数字类型 需要转换一下
row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
user.setAccount(String.valueOf(cell.getStringCellValue()));
break;
case 2:
// 用户手机
/**
* Cannot get a text value from a numeric cell
* 电话字段大小11位,自动解析成十六进制
* 为了防止以上异常出现
* 需要设置cell的类型
* 然后 再把纯数字转换成字符串输出
*/
row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
user.setMobile(String.valueOf(cell.getStringCellValue()));
break;
case 3:
// 用户性别
/**
* Cannot get a text value from a boolean cell
* 布尔类型的也需要转换
*/
row.getCell(3).setCellType(Cell.CELL_TYPE_BOOLEAN);
user.setGender(String.valueOf(cell.getBooleanCellValue()).toLowerCase());
break;
case 4:
// 用户邮箱
user.setEmail(String.valueOf(cell.getStringCellValue()));
break;
case 5:
// 用户部门
user.setDept(String.valueOf(cell.getStringCellValue()));
break;
case 6:
// 备注
user.setMemo(String.valueOf(cell.getStringCellValue()));
break;
default:
System.out.println("Unsigned cell type!"); // 未定义类型
break;
}
}
}
userList.add(user);
}
return userList;
}
private static Workbook getWork(String fileName) throws IOException{
Workbook workbook = null;
if (fileName != null ){
try {
String filePath = fileName.substring(fileName.lastIndexOf("."),fileName.length());
FileInputStream fileInputStream = new FileInputStream(new File(fileName));
if (".xls".equals(filePath.trim().toLowerCase())) {
// 2003版本
workbook = new HSSFWorkbook(fileInputStream);
} else if (".xlsx".equals(filePath.trim().toLowerCase())) {
// 2007版本
workbook = new XSSFWorkbook(fileInputStream);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
return workbook;
}
这是导入数据代码,其中注释比较清楚,都是细节,根据自己的需要选择类型
// 导入Excel 文件
@RequestMapping(value = "/importExcel",produces="text/html;charset=UTF-8", method = {RequestMethod.GET,RequestMethod.POST})
public String importExcel(@RequestParam(value = "myFile",required = false) MultipartFile file,HttpServletRequest request) throws IOException {
Map<String, Object> userMap = new HashMap<String, Object>();
if (!file.isEmpty()) {
// 上传文件名
String path = request.getSession().getServletContext().getRealPath("importExcel");
String fileName = file.getOriginalFilename();
File filePath = new File(path, fileName);
// 判断路径是否存在,有的话新建一个
if (!filePath.mkdirs()) {
// 创建父级文件路径
filePath.mkdirs();
}
try {
// 将上传文件保存到一个目标文件当中
file.transferTo(filePath);
//file.transferTo(new File(path + File.separator + fileName));
} catch (Exception e) {
e.printStackTrace();
}
if (fileName.endsWith(".xls") || fileName.endsWith(".xlsx")){
List<User> list = userService.parseExcel(filePath,filePath.toString());
//List<User> list = ExcelUtil.importExcel(filePath,filePath.toString());
if (list != null && list.size() > 0) {
// 批量添加数据库
userService.insertUsers(list);
return "successImport";
}
}
}
return "error";
}
我用的是SSM框架,因此导入的时候需要在mapper.xml文件里面写sql语句。
<!-- 批量文件导入到数据库 -->
<insert id="insertUsers" parameterType="java.util.List">
INSERT INTO tax_user
(name, account, mobile, gender, email, dept, memo)
VALUES
<foreach collection="list" item="item" open="(" close=")" index="index" separator=",">
#{item.name,jdbcType=VARCHAR},
#{item.account,jdbcType=VARCHAR},
#{item.mobile,jdbcType=VARCHAR},
#{item.gender,jdbcType=VARCHAR},
#{item.email,jdbcType=VARCHAR},
#{item.dept,jdbcType=VARCHAR},
#{item.memo,jdbcType=VARCHAR}
</foreach>
</insert>
2、导出数据
(1)不需要写jsp界面
// 导出Excel 不需要直接跳转到jsp界面
@RequestMapping("doExportExcel")
public String doExportExcel(HttpServletResponse response) throws Exception {
// 第一步 创建一个Workbook,对应一个Excel
HSSFWorkbook workbook = new HSSFWorkbook();
// 第二步 创建一个sheet,对应于Excel中的sheet
HSSFSheet sheet = workbook.createSheet("用户信息表");
// 第三步 在sheet表中添加表头第0行,
HSSFRow row = sheet.createRow(0);
// 第四步 创建单元格,并设置值表头,设置表头居中
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中格式
HSSFCell cell = row.createCell(0); // 表中第一列
cell.setCellValue("用户名");
cell.setCellStyle(style);
cell = row.createCell(1); // 第二列
cell.setCellValue("账号");
cell.setCellStyle(style);
cell = row.createCell(2); // 第三列
cell.setCellValue("所属部门");
cell.setCellStyle(style);
cell = row.createCell(3); // 第四列
cell.setCellValue("性别");
cell.setCellStyle(style);
cell = row.createCell(4); // 第五列
cell.setCellValue("电子邮箱");
cell.setCellStyle(style);
cell = row.createCell(5);
cell.setCellValue("电话");
cell.setCellStyle(style);
cell = row.createCell(6);
cell.setCellValue("备注");
cell.setCellStyle(style);
// 第五步 写入实体数据
PageUtil pageUtil = new PageUtil();
pageUtil.setCurrentPage(1);
pageUtil.setPageSize(999999);
Page<User> page = new Page<User>(pageUtil.getCurrentPage(),pageUtil.getPageSize());
List<User> userList = userService.selectUsersByPage(page);
for (int i = 0; i < userList.size(); i++){
row = sheet.createRow(i+1);
User user = userList.get(i);
// 第六步 创建单元格,并设置值
row.createCell(0).setCellValue(user.getName());
row.createCell(1).setCellValue(user.getAccount());
row.createCell(2).setCellValue(user.getDept());
row.createCell(3).setCellValue(user.getGender());
row.createCell(4).setCellValue(user.getEmail());
row.createCell(5).setCellValue(user.getMobile());
row.createCell(6).setCellValue(user.getMemo());
}
// 第七步 输出Excel文件
OutputStream out = response.getOutputStream();
response.reset(); // 清空
long curTime = System.currentTimeMillis();
// 设置日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String fileName = sdf.format(new Date());
// 设置表头格式
response.setHeader("Content-disposition","attachment;curTime=" + fileName + ".xls");
response.setContentType("application/ms-excel");
response.setCharacterEncoding("UTF-8");
// 关闭流
workbook.write(out);
out.close();
return "successExport";
}
(2)jsp界面形式
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<%
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("用户信息导出_"+ sdf.format(new Date())+".xls", "UTF-8"));
response.setContentType("application/ms-excel");
response.setCharacterEncoding("UTF-8");
%>
<table width="100%" border="1" style="border: 1px #EEEEEE;font-size: 15px">
<thead>
<tr>
<th>提交时间</th>
<th>用户名</th>
<th>账号</th>
<th>所属部门</th>
<th>性别</th>
<th>电子邮箱</th>
<th>电话</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<c:forEach items="${requestScope.list}" var="list">
<tr>
<td>${list.name}</td>
<td>${list.account}</td>
<td>${list.dept}</td>
<td>
<c:if test="${list.gender == 'true'}">男</c:if>
<c:if test="${list.gender == 'false'}">女</c:if>
</td>
<td>${list.dept}</td>
<td>${list.email}</td>
<td>${list.mobile}</td>
<td>${list.memo}</td>
</tr>
</c:forEach>
</tbody>
</table>
最主要是这几句话:
<%
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("用户信息导出_"+ sdf.format(new Date())+".xls", "UTF-8"));
response.setContentType("application/ms-excel");
response.setCharacterEncoding("UTF-8");
%>