java用poi解析excel2003和2007并封装成对象返回

网上看了很多资料 比价乱 而且 质量参差不齐 ,自己 通过实践和看资料学习

完整的 总结了这两个java里常用的工具类
整合成两个通用的方法

为了取值更加方便我用了 json来 组装数据
其实 最新的poi3.9已经可以用一个方法来 读取excel2003和2007了
但是我为了业务逻辑更加清楚才分开来 ,如果 你觉得还可以重构的更好 可以 发出你的改良后的代码哦



import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
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;


/**
* Excel 操作工具类 其中涉及几个文件流操作和转换
* @author zqb
*
* 2013-8-2
*/
public class ExcelUtil {
private static POIFSFileSystem fs;
private static HSSFWorkbook wb;
private static HSSFSheet sheet;
private static HSSFRow row;
private static FileInputStream input;
private static String[] excleTitle;

public static boolean isNum(String str) {
return str.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
}

/**
* 根据文件路径读取Excel数据内容 返回map
* @param excelPath
* @return
*/
public static Map readExcelContent(String excelPath) {
Map contentJson = new LinkedHashMap();
String excelStr = "";// excel 内容
try {
input = new FileInputStream(new File(excelPath));

fs = new POIFSFileSystem(input);
wb = new HSSFWorkbook(fs);
sheet = wb.getSheetAt(0);
int rowNum = sheet.getLastRowNum(); // 得到总行数
row = sheet.getRow(0);// 得到标题的内容对象。
int colNum = row.getPhysicalNumberOfCells();// 得到每行的列数。

excleTitle = new String[colNum];
for (int i = 0; i < colNum; i++) {

excleTitle[i] = getStringCellValue(row.getCell((short) i));
}

// 正文内容应该从第二行开始,第一行为表头的标题
for (int i = 1; i <= rowNum; i++) {

row = sheet.getRow(i);
int j = 0;

while (j < colNum) {
String v = "";
if (j + 1 == colNum) {
String vs = getStringCellValue(row.getCell((short) j))
.trim();
if (vs.indexOf(".") > -1) {
if (isNum(vs)) { // 是否是数字

if (vs.endsWith("0")) {

v = vs.substring(0, vs.indexOf("."));
}

} else {
v = vs.trim();
}

} else {
v = vs.trim();
}
excelStr += v;
} else {

String vs = getStringCellValue(row.getCell((short) j))
.trim()
+ "&";
if (vs.indexOf(".") > -1) {
if (isNum(vs)) { // 是否是数字
if (vs.endsWith("0")) { // 处理用poi读取excel整数后面加.0的格式化
v = vs.substring(0, vs.indexOf("."));
}

} else {
v = vs.trim();
}

} else {
v = vs.trim();
}
excelStr += v;
}

j++;

}
String excelstrArray[] = excelStr.split("&", -1); // 每行数据

Map params = new LinkedHashMap();
for (int k = 0; k < excelstrArray.length; k++) {
params.put(excleTitle[k], excelstrArray[k]);
}
JSONObject jsonObject = JSONObject.fromObject(params);
contentJson.put(i, jsonObject);

// content.put(i, excelStr);

excelStr = "";
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return contentJson;
}


/**
* 根据文件流读取Excel数据内容 返回map 2003
* @param input
* @return
*/
public static Map readExcelContent(
InputStream input) {// 读取Excel数据内容
Map contentJson = new LinkedHashMap();
String excelStr = "";// excel 内容
try {


fs = new POIFSFileSystem(input);
wb = new HSSFWorkbook(fs);
sheet = wb.getSheetAt(0);
int rowNum = sheet.getLastRowNum(); // 得到总行数
row = sheet.getRow(0);// 得到标题的内容对象。
int colNum = row.getPhysicalNumberOfCells();// 得到每行的列数。

excleTitle = new String[colNum];
for (int i = 0; i < colNum; i++) {

excleTitle[i] = getStringCellValue(row.getCell((short) i));
}

// 正文内容应该从第二行开始,第一行为表头的标题
for (int i = 1; i <= rowNum; i++) {

row = sheet.getRow(i);
int j = 0;

while (j < colNum) {
String v = "";
if (j + 1 == colNum) {
String vs = getStringCellValue(row.getCell((short) j))
.trim();
if (vs.indexOf(".") > -1) {
if (isNum(vs)) { // 是否是数字

if (vs.endsWith("0")) {

v = vs.substring(0, vs.indexOf("."));
}

} else {
v = vs.trim();
}

} else {
v = vs.trim();
}
excelStr += v;
} else {

String vs = getStringCellValue(row.getCell((short) j))
.trim()
+ "&";
if (vs.indexOf(".") > -1) {
if (isNum(vs)) { // 是否是数字
if (vs.endsWith("0")) { // 处理用poi读取excel整数后面加.0的格式化
v = vs.substring(0, vs.indexOf("."));
}

} else {
v = vs.trim();
}

} else {
v = vs.trim();
}
excelStr += v;
}

j++;

}
String excelstrArray[] = excelStr.split("&", -1); // 每行数据

Map params = new LinkedHashMap();
for (int k = 0; k < excelstrArray.length; k++) {
params.put(excleTitle[k], excelstrArray[k]);
}
JSONObject jsonObject = JSONObject.fromObject(params);
contentJson.put(i, jsonObject);

// content.put(i, excelStr);

excelStr = "";
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return contentJson;
}

/**
* 读取Office 2007 excel
* */
public static Map read2007Excels(InputStream input)
throws IOException {
Map contentJson = new LinkedHashMap();
// 构造 XSSFWorkbook 对象,strPath 传入文件路径
XSSFWorkbook xwb = new XSSFWorkbook(input);
// 读取第一章表格内容
XSSFSheet sheet = xwb.getSheetAt(0);
Object value = null;
XSSFRow row = null;
XSSFCell cell = null;

XSSFRow headerrow = sheet.getRow(0); // 表头 得到标题的内容对象
int colNum = headerrow.getPhysicalNumberOfCells();// 得到每行的列数。
excleTitle = new String[colNum];
for (int i = 0; i < colNum; i++) {

excleTitle[i] = getStringCellValue(headerrow.getCell((short) i));
}

// System.out.println(sheet.getPhysicalNumberOfRows());
// 循环内容项 不循环标题 所以+1
for (int i = sheet.getFirstRowNum() + 1; i <= sheet
.getPhysicalNumberOfRows(); i++) {
row = sheet.getRow(i);
if (row == null) {
continue;
}
List linked = new LinkedList();
for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
cell = row.getCell(j);
if (null != cell) {
value = getStringCellValue(cell);
}

linked.add(StringUtil.stringIsNull(value));
}
Map params = new LinkedHashMap();
for (int j = 0; j < linked.size(); j++) {
params.put(excleTitle[j], linked.get(j));
}
JSONObject jsonObject = JSONObject.fromObject(params);
contentJson.put(i, jsonObject);
}

return contentJson;
}

/**
* 根据(字节串(或叫字节数组)变成输入流的形式)读取Excel数据内容 返回map
* @param input
* @return
*/
public static Map readExcelContent(
ByteArrayInputStream input) {// 读取Excel数据内容
// Map content = new HashMap();
Map contentJson = new LinkedHashMap();
String excelStr = "";// excel 内容
try {

// ByteArrayInputStream is = new ByteArrayInputStream( new byte[1000]);

fs = new POIFSFileSystem(input);
wb = new HSSFWorkbook(fs);
sheet = wb.getSheetAt(0);
int rowNum = sheet.getLastRowNum(); // 得到总行数
row = sheet.getRow(0);// 得到标题的内容对象。
int colNum = row.getPhysicalNumberOfCells();// 得到每行的列数。

excleTitle = new String[colNum];
for (int i = 0; i < colNum; i++) {

excleTitle[i] = getStringCellValue(row.getCell((short) i));
}

// 正文内容应该从第二行开始,第一行为表头的标题
for (int i = 1; i <= rowNum; i++) {

row = sheet.getRow(i);
int j = 0;

while (j < colNum) {
String v = "";
if (j + 1 == colNum) {
String vs = getStringCellValue(row.getCell((short) j))
.trim();
if (vs.indexOf(".") > -1) {
if (isNum(vs)) { // 是否是数字

if (vs.endsWith("0")) {

v = vs.substring(0, vs.indexOf("."));
}

} else {
v = vs.trim();
}

} else {
v = vs.trim();
}
excelStr += v;
} else {

String vs = getStringCellValue(row.getCell((short) j))
.trim()
+ "&";
if (vs.indexOf(".") > -1) {
if (isNum(vs)) { // 是否是数字
if (vs.endsWith("0")) { // 处理用poi读取excel整数后面加.0的格式化
v = vs.substring(0, vs.indexOf("."));
}

} else {
v = vs.trim();
}

} else {
v = vs.trim();
}
excelStr += v;
}

j++;

}
String excelstrArray[] = excelStr.split("&", -1); // 每行数据

Map params = new LinkedHashMap();
for (int k = 0; k < excelstrArray.length; k++) {
params.put(excleTitle[k], excelstrArray[k]);
}
JSONObject jsonObject = JSONObject.fromObject(params);
contentJson.put(i, jsonObject);

// content.put(i, excelStr);

excelStr = "";
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return contentJson;
}

/**
* 获取单元格数据内容为字符串类型的数据
* @param cell
* @return
*/
private static String getStringCellValue(HSSFCell cell) {
String strCell = "";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
strCell = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_NUMERIC:
strCell = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
strCell = String.valueOf(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
strCell = "";
break;
default:
strCell = "";
break;
}
if (strCell.equals("") || strCell == null) {
return "";
}
if (cell == null) {
return "";
}
return strCell;
}

/**
* 获取单元格数据内容为日期类型的数据
* @param cell
* @return
*/
private static String getDateCellValue(HSSFCell cell) {
String result = "";
try {
int cellType = cell.getCellType();
if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
Date date = cell.getDateCellValue();
result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1)
+ "-" + date.getDate();
} else if (cellType == HSSFCell.CELL_TYPE_STRING) {
String date = getStringCellValue(cell);
result = date.replaceAll("[年月]", "-").replace("日", "").trim();
} else if (cellType == HSSFCell.CELL_TYPE_BLANK) {
result = "";
}
} catch (Exception e) {
System.out.println("日期格式不正确!");
e.printStackTrace();
}
return result;
}

/**
* 根据byte数组,生成文件
*/
public static void getFile(byte[] bfile, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
File dir = new File(filePath);
if (!dir.exists() && dir.isDirectory()) {// 判断文件目录是否存在
dir.mkdirs();
}
file = new File(filePath + "\\" + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bfile);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}

// 从byte[]转file
public static File getFileFromBytes(byte[] b, String outputFile) {
BufferedOutputStream stream = null;
File file = null;
try {
file = new File(outputFile);
if (!file.exists() && file.isDirectory()) {// 判断文件目录是否存在
file.mkdirs(); //mkdirs() 可以在不存在的目录中创建文件夹。诸如:a\\b,既可以创建多级目录。
}

FileOutputStream fstream = new FileOutputStream(file);
stream = new BufferedOutputStream(fstream);
stream.write(b);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return file;
}

/**
* 读取Office 2007 excel
* */
private static Map read2007Excels(File file)
throws IOException {
Map contentJson = new LinkedHashMap();
// 构造 XSSFWorkbook 对象,strPath 传入文件路径
XSSFWorkbook xwb = new XSSFWorkbook(new FileInputStream(file));
// 读取第一章表格内容
XSSFSheet sheet = xwb.getSheetAt(0);
Object value = null;
XSSFRow row = null;
XSSFCell cell = null;

XSSFRow headerrow = sheet.getRow(0); // 表头 得到标题的内容对象
int colNum = headerrow.getPhysicalNumberOfCells();// 得到每行的列数。
excleTitle = new String[colNum];
for (int i = 0; i < colNum; i++) {

excleTitle[i] = getStringCellValue(headerrow.getCell((short) i));
}

// System.out.println(sheet.getPhysicalNumberOfRows());
// 循环内容项 不循环标题 所以+1
for (int i = sheet.getFirstRowNum() + 1; i <= sheet
.getPhysicalNumberOfRows(); i++) {
row = sheet.getRow(i);
if (row == null) {
continue;
}
List linked = new LinkedList();
for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
cell = row.getCell(j);
if (null != cell) {
value = getStringCellValue(cell);
}

linked.add(StringUtil.stringIsNull(value));
}
Map params = new LinkedHashMap();
for (int j = 0; j < linked.size(); j++) {
params.put(excleTitle[j], linked.get(j));
}
JSONObject jsonObject = JSONObject.fromObject(params);
contentJson.put(i, jsonObject);
}

return contentJson;
}

/**
* 获取单元格数据内容为字符串类型的数据
*
* @param cell
* @return
*/
private static String getStringCellValue(XSSFCell cell) {
String strCell = "";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
strCell = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_NUMERIC:
strCell = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
strCell = String.valueOf(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
strCell = "";
break;
default:
strCell = "";
break;
}
if (strCell.equals("") || strCell == null) {
return "";
}
if (cell == null) {
return "";
}
return strCell;
}

/**
* 获得指定文件的byte数组
*/
public static byte[] getBytes(String filePath) {
byte[] buffer = null;
try {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer;
}



调用的时候 根据文件后缀名分别调用不同的方法就行

测试


Map content = new LinkedHashMap();
if (version.equals("2003")) {
content = ExcelUtil.readExcelContent(fileinput);
} else if (version.equals("2007")) {
content = ExcelUtil.read2007Excels(fileinput);
}

for (Map.Entry entry : content.entrySet()) {
System.out.println(entry.getValue().get("excel表头的名称")));
//这个循环里可以把这些值 组装到一个 po里
//这样取值更加方便
//比如 Po p=new Po(); po.setEntityName(entry.getValue().get("excel表头的名称")));
//....具体怎么扩展 更加适合你的项目 当然要你们自己思考了 呵呵...
}



这样可以获取对应表头的值

你可能感兴趣的:(java)