您的位置:首页 > 编程语言 > Java开发

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

2013-08-20 20:19 253 查看
网上看了很多资料 比价乱 而且 质量参差不齐 ,自己 通过实践和看资料学习

完整的 总结了这两个java里常用的工具类

整合成两个通用的方法

为了取值更加方便我用了 json来 组装数据

其实 最新的poi3.9已经可以用一个方法来 读取excel2003和2007了

但是我为了业务逻辑更加清楚才分开来 ,如果 你觉得还可以重构的更好 可以 发出你的改良后的代码哦

Java代码



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;

}

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

测试

Java代码



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表头的名称")));

//....具体怎么扩展 更加适合你的项目 当然要你们自己思考了 呵呵...

}

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

所需jar.rar (10 MB)
下载次数: 8
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: