最近在做项目的时候遇到这样一个需求:客户给了一堆Excel数据文档,是从系统中导出的,我们需要按数据的格式建立数据库,读取这些文档,并存入数据库。
数据库采用MySQL,开发框架采用Spring+mybatis, 表已经建立好,Excel文件每一列的标题为汉字,所以每个表的字段名是自己定义的,并将列标题作为该字段的注释。梳理表之间的关系并建表,写好实体类,xml映射文件,dao层和service层,然后需要完成读取Excel文档并调用service层的insert操作。
因为表的数量很多,为每一个表建立单独的读取文档和入库的操作,代码的工作量太大,而且不够灵活,不利于后期维护。采用Java的反射技术来获取实体类的属性,然后和数据库表中的字段名能够对应上,同时该字段的注释又能和Excel的列标题对应上,从而直接读取Excel文档就能找到对应的实体类和数据表来进行insert操作
主体类:ReadAndSaveExcelDataUtil
package cn.ac.iie.gyro.utils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
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.DateUtil;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.ac.iie.gyro.entity.erp.AcquMaterialReqForm;
import cn.ac.iie.gyro.entity.erp.BatchInfoForm;
import cn.ac.iie.gyro.entity.erp.InventoryDataForm;
import cn.ac.iie.gyro.entity.erp.MaterialMasterForm;
import cn.ac.iie.gyro.entity.erp.OutboundCertificateForm;
import cn.ac.iie.gyro.entity.erp.PreMaterialReqForm;
import cn.ac.iie.gyro.entity.erp.ProForm;
import cn.ac.iie.gyro.entity.erp.ProOrderForm;
import cn.ac.iie.gyro.entity.erp.PurOrderForm;
import cn.ac.iie.gyro.entity.erp.SupplierForm;
import cn.ac.iie.gyro.entity.system.ColumnComment;
import cn.ac.iie.gyro.service.MysqlService;
@Component
public class ReadAndSaveExcelDataUtil {
@Autowired
private MysqlService mysqlService;
private static ReadAndSaveExcelDataUtil readErpExcelDataUtil;
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@PostConstruct
public void init() {
readErpExcelDataUtil = this;
readErpExcelDataUtil.mysqlService = this.mysqlService;
}
public MysqlService getMysqlService() {
return mysqlService;
}
public void setMysqlService(MysqlService mysqlService) {
this.mysqlService = mysqlService;
}
public static List<Object> readAndSaveData(String filePath,String entity,String module){
Workbook wb =null;
Sheet sheet = null;
List<Object> list = null;
HashMap<String, Integer> propMap = MapConstructor.getMapFile(filePath);
List<ColumnComment> commentList = readErpExcelDataUtil.getMysqlService().getColumnComment(entity);
HashMap<String, String> standardMap = MapConstructor.getMapStandard(commentList);
try{
Class<?> classTypeOfBean = null;
Class<?> classTypeOfForm = null;
classTypeOfBean = Class.forName("cn.ac.iie.gyro.entity."+module+"."+entity+"Bean");
classTypeOfForm = Class.forName("cn.ac.iie.gyro.entity."+module+"."+entity+"Form");
Object bean = classTypeOfBean.newInstance();
// Object form = classTypeOfForm.newInstance();
Field[] fields = bean.getClass().getDeclaredFields();
wb = readExcel(filePath);
Row row = null;
if(wb != null){
list = new ArrayList<Object>();
//获取第一个sheet
sheet = wb.getSheetAt(0);
//获取最大行数
int rownum = sheet.getPhysicalNumberOfRows();
//获取第一行
row = sheet.getRow(0);
for (int i = 1; i<rownum; i++) {
row = sheet.getRow(i);
if(row !=null){
if(row.getCell(0)==null || ((String) getCellFormatValue(row.getCell(0))).equals("")){
continue;
}
Object form = classTypeOfForm.newInstance();
for (Field f : fields) {
if(f.getType().equals(String.class)){
String propName = standardMap.get(f.getName());
Integer propIndex = propMap.get(propName);
if(propIndex != null && propIndex >= 0){
String value = (String) getCellFormatValue(row.getCell(propIndex));
ReflectUtil.setter(form, f.getName(),value , f.getType());
}
}else if(f.getType().equals(Integer.class)){
String propName = standardMap.get(f.getName());
Integer propIndex = propMap.get(propName);
if(propIndex != null && propIndex >= 0){
String value_str = (String) getCellFormatValue(row.getCell(propIndex));
if(value_str != null && !value_str.equals("")){
Integer value = Integer.parseInt(value_str);
ReflectUtil.setter(form, f.getName(),value , f.getType());
}
}
}else if(f.getType().equals(Double.class)){
String propName = standardMap.get(f.getName());
Integer propIndex = propMap.get(propName);
if(propIndex != null && propIndex >= 0){
String value_str = (String) getCellFormatValue(row.getCell(propIndex));
if(value_str != null && !value_str.equals("")){
Double value = Double.parseDouble(value_str);
ReflectUtil.setter(form, f.getName(),value , f.getType());
}
}
}else if(f.getType().equals(Long.class)){
String propName = standardMap.get(f.getName());
Integer propIndex = propMap.get(propName);
if(propIndex != null && propIndex >= 0){
String value_str = (String) getCellFormatValue(row.getCell(propIndex));
if(value_str != null && !value_str.equals("")){
Long value = Long.parseLong(value_str);
ReflectUtil.setter(form, f.getName(),value , f.getType());
}
}
}else if(f.getType().equals(Date.class)){
String propName = standardMap.get(f.getName());
Integer propIndex = propMap.get(propName);
if(propIndex != null && propIndex >= 0){
String value_str = (String) getCellFormatValue(row.getCell(propIndex));
if(value_str != null && !value_str.equals("") && row.getCell(propIndex).getNumericCellValue()!=0){
Date value = HSSFDateUtil.getJavaDate(row.getCell(propIndex).getNumericCellValue());
ReflectUtil.setter(form, f.getName(),value , f.getType());
}
}
}
}
list.add(form);
}
}
}
}catch(Exception e){
e.printStackTrace();
}
return list;
}
public static Workbook readExcel(String filePath){
Workbook wb = null;
if(filePath==null){
return null;
}
String extString = filePath.substring(filePath.lastIndexOf("."));
InputStream is = null;
try {
is = new FileInputStream(filePath);
if(".xls".equals(extString)){
return wb = new HSSFWorkbook(is);
}else if(".xlsx".equals(extString)){
return wb = new XSSFWorkbook(is);
}else{
return wb = null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return wb;
}
public static Object getCellFormatValue(Cell cell){
Object cellValue = null;
if(cell!=null){
//判断cell类型
switch(cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC:{
cellValue = String.valueOf(cell.getNumericCellValue());
break;
}
case Cell.CELL_TYPE_FORMULA:{
//判断cell是否为日期格式
if(DateUtil.isCellDateFormatted(cell)){
//转换为日期格式YYYY-mm-dd
cellValue = cell.getDateCellValue();
}else{
//数字
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
}
case Cell.CELL_TYPE_STRING:{
cellValue = cell.getRichStringCellValue().getString();
break;
}
default:
cellValue = "";
}
}else{
cellValue = "";
}
return cellValue;
}
}
其他工具类:
MapConstructor:
package cn.ac.iie.gyro.utils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
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 cn.ac.iie.gyro.entity.system.ColumnComment;
public class MapConstructor {
public static HashMap<String, Integer> getMapFile(String filePath) {
Workbook wb =null;
Sheet sheet = null;
Row row = null;
HashMap<String, Integer> mapper = new HashMap<String, Integer>();
try{
wb = readExcel(filePath);
if(wb != null){
sheet = wb.getSheetAt(0);
row = sheet.getRow(0);
if(row != null){
int columnNum=row.getPhysicalNumberOfCells();
for(int i=0;i<columnNum;i++){
mapper.put((String) getCellFormatValue(row.getCell(i)), i);
}
}
}
}catch(Exception e){
e.printStackTrace();
}
return mapper;
}
public static HashMap<String, String> getMapStandard(List<ColumnComment> commentList){
HashMap<String, String> mapper = new HashMap<String, String>();
for(int i=0;i<commentList.size();i++){
mapper.put(commentList.get(i).getColumnName(), commentList.get(i).getColumnComment());
}
return mapper;
}
public static HashMap<Integer, String> getMapStandard(String filePath) {
Workbook wb =null;
Sheet sheet = null;
Row row = null;
HashMap<Integer, String> mapper = new HashMap<Integer, String>();
try{
wb = readExcel(filePath);
if(wb != null){
sheet = wb.getSheetAt(0);
row = sheet.getRow(0);
if(row != null){
int columnNum=row.getPhysicalNumberOfCells();
for(int i=0;i<columnNum;i++){
mapper.put(i, (String) getCellFormatValue(row.getCell(i)));
}
}
}
}catch(Exception e){
e.printStackTrace();
}
return mapper;
}
public static Workbook readExcel(String filePath){
Workbook wb = null;
if(filePath==null){
return null;
}
String extString = filePath.substring(filePath.lastIndexOf("."));
InputStream is = null;
try {
is = new FileInputStream(filePath);
if(".xls".equals(extString)){
return wb = new HSSFWorkbook(is);
}else if(".xlsx".equals(extString)){
return wb = new XSSFWorkbook(is);
}else{
return wb = null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return wb;
}
public static Object getCellFormatValue(Cell cell){
Object cellValue = null;
if(cell!=null){
//判断cell类型
switch(cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC:{
cellValue = String.valueOf(cell.getNumericCellValue());
break;
}
case Cell.CELL_TYPE_FORMULA:{
//判断cell是否为日期格式
if(DateUtil.isCellDateFormatted(cell)){
//转换为日期格式YYYY-mm-dd
cellValue = cell.getDateCellValue();
}else{
//数字
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
}
case Cell.CELL_TYPE_STRING:{
cellValue = cell.getRichStringCellValue().getString();
break;
}
default:
cellValue = "";
}
}else{
cellValue = "";
}
return cellValue;
}
}
ExcelUtil:
package cn.ac.iie.gyro.utils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
public class ExcelUtil {
//默认单元格内容为数字时格式
private static DecimalFormat df = new DecimalFormat("0");
// 默认单元格格式化日期字符串
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 格式化数字
private static DecimalFormat nf = new DecimalFormat("0.00");
public static ArrayList<ArrayList<Object>> readExcel(File file){
if(file == null){
return null;
}
if(file.getName().endsWith("xlsx")){
//处理ecxel2007
return readExcel2007(file);
}else{
//处理ecxel2003
return readExcel2003(file);
}
}
/*
* @return 将返回结果存储在ArrayList内,存储结构与二位数组类似
* lists.get(0).get(0)表示过去Excel中0行0列单元格
*/
public static ArrayList<ArrayList<Object>> readExcel2003(File file){
try{
ArrayList<ArrayList<Object>> rowList = new ArrayList<ArrayList<Object>>();
ArrayList<Object> colList;
HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(file));
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row;
HSSFCell cell;
Object value;
for(int i = sheet.getFirstRowNum() , rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows() ; i++ ){
row = sheet.getRow(i);
colList = new ArrayList<Object>();
if(row == null){
//当读取行为空时
if(i != sheet.getPhysicalNumberOfRows()){//判断是否是最后一行
rowList.add(colList);
}
continue;
}else{
rowCount++;
}
for( int j = row.getFirstCellNum() ; j <= row.getLastCellNum() ;j++){
cell = row.getCell(j);
if(cell == null || cell.getCellType() == HSSFCell.CELL_TYPE_BLANK){
//当该单元格为空
if(j != row.getLastCellNum()){//判断是否是该行中最后一个单元格
colList.add("");
}
continue;
}
switch(cell.getCellType()){
case XSSFCell.CELL_TYPE_STRING:
System.out.println(i + "行" + j + " 列 is String type");
value = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
if ("@".equals(cell.getCellStyle().getDataFormatString())) {
value = df.format(cell.getNumericCellValue());
} else if ("General".equals(cell.getCellStyle()
.getDataFormatString())) {
value = nf.format(cell.getNumericCellValue());
} else {
value = sdf.format(HSSFDateUtil.getJavaDate(cell
.getNumericCellValue()));
}
System.out.println(i + "行" + j
+ " 列 is Number type ; DateFormt:"
+ value.toString());
break;
case XSSFCell.CELL_TYPE_BOOLEAN:
System.out.println(i + "行" + j + " 列 is Boolean type");
value = Boolean.valueOf(cell.getBooleanCellValue());
break;
case XSSFCell.CELL_TYPE_BLANK:
System.out.println(i + "行" + j + " 列 is Blank type");
value = "";
break;
default:
System.out.println(i + "行" + j + " 列 is default type");
value = cell.toString();
}// end switch
colList.add(value);
}//end for j
rowList.add(colList);
}//end for i
return rowList;
}catch(Exception e){
return null;
}
}
public static ArrayList<ArrayList<Object>> readExcel2007(File file){
try{
ArrayList<ArrayList<Object>> rowList = new ArrayList<ArrayList<Object>>();
ArrayList<Object> colList;
XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(file));
XSSFSheet sheet = wb.getSheetAt(0);
XSSFRow row;
XSSFCell cell;
Object value;
for(int i = sheet.getFirstRowNum() , rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows() ; i++ ){
row = sheet.getRow(i);
colList = new ArrayList<Object>();
if(row == null){
//当读取行为空时
if(i != sheet.getPhysicalNumberOfRows()){//判断是否是最后一行
rowList.add(colList);
}
continue;
}else{
rowCount++;
}
for( int j = row.getFirstCellNum() ; j <= row.getLastCellNum() ;j++){
cell = row.getCell(j);
if(cell == null || cell.getCellType() == HSSFCell.CELL_TYPE_BLANK){
//当该单元格为空
if(j != row.getLastCellNum()){//判断是否是该行中最后一个单元格
colList.add("");
}
continue;
}
switch(cell.getCellType()){
case XSSFCell.CELL_TYPE_STRING:
System.out.println(i + "行" + j + " 列 is String type");
value = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
if(HSSFDateUtil.isCellDateFormatted(cell)){
value = sdf.format(HSSFDateUtil.getJavaDate(cell
.getNumericCellValue()));
}else{
value = df.format(cell.getNumericCellValue());
}
/*
if ("@".equals(cell.getCellStyle().getDataFormatString())) {
value = df.format(cell.getNumericCellValue());
} else if ("General".equals(cell.getCellStyle()
.getDataFormatString())) {
value = nf.format(cell.getNumericCellValue());
} else {
value = sdf.format(HSSFDateUtil.getJavaDate(cell
.getNumericCellValue()));
}
*/
System.out.println(i + "行" + j
+ " 列 is Number type ; DateFormt:"
+ value.toString());
break;
case XSSFCell.CELL_TYPE_BOOLEAN:
System.out.println(i + "行" + j + " 列 is Boolean type");
value = Boolean.valueOf(cell.getBooleanCellValue());
break;
case XSSFCell.CELL_TYPE_BLANK:
System.out.println(i + "行" + j + " 列 is Blank type");
value = "";
break;
default:
System.out.println(i + "行" + j + " 列 is default type");
value = cell.toString();
}// end switch
colList.add(value);
}//end for j
rowList.add(colList);
}//end for i
return rowList;
}catch(Exception e){
System.out.println("exception");
return null;
}
}
public static void writeExcel(ArrayList<ArrayList<Object>> result, String standardPath,String filePath,String tempPath) {
if (result == null) {
return;
}
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("sheet1");
HashMap<String, Integer> mapFile = MapConstructor.getMapFile(filePath);
HashMap<Integer, String> mapStandard = MapConstructor.getMapStandard(standardPath);
for (int i = 0; i < result.size(); i++) {
HSSFRow row = sheet.createRow(i);
if (result.get(i) != null) {
for (int j = 0; j < result.get(i).size(); j++) {
HSSFCell cell = row.createCell(j);
String prop = mapStandard.get(j);
if(prop != null && mapFile.containsKey(prop)){
try{
int index = mapFile.get(prop);
cell.setCellValue(result.get(i).get(index).toString());
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
wb.write(os);
} catch (IOException e) {
e.printStackTrace();
}
byte[] content = os.toByteArray();
File file = new File(tempPath);//Excel文件生成后存储的位置。
OutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(content);
os.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static DecimalFormat getDf() {
return df;
}
public static void setDf(DecimalFormat df) {
ExcelUtil.df = df;
}
public static SimpleDateFormat getSdf() {
return sdf;
}
public static void setSdf(SimpleDateFormat sdf) {
ExcelUtil.sdf = sdf;
}
public static DecimalFormat getNf() {
return nf;
}
public static void setNf(DecimalFormat nf) {
ExcelUtil.nf = nf;
}
public static void main(String[] args) {
File file = new File("D:/aa.xlsx");
ArrayList<ArrayList<Object>> result = ExcelUtil.readExcel(file);
for(int i = 0 ;i < result.size() ;i++){
for(int j = 0;j<result.get(i).size(); j++){
System.out.println(i+"行 "+j+"列 "+ result.get(i).get(j).toString());
}
}
// ExcelUtil.writeExcel(result,"D:/b.xlsx");
System.out.println("完成");
}
}
ReflectUtil:
package cn.ac.iie.gyro.utils;
import java.lang.reflect.Method;
public class ReflectUtil {
/**
* @param obj 要操作的对象
* @param att 要操作的属性
* @param value 要设置的属性数据
* @param type 要设置的属性的类型
*/
public static void setter(Object obj, String att, Object value, Class<?> type)
{
try
{
Method met = obj.getClass().getMethod("set" + initStr(att), type);
met.invoke(obj, value);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* @param obj 要操作的对象
* @param att 要操作的属性
*/
public static void getter(Object obj, String att) throws Exception
{
Method met = obj.getClass().getMethod("get" + initStr(att));
System.out.println(met.invoke(obj));
}
/**
* 将单词首字母大写
*
* @param old
* @return
*/
public static String initStr(String old)
{
String newStr = old.substring(0, 1).toUpperCase() + old.substring(1);
return newStr;
}
}