網上看了不少資料 比價亂 並且 質量良莠不齊 ,本身 經過實踐和看資料學習
完整的 總結了這兩個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<Integer, JSONObject> readExcelContent(String excelPath) {
Map<Integer, JSONObject> contentJson = new LinkedHashMap<Integer, JSONObject>();
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<String, String> params = new LinkedHashMap<String, String>();
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<Integer, JSONObject> readExcelContent(
InputStream input) {// 讀取Excel數據內容
Map<Integer, JSONObject> contentJson = new LinkedHashMap<Integer, JSONObject>();
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<String, String> params = new LinkedHashMap<String, String>();
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<Integer, JSONObject> read2007Excels(InputStream input)
throws IOException {
Map<Integer, JSONObject> contentJson = new LinkedHashMap<Integer, JSONObject>();
// 構造 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<String> linked = new LinkedList<String>();
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<String, String> params = new LinkedHashMap<String, String>();
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<Integer, JSONObject> readExcelContent(
ByteArrayInputStream input) {// 讀取Excel數據內容
// Map<Integer, String> content = new HashMap<Integer, String>();
Map<Integer, JSONObject> contentJson = new LinkedHashMap<Integer, JSONObject>();
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<String, String> params = new LinkedHashMap<String, String>();
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<Integer, JSONObject> read2007Excels(File file)
throws IOException {
Map<Integer, JSONObject> contentJson = new LinkedHashMap<Integer, JSONObject>();
// 構造 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<String> linked = new LinkedList<String>();
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<String, String> params = new LinkedHashMap<String, String>();
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<Integer, JSONObject> content = new LinkedHashMap<Integer, JSONObject>();
if (version.equals("2003")) {
content = ExcelUtil.readExcelContent(fileinput);
} else if (version.equals("2007")) {
content = ExcelUtil.read2007Excels(fileinput);
}
for (Map.Entry<Integer, JSONObject> entry : content.entrySet()) {
System.out.println(entry.getValue().get("excel表頭的名稱")));
//這個循環裏能夠把這些值 組裝到一個 po裏
//這樣取值更加方便
//好比 Po p=new Po(); po.setEntityName(entry.getValue().get("excel表頭的名稱")));
//....具體怎麼擴展 更加適合你的項目 固然要大家本身思考了 呵呵...
}
這樣能夠獲取對應表頭的值