Java解析Excel表格(支持xls和xlsx格式),并转换为Json数据

时间:2022-09-13 13:59:56

首先,我们看一下我们程序的结构和运行结果:

1. 项目结构:

Java解析Excel表格(支持xls和xlsx格式),并转换为Json数据


2. studen.xls视图:

Java解析Excel表格(支持xls和xlsx格式),并转换为Json数据


3. user.xls视图:

Java解析Excel表格(支持xls和xlsx格式),并转换为Json数据

4. 解析结果:

(1)students.xlsx 解析结果:

[
    {
        "name": "Jack",
        "age": "12.0",
        "hight": "155.6",
        "dream": "当一名科学家"
    },
    {
        "name": "mara",
        "age": "14.0",
        "hight": "162.0",
        "dream": "去太空旅行"
    }
]

(2)user.xls解析结果:

[
    {
        "name": "张三",
        "age": "12.0",
        "sex": "男",
        "birth": "33495.0",
        "city": "成都",
        "money": "17.5"
    },
    {
        "name": "李四",
        "age": "13.0",
        "sex": "女",
        "birth": "1991-06-05 00:00:00",
        "city": "北京",
        "money": "17.5"
    },
    {
        "name": "王五",
        "age": "15.0",
        "sex": "男",
        "birth": "33492",
        "city": "上海",
        "money": "17.5"
    },
    {
        "name": "刘六",
        "age": "12.0",
        "sex": "女",
        "birth": "1991-06-05 12:35:00",
        "city": "西安",
        "money": "23.6"
    }
]


接下来,正式揭开代码面纱:

1. 准备jar包(Maven依赖):

PS:不是Maven工程的请戳这里获取Jar包

<!-- Junit(测试用,非必须) -->
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>3.8.1</version>
	<scope>test</scope>
</dependency>

<!-- Poi(解析Excle表格用) -->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.11-beta1</version>
</dependency>

<!-- Json(组装Json用)-->
<dependency>
	<groupId>net.sf.json-lib</groupId>
	<artifactId>json-lib</artifactId>
	<version>2.4</version>
	<classifier>jdk15</classifier>
</dependency>

2. 功能类代码:

package com.zyq.excel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
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 net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class ExcelTool {

	public static final String XLSX = ".xlsx";
	public static final String XLS=".xls";

	/**
	 * 获取Excel文件(.xls和.xlsx都支持)
	 * @param file
	 * @return  解析excle后的Json数据
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 * @throws InvalidFormatException 
	 */
	public static JSONArray readExcel(File file) throws FileNotFoundException, IOException, InvalidFormatException{		
		int res = checkFile(file);
		if (res == 0) {
			throw new NullPointerException("the file is null.");
		}else if (res == 1) {
			return readXLSX(file);		
		}else if (res == 2) {
			return readXLS(file);
		}
		throw new IllegalAccessError("the file["+file.getName()+"] is not excel file.");
	}

	/**
	 * 判断File文件的类型
	 * @param file 传入的文件
	 * @return 0-文件为空,1-XLSX文件,2-XLS文件,3-其他文件
	 */
	public static int checkFile(File file){
		if (file==null) {
			return 0;
		}		
		String flieName = file.getName();		
		if (flieName.endsWith(XLSX)) {
			return 1;
		}
		if (flieName.endsWith(XLS)) {
			return 2;
		}		
		return 3;
	}

	/**
	 * 读取XLSX文件
	 * @param file
	 * @return
	 * @throws IOException 
	 * @throws InvalidFormatException 
	 */
	public static JSONArray readXLSX(File file) throws InvalidFormatException, IOException{
		Workbook book = new XSSFWorkbook(file);
		Sheet sheet = book.getSheetAt(0); 
		return read(sheet, book);
	}

	/**
	 * 读取XLS文件
	 * @param file
	 * @return
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	public static JSONArray readXLS(File file) throws FileNotFoundException, IOException{
		POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(file));  
		Workbook book = new HSSFWorkbook(poifsFileSystem);        
		Sheet sheet = book.getSheetAt(0);
		return read(sheet, book);
	}

	/**
	 * 解析数据
	 * @param sheet 表格sheet对象
	 * @param book 用于流关闭
	 * @return
	 * @throws IOException
	 */
	public static JSONArray read(Sheet sheet,Workbook book) throws IOException{
		int rowStart = sheet.getFirstRowNum();	// 首行下标
		int rowEnd = sheet.getLastRowNum();	// 尾行下标		
		// 如果首行与尾行相同,表明只有一行,直接返回空数组
		if (rowStart == rowEnd) {
			book.close();
			return new JSONArray();
		}	
		// 获取第一行JSON对象键
		Row firstRow = sheet.getRow(rowStart);
		int cellStart = firstRow.getFirstCellNum(); 
		int cellEnd = firstRow.getLastCellNum();		
		Map<Integer, String> keyMap = new HashMap<Integer, String>();
		for (int j = cellStart; j < cellEnd; j++) {
			keyMap.put(j,getValue(firstRow.getCell(j), rowStart, j, book, true));
		}
		// 获取每行JSON对象的值
		JSONArray array = new JSONArray();
		for(int i = rowStart+1; i <= rowEnd ; i++) {  		
			Row eachRow = sheet.getRow(i);
			JSONObject obj = new JSONObject();
			StringBuffer sb = new StringBuffer();
			for (int k = cellStart; k < cellEnd; k++) {
				if (eachRow != null) {
					String val = getValue(eachRow.getCell(k), i, k, book, false);
					sb.append(val);		// 所有数据添加到里面,用于判断该行是否为空
					obj.put(keyMap.get(k),val);			
                }				
			}
			if (sb.toString().length() > 0) {
				array.add(obj);
            }
		}
		book.close();
		return array; 
	}

	/**
	 * 获取每个单元格的数据
	 * @param cell 单元格对象
	 * @param rowNum 第几行
	 * @param index 该行第几个
	 * @param book 主要用于关闭流
	 * @param isKey 是否为键:true-是,false-不是。 如果解析Json键,值为空时报错;如果不是Json键,值为空不报错
	 * @return
	 * @throws IOException
	 */
	public static String getValue(Cell cell,int rowNum,int index,Workbook book,boolean isKey) throws IOException{

		// 空白或空
		if (cell == null || cell.getCellType()==Cell.CELL_TYPE_BLANK ) {
			if (isKey) {
				book.close();
				throw new NullPointerException(String.format("the key on row %s index %s is null ", ++rowNum,++index));
            }else{
            	return "";
            }			
		}

		// 0. 数字 类型
		if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
			if (HSSFDateUtil.isCellDateFormatted(cell)) {
				Date date = cell.getDateCellValue();
				DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				return df.format(date);
			}			
			String val = cell.getNumericCellValue()+"";
			val = val.toUpperCase();			
			if (val.contains("E")) {
				val = val.split("E")[0].replace(".", "");
            }
			return val;
		}		

		// 1. String类型
		if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
			String val = cell.getStringCellValue();
			if (val == null || val.trim().length()==0) {
				if (book != null) {
					book.close();
				}
				return "";
			}
			return val.trim();
		}

		// 2. 公式 CELL_TYPE_FORMULA
		if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
			return cell.getStringCellValue();
		}

		// 4. 布尔值 CELL_TYPE_BOOLEAN
		if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
			return cell.getBooleanCellValue()+"";
		}

		// 5.	错误 CELL_TYPE_ERROR
		return "";
	}
}


3. 测试代码:

package com.zyq.excel;

import java.io.File;

import junit.framework.TestCase;

public class Test extends TestCase{
	
	public void readTest() throws Exception{	
		File f1 = new File("user.xlsx");
		File f2 = new File("student.xls");
		System.out.println(ExcelTool.readExcel(f1));
		System.out.println(ExcelTool.readExcel(f2));
	}

}


最后,附上Demo完整实例下载链接: 详情点击!