java实现Excel文件导入导出网上有很多方法,比如:
通过POI实现Excel文件导入导出,
使用java Excel操作Excel文件,
或者使用 JXL实现读写Excel等等。
我这里自己总结以下比较简单常用的通过POI实现Excel文件读写导入导出功能
POI优点:效率搞,支持的应用广泛,操作属性丰富等优点,也较易上手。
本次我总结的内容可以同时支持.xlsx和.xls两种Excel格式
首先你的项目需要在pom文件配置依赖包
<!-- 读取后缀为xlsx或xls的excel操作需要导入包 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
在项目中创建一个Util包,然后将以下两个ExcelUtil和ReadExcelUtil操作Excel的Util类放进去:
这是我的包目录:
ExcelUtil 类:
public class ExcelUtil {
private static final Logger logger = Logger.getLogger(ExcelUtil.class);
public static final String OFFICE_EXCEL_2003_POSTFIX = "xls";
public static final String OFFICE_EXCEL_2010_POSTFIX = "xlsx";
public static final String EMPTY = "";
public static final String POINT = ".";
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
/**
* 获得path的后缀名
* @param path
* @return
*/
public static String getPostfix(String path){
if(path==null || EMPTY.equals(path.trim())){
return EMPTY;
}
if(path.contains(POINT)){
return path.substring(path.lastIndexOf(POINT)+1,path.length());
}
return EMPTY;
}
/**
* 单元格格式
* @param hssfCell
* @return
*/
@SuppressWarnings({
"static-access", "deprecation" })
public static String getHValue(HSSFCell hssfCell){
if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
return String.valueOf(hssfCell.getBooleanCellValue());
} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
String cellValue = "";
if(HSSFDateUtil.isCellDateFormatted(hssfCell)){
Date date = HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue());
cellValue = sdf.format(date);
}else{
DecimalFormat df = new DecimalFormat("#.##");
cellValue = df.format(hssfCell.getNumericCellValue());
String strArr = cellValue.substring(cellValue.lastIndexOf(POINT)+1,cellValue.length());
if(strArr.equals("00")){
cellValue = cellValue.substring(0, cellValue.lastIndexOf(POINT));
}
}
return cellValue;
} else {
return String.valueOf(hssfCell.getStringCellValue());
}
}
/**
* 单元格格式
* @param xssfCell
* @return
*/
public static String getXValue(XSSFCell xssfCell){
if (xssfCell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
return String.valueOf(xssfCell.getBooleanCellValue());
} else if (xssfCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
String cellValue = "";
if(XSSFDateUtil.isCellDateFormatted(xssfCell)){
Date date = XSSFDateUtil.getJavaDate(xssfCell.getNumericCellValue());
cellValue = sdf.format(date);
}else{
DecimalFormat df = new DecimalFormat("#.##");
cellValue = df.format(xssfCell.getNumericCellValue());
String strArr = cellValue.substring(cellValue.lastIndexOf(POINT)+1,cellValue.length());
if(strArr.equals("00")){
cellValue = cellValue.substring(0, cellValue.lastIndexOf(POINT));
}
}
return cellValue;
} else {
return String.valueOf(xssfCell.getStringCellValue());
}
}
/**
* 自定义xssf日期工具类
*
*/
static class XSSFDateUtil extends DateUtil {
protected static int absoluteDay(Calendar cal, boolean use1904windowing) {
return DateUtil.absoluteDay(cal, use1904windowing);
}
}
}
ReadExcelUtil 类:
public class ReadExcelUtil {
public int totalRows; //sheet中总行数
public static int totalCells; //每一行总单元格数
/**
* read the Excel .xlsx,.xls
* @param file jsp中的上传文件
* @return
* @throws IOException
*/
public List<ArrayList<String>> readExcel(MultipartFile file) throws IOException {
if(file==null||ExcelUtil.EMPTY.equals(file.getOriginalFilename().trim())){
return null;
}else{
String postfix = ExcelUtil.getPostfix(file.getOriginalFilename());
if(!ExcelUtil.EMPTY.equals(postfix)){
if(ExcelUtil.OFFICE_EXCEL_2003_POSTFIX.equals(postfix)){
return readXls(file);
}else if(ExcelUtil.OFFICE_EXCEL_2010_POSTFIX.equals(postfix)){
return readXlsx(file);
}else{
return null;
}
}
}
return null;
}
/**
* read the Excel 2010 .xlsx
* @param file
* @return
* @throws IOException
*/
@SuppressWarnings("deprecation")
public List<ArrayList<String>> readXlsx(MultipartFile file){
List<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
// IO流读取文件
InputStream input = null;
XSSFWorkbook wb = null;
ArrayList<String> rowList = null;
try {
input = file.getInputStream();
// 创建文档
wb = new XSSFWorkbook(input);
//读取sheet(页)
for(int numSheet=0;numSheet<wb.getNumberOfSheets();numSheet++){
XSSFSheet xssfSheet = wb.getSheetAt(numSheet);
if(xssfSheet == null){
continue;
}
totalRows = xssfSheet.getLastRowNum();
//读取Row,从第4行开始
for(int rowNum = 1;rowNum <= totalRows;rowNum++){
XSSFRow xssfRow = xssfSheet.getRow(rowNum);
if(xssfRow!=null){
rowList = new ArrayList<String>();
totalCells = xssfRow.getLastCellNum();
//读取列,从第一列开始
for(int c=0;c<=totalCells+1;c++){
XSSFCell cell = xssfRow.getCell(c);
if(cell==null){
rowList.add(ExcelUtil.EMPTY);
continue;
}
rowList.add(ExcelUtil.getXValue(cell).trim());
}
list.add(rowList);
}
}
}
return list;
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* read the Excel 2003-2007 .xls
* @param file
* @return
* @throws IOException
*/
public List<ArrayList<String>> readXls(MultipartFile file){
List<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
// IO流读取文件
InputStream input = null;
HSSFWorkbook wb = null;
ArrayList<String> rowList = null;
try {
input = file.getInputStream();
// 创建文档
wb = new HSSFWorkbook(input);
//读取sheet(页)
for(int numSheet=0;numSheet<wb.getNumberOfSheets();numSheet++){
HSSFSheet hssfSheet = wb.getSheetAt(numSheet);
if(hssfSheet == null){
continue;
}
totalRows = hssfSheet.getLastRowNum();
//读取Row,从第二行开始
for(int rowNum = 1;rowNum <= totalRows;rowNum++){
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
if(hssfRow!=null){
rowList = new ArrayList<String>();
totalCells = hssfRow.getLastCellNum();
//读取列,从第一列开始
for(short c=0;c<=totalCells+1;c++){
HSSFCell cell = hssfRow.getCell(c);
if(cell==null){
rowList.add(ExcelUtil.EMPTY);
continue;
}
rowList.add(ExcelUtil.getHValue(cell).trim());
}
list.add(rowList);
}
}
}
return list;
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
Controller层
方法1:获取Excel文件并解析数据
方法2:信息excel数据重新整理导出Excel
@Controller
@RequestMapping("/v1/customer")
public class CustomerInfoController {
private static Logger logger = Logger.getLogger(CustomerInfoController.class);
@Autowired
private CustomerInfoService customerInfoService;
@ApiOperation(value = "信息excel数据解析导入数据库", notes = "注意事项")
@RequestMapping(value="/excelImport",method=RequestMethod.POST)
@ResponseBody
public ResponseData excelImport(@RequestParam(value="userFile") MultipartFile file,
HttpServletRequest request) {
List<ArrayList<String>> readExcel = new ArrayList<>();
try {
//调用util方法拿到解析的数据集合
readExcel = new ReadExcelUtil().readExcel(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String originalFileName = file.getOriginalFilename();
int beginIndex = originalFileName.lastIndexOf(".");
//原名
String fileName = originalFileName.substring(0,beginIndex);
boolean response = customerInfoService.insterCustomerInfo(readExcel, fileName);
if (response) {
return new ResponseData(SystemCodeConstant.RIGHT_CODE, response, "请求成功");
}else{
return new ResponseData(SystemCodeConstant.ERROR_CODE, response, SystemErrorConstant.SAVE_ERROR_DESCRIPTION);
}
}
@ApiOperation(value = "信息excel数据重新整理导出Excel", notes = "注意事项")
@RequestMapping(value="/excelExportFile",method=RequestMethod.POST)
@ResponseBody
public void excelExportFile(@RequestParam(value="file") MultipartFile file, HttpServletResponse response) {
List<ArrayList<String>> readExcel = new ArrayList<>();
try {
//调用util方法拿到解析的数据集合
readExcel = new ReadExcelUtil().readExcel(file);
} catch (IOException e) {
e.printStackTrace();
}
//获取文件名后缀
String postfix = ExcelUtil.getPostfix(file.getOriginalFilename());
//获取文件名
String originalFileName = file.getOriginalFilename();
int beginIndex = originalFileName.lastIndexOf(".");
String fileName = originalFileName.substring(0,beginIndex);
//调用service层业务接口实现Excel文件整理和创建
Workbook wb = customerInfoService.excelEmportFile(readExcel, fileName, postfix);
// 响应到客户端
try {
fileName = fileName + "." + postfix;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
wb.write(outputStream);
ByteArrayInputStream tempIn = new ByteArrayInputStream(outputStream.toByteArray());
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Length", String.valueOf(tempIn.available()));
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
response.addHeader("Content-type", "application-download");
response.setContentType("application/octet-stream");
ServletOutputStream out = response.getOutputStream();
BufferedOutputStream toOut = new BufferedOutputStream(out);
byte[] buffer = new byte[tempIn.available()];
int a;
while ((a = tempIn.read(buffer)) != -1) {
out.write(buffer, 0, a);
}
toOut.write(buffer);
toOut.flush();
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
具体的业务操作如下service接口实现:
方法1:将解析的Excel数据集合保存至数据库
方法2:将解析的Excel数据按照业务过滤重复数据重新生成Excel文件返回
@Service
@Transactional
public class CustomerInfoServiceImpl implements CustomerInfoService {
@Autowired
//操作数据库接口
private CustomerInfoMapper customerInfoMapper;
@Override
public boolean insterCustomerInfo(List<ArrayList<String>> readExcel, String fileName) {
// 读取数据封装实体
if(readExcel.size() == 0) {
return false;
}
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String sign = fileName+formatter.format(new Date());
List<CustomerPhoneInfoDo> doList = new ArrayList<>();
//将解析的Excel数据集合封装到实体,
for(List<String> sList : readExcel) {
CustomerPhoneInfoDo customerPhoneInfoDo = new CustomerPhoneInfoDo();
int count = 0;
for(String str : sList) {
if(0 == count) {
// 客户名称
customerPhoneInfoDo.setUserName(str==null?"":str.toString());
}else if(1 == count) {
//电话
customerPhoneInfoDo.setPhone(str==null?"":str.toString());
}else if(2 == count) {
//区域
customerPhoneInfoDo.setRegion(str==null?"":str.toString());
}else if(3 == count) {
//客户需求
customerPhoneInfoDo.setCustomerNeed(str==null?"":str.toString());
}else if(4 == count) {
//宣传人
customerPhoneInfoDo.setPublicist(str==null?"":str.toString());
}else if(5 == count) {
//带队人
customerPhoneInfoDo.setLeader(str==null?"":str.toString());
}else if(6 == count) {
//经理
customerPhoneInfoDo.setManager(str==null?"":str.toString());
}
customerPhoneInfoDo.setSign(sign);
count ++;
}
doList.add(customerPhoneInfoDo);
}
//封装好实体集合后,逐个再保存数据
boolean insertCustomerInfo = false;
if(doList.size() > 0) {
for(CustomerPhoneInfoDo customerPhoneInfoDo : doList) {
insertCustomerInfo = customerInfoMapper.insertCustomerInfo(customerPhoneInfoDo);
}
}
return insertCustomerInfo;
}
@Override
public Workbook excelEmportFile(List<ArrayList<String>> readExcel, String fileName, String postfix) {
// 读取数据封装实体
if(readExcel.size() == 0) {
return null;
}
List<CustomerPhoneInfoDo> custorList = getCustorList(readExcel);
List<CustomerPhoneInfoDo> newDoList = new ArrayList<>();
for(CustomerPhoneInfoDo customerPhoneInfoDo : custorList) {
if(newDoList.size() > 0) {
boolean status = true;
//判断该条数据在新的集合中是否存在
for(CustomerPhoneInfoDo cusDo : newDoList) {
if(customerPhoneInfoDo.getPhone() != null) {
if(cusDo.getPhone() != null) {
if(customerPhoneInfoDo.getPhone().equals(cusDo.getPhone())) {
status = false;
}
}
}
}
// 判断该条数据是否存在新的对象中,true则不存在
if(status) {
newDoList.add(customerPhoneInfoDo);
}
} else {
newDoList.add(customerPhoneInfoDo);
}
}
//**根据文件的后缀名选择执行方法整理excel文件**
if(!ExcelUtil.EMPTY.equals(postfix)){
if(ExcelUtil.OFFICE_EXCEL_2003_POSTFIX.equals(postfix)){
return exportXLSExcel(newDoList, fileName);
}else if(ExcelUtil.OFFICE_EXCEL_2010_POSTFIX.equals(postfix)){
return exportXLSXExcel(newDoList, fileName);
}
}
return null;
}
/*
* 将读取的excel文件内容封装
*/
public List<CustomerPhoneInfoDo> getCustorList(List<ArrayList<String>> readExcel){
List<CustomerPhoneInfoDo> doList = new ArrayList<>();
for(List<String> sList : readExcel) {
CustomerPhoneInfoDo customerPhoneInfoDo = new CustomerPhoneInfoDo();
int count = 0;
for(String str : sList) {
if(0 == count) {
// 客户名称
customerPhoneInfoDo.setUserName(str==null?"":str.toString());
}else if(1 == count) {
//电话
customerPhoneInfoDo.setPhone(str==null?"":str.toString());
}else if(2 == count) {
//区域
customerPhoneInfoDo.setRegion(str==null?"":str.toString());
}else if(3 == count) {
//客户需求
customerPhoneInfoDo.setCustomerNeed(str==null?"":str.toString());
}else if(4 == count) {
//宣传人
customerPhoneInfoDo.setPublicist(str==null?"":str.toString());
}else if(5 == count) {
//带队人
customerPhoneInfoDo.setLeader(str==null?"":str.toString());
}else if(6 == count) {
//经理
customerPhoneInfoDo.setManager(str==null?"":str.toString());
}
count ++;
}
doList.add(customerPhoneInfoDo);
}
return doList;
}
public Workbook exportXLSXExcel(List<CustomerPhoneInfoDo> doList,String fileName) {
// 创建Excel表。
Workbook book = new XSSFWorkbook();
// 在当前Excel创建一个子表
Sheet sheet = book.createSheet("DIS"+fileName);
// 设置表头信息(写入Excel左上角是从(0,0)开始的)
Row row = sheet.createRow(0);
row.createCell(0).setCellValue("客户姓名");
row.createCell(1).setCellValue("电话");
row.createCell(2).setCellValue("区域");
row.createCell(3).setCellValue("客户需求");
row.createCell(4).setCellValue("宣传人");
row.createCell(5).setCellValue("带队人");
row.createCell(6).setCellValue("经理");
int count = 1;
for(CustomerPhoneInfoDo CustomerPhoneInfoDo : doList) {
// 行
Row rows = sheet.createRow(count);
// 单元格
// 写入数据
rows.createCell(0).setCellValue(CustomerPhoneInfoDo.getUserName());
rows.createCell(1).setCellValue(CustomerPhoneInfoDo.getPhone());
rows.createCell(2).setCellValue(CustomerPhoneInfoDo.getRegion());
rows.createCell(3).setCellValue(CustomerPhoneInfoDo.getCustomerNeed());
rows.createCell(4).setCellValue(CustomerPhoneInfoDo.getPublicist());
rows.createCell(5).setCellValue(CustomerPhoneInfoDo.getLeader());
rows.createCell(6).setCellValue(CustomerPhoneInfoDo.getManager());
count ++;
}
// 保存excel文件
/*try {
book.write(new FileOutputStream("D://Excel//" + "DIS"+fileName + ".xlsx"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}*/
return book;
}
public Workbook exportXLSExcel(List<CustomerPhoneInfoDo> doList,String fileName) {
// 创建Excel表。
Workbook book = new HSSFWorkbook();
// 在当前Excel创建一个子表
Sheet sheet = book.createSheet("DIS"+fileName);
// 设置表头信息(写入Excel左上角是从(0,0)开始的)
Row row = sheet.createRow(0);
row.createCell(0).setCellValue("客户姓名");
row.createCell(1).setCellValue("电话");
row.createCell(2).setCellValue("区域");
row.createCell(3).setCellValue("客户需求");
row.createCell(4).setCellValue("宣传人");
row.createCell(5).setCellValue("带队人");
row.createCell(6).setCellValue("经理");
int count = 1;
for(CustomerPhoneInfoDo CustomerPhoneInfoDo : doList) {
// 行
Row rows = sheet.createRow(count);
// 单元格
// 写入数据
rows.createCell(0).setCellValue(CustomerPhoneInfoDo.getUserName());
rows.createCell(1).setCellValue(CustomerPhoneInfoDo.getPhone());
rows.createCell(2).setCellValue(CustomerPhoneInfoDo.getRegion());
rows.createCell(3).setCellValue(CustomerPhoneInfoDo.getCustomerNeed());
rows.createCell(4).setCellValue(CustomerPhoneInfoDo.getPublicist());
rows.createCell(5).setCellValue(CustomerPhoneInfoDo.getLeader());
rows.createCell(6).setCellValue(CustomerPhoneInfoDo.getManager());
count ++;
}
// 保存excel文件
/*try {
book.write(new FileOutputStream("D://Excel//" + "DIS"+fileName + ".xls"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} */
return book;
}
}
内容较多也较详细,希望对大家有所帮助,如有高手经过,请给出指点意见。