POI 导入导出功能,引用jar包是关键,maven依赖支持3.17版.
首先,理解一下一个Excel的文件的组织形式,一个Excel文件对应于一个workbook(HSSFWorkbook),一个workbook可以有多个sheet(页/表)(HSSFSheet)组成,一个sheet是由多个row(行)(HSSFRow)组成,一个row是由多个cell(单元格)(HSSFCell)组成。
1、用HSSFWorkbook打开或者创建“Excel文件对象
2、用HSSFWorkbook对象返回或者创建Sheet对象
3、用Sheet对象返回行对象,用行对象得到Cell对象
4、对Cell对象读写
org.apache.poi
poi
3.17
org.apache.poi
poi-ooxml
3.17
poi-3.7-20101029.jar
poi-3.9.jar
poi-ooxml-3.9.jar
poi-ooxml-schemas-3.9.jar
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFHyperlink;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Created by cdw on 2018/04/19.
*
* Apache POI操作Excel对象 HSSF:操作Excel 2007之前版本(.xls)格式,生成的EXCEL不经过压缩直接导出
* XSSF:操作Excel 2007及之后版本(.xlsx)格式,内存占用高于HSSF SXSSF:从POI3.8
* beta3开始支持,基于XSSF,低内存占用,专门处理大数据量(建议)。
*
* 注意: 值得注意的是SXSSFWorkbook只能写(导出)不能读(导入)
*
* 说明: .xls格式的excel(最大行数65536行,最大列数256列) .xlsx格式的excel(最大行数1048576行,最大列数16384列)
* 这里引用的是阿里的json包,也可以自行转换成net.sf.json.JSONArray net.sf.json.JSONObject
*/
public class ExcelUtil {
private final static String Excel_2003 = ".xls"; // 2003 版本的excel
private final static String Excel_2007 = ".xlsx"; // 2007 版本的excel
public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 默认日期格式(类型为Date即可转换)
public static final int DEFAULT_COLUMN_WIDTH = 17; // 默认列宽
/**
* 导入Excel
*
* @param file
* 输入文件流
*/
public static List> importExcel(@RequestParam(value = "file", required = false) MultipartFile file)
throws Exception {
String fileName = file.getOriginalFilename();
String xls = fileName.substring(fileName.lastIndexOf('.'));
if (Excel_2003.equals(xls) || Excel_2007.equals(xls)) {
return ExcelUtil.getImportExcel(file);
} else {
// 导入格式不正确
System.out.println("导入格式不正确:导入失败!");
}
return null;
}
/**
* 导出Excel
*
* @param titleList
* 表格头信息集合
* @param dataArray
* 数据数组
* @param os
* 文件输出流
*/
public static void exportExcel(ArrayList titleList, JSONArray dataArray, OutputStream os)
throws Exception {
ExcelUtil.getExportExcel(titleList, dataArray, os);
}
/**
* 导入Excel
*
* @param file
* 导入文件流对象
*/
private static List> getImportExcel(MultipartFile file) throws Exception {
ImportExcelUtil util = new ImportExcelUtil();
String fileName = file.getOriginalFilename();
InputStream inputStream = file.getInputStream();
// 将导入的Excel数据转换成list集合
List> excelLists = util.getBankListByExcel(inputStream, fileName);
// 获取工作模板行数据对象
// HSSFWorkbook workbook = new HSSFWorkbook(new POIFSFileSystem(inputStream));
// 或
// Workbook workbook = util.getWorkbook(inputStream, fileName);
//
// for (int i = 0; i < excelLists.size(); i++) { // 循环行
// List
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by cdw on 2018/04/19.
*
* 转换类
*
* 说明: .xls格式的excel(最大行数65536行,最大列数256列) .xlsx格式的excel(最大行数1048576行,最大列数16384列)
*/
public class ImportExcelUtil {
private final static String Excel_2003 = ".xls"; //2003 版本的excel
private final static String Excel_2007 = ".xlsx"; //2007 版本的excel
/**
* @param in
* @param fileName
*
* @return
*/
public List> getBankListByExcel(InputStream in, String fileName) throws Exception {
List> list = null;
//创建Excel工作簿
Workbook work = this.getWorkbook(in, fileName);
if (work == null) {
throw new Exception("创建Excel工作簿为空!");
}
Sheet sheet = null;
Row row = null;
Cell cell = null;
list = new ArrayList>();
//遍历Excel中的所有sheet
for (int i = 0; i < work.getNumberOfSheets(); i++) {
sheet = work.getSheetAt(i);
if (sheet == null) {
continue;
}
//遍历当前sheet中的所有行
//int totalRow = sheet.getPhysicalNumberOfRows();//如果excel有格式,这种方式取值不准确
int totalRow = sheet.getPhysicalNumberOfRows();
for (int j = sheet.getFirstRowNum(); j < totalRow; j++) {
row = sheet.getRow(j);
if (!isRowEmpty(row)) {
//if(row != null && !"".equals(row)) {
//获取第一个单元格的数据是否存在
Cell fristCell = row.getCell(0);
if (fristCell != null) {
//遍历所有的列
List li = new ArrayList();
//int totalColum = row.getLastCellNum();
for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
cell = row.getCell(y);
String callCal = this.getCellValue(cell) + "";
li.add(callCal);
}
list.add(li);
}
} else if (isRowEmpty(row)) {
continue;
}
}
}
in.close();
return list;
}
/**
* 判断行是否为空
*
* @param row
*
* @return
*/
public static boolean isRowEmpty(Row row) {
for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
Cell cell = row.getCell(c);
if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK)
return false;
}
return true;
}
/**
* 描述:根据文件后缀,自动适应上传文件的版本
*
* @param inStr,fileName
*
* @return
*
* @throws Exception
*/
public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
Workbook work = null;
String fileType = fileName.substring(fileName.lastIndexOf("."));
if (Excel_2003.equals(fileType)) {
work = new HSSFWorkbook(inStr);//2003 版本的excel
} else if (Excel_2007.equals(fileType)) {
work = new XSSFWorkbook(inStr);//2007 版本的excel
} else {
throw new Exception("解析文件格式有误!");
}
return work;
}
/**
* 描述:对表格中数值进行格式化
*
* @param cell
*
* @return
*/
public Object getCellValue(Cell cell) {
/*Object value = null;
DecimalFormat df1 = new DecimalFormat("0.00");//格式化number,string字符
SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");//日期格式化
DecimalFormat df2 = new DecimalFormat("0.00");//格式化数字
if(cell !=null && !"".equals(cell)) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
value = cell.getRichStringCellValue().getString();
break;
case Cell.CELL_TYPE_NUMERIC:
if("General".equals(cell.getCellStyle().getDataFormatString())) {
value = df1.format(cell.getNumericCellValue());
}else if("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {
value = sdf.format(cell.getDateCellValue());
}else if(HSSFDateUtil.isCellDateFormatted(cell)){
Date date = cell.getDateCellValue();
value = sdf.format(date);
}
else {
value = df2.format(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
value = cell.getBooleanCellValue();
break;
case Cell.CELL_TYPE_BLANK:
value = "";
break;
default:
break;
}
}
return value;*/
String result = new String();
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_FORMULA: //Excel公式
try {
result = String.valueOf(cell.getNumericCellValue());
} catch (IllegalStateException e) {
result = String.valueOf(cell.getRichStringCellValue());
}
break;
case HSSFCell.CELL_TYPE_NUMERIC:// 数字类型
if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
SimpleDateFormat sdf;
if (cell.getCellStyle().getDataFormat() == HSSFDataFormat
.getBuiltinFormat("h:mm")) {
sdf = new SimpleDateFormat("HH:mm");
} else {// 日期
sdf = new SimpleDateFormat("yyyy-MM-dd");
}
Date date = cell.getDateCellValue();
result = sdf.format(date);
} else if (cell.getCellStyle().getDataFormat() == 58) {
// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
SimpleDateFormat sdf = new SimpleDateFormat("M月d日");
double value = cell.getNumericCellValue();
Date date = org.apache.poi.ss.usermodel.DateUtil
.getJavaDate(value);
result = sdf.format(date);
} else {
double value = cell.getNumericCellValue();
CellStyle style = cell.getCellStyle();
DecimalFormat format = new DecimalFormat();
String temp = style.getDataFormatString();
// 单元格设置成常规
if (temp.equals("General")) {
format.applyPattern("#.##");
}
result = format.format(value);
}
break;
case HSSFCell.CELL_TYPE_STRING:// String类型
result = cell.getRichStringCellValue().toString();
break;
case HSSFCell.CELL_TYPE_BLANK:
result = "";
default:
result = "";
break;
}
return result;
}
public String getFormat(String str) {
if(str.equals("null")) {
str="";
return str;
}else{
return str;
}
}
public Integer getFormats(Integer str) {
if(str==null) {
str=0;
return str;
}else{
return str;
}
}
/**
* 获取字符串中的数字订单号、数字金额等,如从"USD 374.69"中获取到374.69、从“交易单号:123456789”获取到123456789
*
* @return
*/
public static String getFormatNumber(String str){
str = str.trim();
Pattern p = Pattern.compile("[0-9]");
int indexNum = 0;
int lenght = str.length();
String num = "";
for(int i=0;i
// 导出
@ResponseBody
@RequestMapping(value = "/excelOut", method = RequestMethod.GET)
public String excelOut(HttpServletRequest request, HttpServletResponse response) {
try {
// 获得输出流
OutputStream output = response.getOutputStream();
ArrayList titleList = new ArrayList();
LinkedHashMap titleMap = new LinkedHashMap();
// title1设置标题,key固定
titleMap.put("title1", "测试导出表");
titleMap.put("title2", "测试导出表链接");
LinkedHashMap headMap = new LinkedHashMap();
headMap.put("ranking", "序号");
headMap.put("posterName", "名称");
headMap.put("status", "状态");
titleList.add(titleMap);
titleList.add(headMap);
// 数据集合,下面的字段名必须和上面的map对象key或者数据实体类参数保持一致
List objects = new ArrayList();
for (int i = 0; i < 20; i++) {
JSONObject result = new JSONObject();
result.put("ranking", "value" + i);
result.put("posterName", "value" + i);
result.put("status", "value" + i);
objects.add(result);
}
JSONArray objectsList = JSONArray.parseArray(objects.toString());
// 设置应用类型,以及编码
response.setContentType("application/msexcel;charset=utf-8");
response.setHeader("Content-Disposition",
"filename=" + new String("测试导出表.xlsx/测试导出表.xls".getBytes("gb2312"), "iso8859-1"));
ExcelUtil.exportExcel(titleList, objectsList, output);
} catch (Exception e) {
e.printStackTrace();
}
return "success";
}
// 导入
@ResponseBody
@RequestMapping(value = "/excelIn", method = RequestMethod.POST)
public String excelIn(@RequestParam(value = "file", required = false) MultipartFile file,
HttpServletResponse response) {
try {
List> lists = ExcelUtil.importExcel(file);
System.out.println("导入结果:" + lists.toString());
} catch (Exception e) {
e.printStackTrace();
}
return "success";
}
文件引用
jquery.min.js
jquery.form.js
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
导入导出-导入页面