一个项目可能会有大量的录入数据,通过手动在页面上添,是非常麻烦的事情.可以采用excel表格导入数据的方式,减轻用户的手动压力.
实现步骤说明 :
1.从页面下载模板(也就是excel导出功能只不过数据为空就可以)
建好规定的一个excel模板文件(当然也可以使用POI写代码来画,但比较麻烦),提供给用户按格式放入数据.
例如:
2.用户下载到模板后,往里放入数据.在上传到服务器
实现步骤:1.通过fileupload得到输入流,2.使用POI解析输入流,得到数据集合或者封装到实体类3.存入数据库
得到流数据的两种方式:
第一个:Spring本身提供了CommonsMultipartResolver这个类,只要在配置文件中配置上,
<!-- 支持上传文件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件最大值 -->
<property name="maxUploadSize" value="10240" />
<!-- 缓存最大值 -->
<property name="maxInMemorySize" value="1024" />
<!-- 编码格式 -->
<property name="defaultEncoding" value="UTF-8" />
</bean>
然后方法中获取request对象,强转成MultipartHttpServletRequest对象,获取inputStream即可得到上传的数据流.
MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
ServletInputStream inputStream = mRequest.getInputStream();
第二个:使用commons-fileupload这个包,spring也是通过它来实现的.大致方法
InputStream inputStream = null;
DiskFileItemFactory factory = new DiskFileItemFactory();
FileUpload fileUpload = new FileUpload(factory);
fileUpload.setSizeMax(102400);
fileUpload.setHeaderEncoding("UTF-8");
fileUpload.setFileSizeMax(1024);
List<FileItem> fileItems = fileUpload.parseRequest(request);
for (FileItem item:fileItems){
inputStream = item.getInputStream();
}
注:request只能被fileupload解析一次.如果项目配置了CommonsMultipartResolver,直接通过第一种转化request的方式即可.SpringBoot项目是配置好的.使用第二种方式无法获取到数据流
POI解析excel基本代码
//获取输入流
ServletInputStream inputStream = request.getInputStream();
//通过poi解析流为hssfworkbook对象:如果是xls格式对应HSSFWorkbook,
// 如果是xlsx对应着XSSFWorkbook,需要导入poi-ooxml的包
HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
//获取sheet页
HSSFSheet sheet = workbook.getSheetAt(0);
//遍历表格数据
//行对象
Iterator<Row> rowIterator = sheet.rowIterator();
while (rowIterator.hasNext()){
//得到行对象
Row row = rowIterator.next();
//得到每个单元格的迭代器
Iterator<Cell> cellIterator = row.cellIterator();
//获取值(略)
//封装数据(略)
}
//调用DAO层,存数据即可
到这里功能就实现啦.
下面放一个工具类ExcelHelper :
可以用来导出,解析数据的一些功能
import org.apache.poi.POIXMLException;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
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 java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ExcelHelper {
private static final int NO_DATA = -1;
private static final int ROW_DATA = 0;
private static final int CELL_DATA = 1;
public Map<String, Object> valueToMap(Class<?> clazz, Object value) {
Map<String, Object> valueMap = new HashMap<String, Object>();
for (Field field : clazz.getDeclaredFields()) {
String attrName = field.getName();
String methodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
try {
Method m = clazz.getMethod(methodName);
if (m != null) {
Object oVal = m.invoke(value);
if (oVal != null) {
valueMap.put(attrName, oVal);
}
}
} catch (Exception e) {
}
}
return valueMap;
}
public void export(OutputStream out, File templateFile, Map<String, Object> datas)
throws FileNotFoundException, IOException {
Workbook workbook = null;
FileInputStream in = null;
try {
in = new FileInputStream(templateFile);
workbook = new XSSFWorkbook(in);// 先尝试用xlsx格式读
} catch (FileNotFoundException e) {
throw e;
} catch (POIXMLException e) {// 异常后,使用xls格式读
in = new FileInputStream(templateFile);
workbook = new HSSFWorkbook(in);
}
Sheet sheet = workbook.getSheetAt(0);
fillSheet(sheet, datas);
workbook.write(out);
out.flush();
out.close();
in.close();
}
@SuppressWarnings("rawtypes")
protected void fillSheet(Sheet sheet, Map<String, Object> datas) {
int i = sheet.getFirstRowNum();
int end = sheet.getLastRowNum();
while (i <= end) {
Row row = sheet.getRow(i);
int rowState = NO_DATA;
for (Iterator<Cell> it = row.cellIterator(); it.hasNext();) {
Cell cell = it.next();
String cellValue = cell.getStringCellValue();
if (hasRowExpression(cell)) {// 是否行数据
rowState = ROW_DATA;
break;// 发现行数据即刻跳出
} else if (isExpressionValue(cellValue)) {
rowState = CELL_DATA;
Object newValue = getExpressionValue(datas, cellValue);
if (newValue != null) {
cell.setCellValue(newValue.toString());
}
} else {
rowState = NO_DATA;
}
}
if (rowState == ROW_DATA) {
Object rowsObject = datas.get("rows");
if (rowsObject != null) {
if (rowsObject instanceof Collection) {
Collection rows = (Collection) rowsObject;
for (Iterator it = rows.iterator(); it.hasNext();) {
Object rowData = it.next();
Row target = sheet.getRow(i);
if (it.hasNext()) {
if (i < end) {
insertRow(sheet, i, 1);
Row source = sheet.getRow(++i);
copyRow(source, target);
} else if (i == end) {
Row newRow = sheet.createRow(++i);
copyRow(target, newRow);
}
end++;
}
processRow(target, rowData);
}
}
} else {
sheet.removeRow(row);
}
}
i++;
}
}
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat();
protected void processRow(Row target, Object rowData) {
for (Iterator<Cell> cellIterator = target.cellIterator(); cellIterator.hasNext();) {
Cell cell = cellIterator.next();
if (hasRowExpression(cell)) {// 是否行数据
String newValue = getRowExpressionValue(rowData, cell.getCellComment().getString().getString());
if (newValue != null) {
if (newValue.matches("[\\d\\.]+")) {// number
cell.setCellValue(Double.parseDouble(newValue));
} else if (newValue.matches("\\d{4}-\\d{2}-\\d{2}")) {
try {
cell.setCellValue(DATE_FORMAT.parse(newValue));
} catch (ParseException e) {
cell.setCellValue(newValue);
}
} else {
cell.setCellValue(newValue);
}
}
cell.removeCellComment();
}
}
}
protected void copyRow(Row source, Row target) {
for (int i = source.getFirstCellNum(); i < source.getLastCellNum(); i++) {
Cell sourceCell = source.getCell(i);
Cell targetCell = target.createCell(i);
targetCell.setCellStyle(sourceCell.getCellStyle());
targetCell.setCellType(sourceCell.getCellType());
targetCell.setCellComment(sourceCell.getCellComment());
}
}
protected boolean isExpressionValue(String cellValue) {
// 检查是否包含表达式
return cellValue.matches("[\\s\\S]*\\$\\{\\s*[^\\{\\s]+\\s*\\}[\\s\\S]*");
}
protected boolean hasRowExpression(Cell cell) {
if (cell == null || cell.getCellComment() == null)
return false;
String comment = cell.getCellComment().getString().getString();
// 检查是否包含表达式是否包含row标示
return comment.matches("[\\s\\S]*\\$\\{\\s*\\w+.\\w+\\s*\\}[s\\S]*");
}
private static final Pattern PARAMETER_PATTERN = Pattern.compile("\\$\\{\\s*([^\\{\\s]+)\\s*\\}");
protected Object getExpressionValue(Map<String, Object> datas, String expression) {
Matcher m = PARAMETER_PATTERN.matcher(expression);
while (m.find()) {
String target = m.group();
String key = m.group(1);
Object val = datas.get(key);
String replacement = val != null ? val.toString() : "";
do {
expression = expression.replace(target, replacement);
} while (expression.contains(target));
}
return expression;
}
private static final Pattern ROW_PATTERN = Pattern.compile("\\$\\{\\s*row.(\\w+)\\s*\\}");
protected String getRowExpressionValue(Object object, String expression) {
Matcher m = ROW_PATTERN.matcher(expression);
while (m.find()) {
String target = m.group();
String key = m.group(1);
Object val = getAttribute(object, key);
String replacement = val != null ? val.toString() : "";
do {
expression = expression.replace(target, replacement);
} while (expression.contains(target));
}
return expression;
}
@SuppressWarnings("unchecked")
private Object getAttribute(Object object, String attr) {
String val = "";
if (object instanceof Map) {
Map<String, Object> dataMap = (Map<String, Object>) object;
Object oVal = dataMap.get(attr);
if (oVal != null) {
val = oVal.toString();
}
} else {
try {
String methodName = "get" + attr.substring(0, 1).toUpperCase() + attr.substring(1);
Object oVal = object.getClass().getMethod(methodName).invoke(object);
if (oVal != null) {
val = oVal.toString();
}
} catch (Exception e) {
}
}
return val;
}
public static void insertRow(Sheet sheet, int starRow, int rows) {
sheet.shiftRows(starRow + 1, sheet.getLastRowNum(), rows, true, false);
starRow = starRow - 1;
for (int i = 0; i < rows; i++) {
starRow = starRow + 1;
Row sourceRow = sheet.getRow(starRow);
Row targetRow = sheet.createRow(starRow + 1);
targetRow.setHeight(sourceRow.getHeight());
Cell sourceCell = null;
Cell targetCell = null;
for (int m = sourceRow.getFirstCellNum(); m < sourceRow.getLastCellNum(); m++) {
sourceCell = sourceRow.getCell(m);
targetCell = targetRow.createCell(m);
targetCell.setCellStyle(sourceCell.getCellStyle());
targetCell.setCellType(sourceCell.getCellType());
}
}
}
public List<Map<String, Object>> readRows(InputStream inputFile, FileInputStream templateFile)
throws FileNotFoundException, IOException {
Workbook source = new HSSFWorkbook(inputFile);
Workbook template = new HSSFWorkbook(templateFile);
List<Map<String, Object>> datas = extractSheet(source.getSheetAt(0), template.getSheetAt(0));
try {
inputFile.close();
templateFile.close();
} catch (IOException e) {
}
return datas;
}
public List<Map<String, Object>> readRows(File inputFile, File templateFile)
throws FileNotFoundException, IOException {
Workbook source = null;
Workbook template = null;
InputStream in = null;
InputStream tis = null;
try {
in = new FileInputStream(inputFile);
tis = new FileInputStream(templateFile);
template = new XSSFWorkbook(tis);// 先尝试用xlsx格式读
source = new XSSFWorkbook(in);// 先尝试用xlsx格式读
} catch (FileNotFoundException e) {
throw e;
} catch (POIXMLException e) {// 异常后,使用xls格式读
in = new FileInputStream(inputFile);
tis = new FileInputStream(templateFile);
source = new HSSFWorkbook(in);
template = new HSSFWorkbook(tis);
}
List<Map<String, Object>> datas = extractSheet(source.getSheetAt(0), template.getSheetAt(0));
try {
in.close();
tis.close();
} catch (IOException e) {
}
return datas;
}
protected List<Map<String, Object>> extractSheet(Sheet sheet, Sheet template) {
List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>();
int idx = template.getFirstRowNum();
while (idx <= template.getLastRowNum()) {
Row templateRow = template.getRow(idx);
boolean found = false;
Map<Short, String> templateData = new HashMap<Short, String>();
for (short i = 0; i <= templateRow.getLastCellNum(); i++) {
Cell cell = templateRow.getCell(i);
if (hasRowExpression(cell)) {
Matcher m = ROW_PATTERN.matcher(cell.getCellComment().getString().getString());
m.find();
String attributeName = m.group(1);
if (attributeName != null && !"".equals(attributeName)) {
templateData.put(i, attributeName);
}
found = true;
}
}
if (found) {// 找到模板中的行
for (int i = idx; i <= sheet.getLastRowNum(); i++) {
Row dataRow = sheet.getRow(i);
Map<String, Object> rowData = new HashMap<String, Object>();
for (Short key : templateData.keySet()) {
String attributeName = templateData.get(key);
Cell dataCell = dataRow.getCell(key);
if (dataCell != null) {
if (dataCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
if (HSSFDateUtil.isCellDateFormatted(dataCell)) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat _sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy",
Locale.UK);
Date date = null;
try {
date = _sdf.parse(
HSSFDateUtil.getJavaDate(dataCell.getNumericCellValue()).toString());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 如果是date类型则 ,获取该cell的date值
rowData.put(attributeName, sdf.format(date));
} else { // 纯数字
rowData.put(attributeName, dataCell.getNumericCellValue());
}
} else {
rowData.put(attributeName, dataCell.getStringCellValue());
}
}
}
datas.add(rowData);
}
}
idx++;
}
return datas;
}
}