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

java 解析Excel 工具类 (支持2003&2007)

2013-07-04 15:17 399 查看
2003excel直接采用的jxl进行解析,2007excel其实是个压缩文件,我们用解压缩工具可以打开,里面有对于这个excel结构的完整描述。开始采用的解析方法是直接解析压缩文件里面的excel结构来进行解析,但是处理小数的时候有点问题,最后还是换成poi的方式进行,但是处理小数仍然有问题,还是通过结构里面的描述来解决。各种数据类型基本都测试通过,可以直接使用,jxl和poi的jar包网上可以直接下。废话不多说,直接贴代码。

代码包含2个文件:ExcelParser(解析类),EpointSheet(解析后对于excel封装的对象类)

package com.epoint.utility.excel;

import java.io.File;

import java.io.IOException;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Calendar;

import java.util.Date;

import java.util.List;

import jxl.Cell;

import jxl.CellType;

import jxl.DateCell;

import jxl.NumberCell;

import jxl.Sheet;

import jxl.Workbook;

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;

import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTCellImpl;

import com.epoint.utility.string.StringUtil;

/**

* excel解析工具类(针对2003版本的excel采用jxl进行解析,2007的采用poi解析,

* 解析之后会封装成EpointSheet对象集合

* ,每个EpointSheet代表一个excel的一个sheet,具体属性可以参看EpointSheet类的说明)

*

* @作者 komojoemary

* @version [版本号, 2011-4-7]

* @see [相关类/方法]

* @since [产品/模块版本]

*/

public class ExcelParser

{

/**

* 解析excel文件

*

* @param fileName

* excel文件全路径

* @return List<EpointSheet> 封装好的sheet对象集合

*/

public static List<EpointSheet> parseExcel(String fileName) {

if (StringUtil.getFileName(fileName).indexOf("xlsx") != -1) {

return parse2007ExcelPoi(fileName);

}

else {

return parse2003ExcelJxl(fileName);

}

}

/**

* 采用jxl工具类来解析2003excel

*

* @param fileName

* 文件名字

* @return List<EpointSheet>

*/

private static List<EpointSheet> parse2003ExcelJxl(String fileName) {

List<EpointSheet> result = null;

try {

// 构建1个工作簿对象

Workbook rwb = Workbook.getWorkbook(new File(fileName));

// 获取所有的sheet

Sheet[] allSheet = rwb.getSheets();

if (allSheet != null && allSheet.length > 0) {

result = new ArrayList<EpointSheet>();

for (int i = 0; i < allSheet.length; i++) {

Sheet rs = rwb.getSheet(i);

int row = rs.getRows();

int column = rs.getColumns();

List<Object[]> excelValue = new ArrayList<Object[]>();

String sheetName = rs.getName();

// 解析某个sheet每行的值

for (int j = 0; j < row; j++) {

Object[] rowValue = new Object[column];

for (int m = 0; m < column; m++) {

Cell cell = rs.getCell(m, j);

// 日期

if (cell.getType() == CellType.DATE) {

DateCell dateCell = (DateCell) cell;

rowValue[m] = dateCell.getDate();

}

// 数字

else if (cell.getType() == CellType.NUMBER) {

NumberCell numberCell = (NumberCell) cell;

rowValue[m] = numberCell.getValue();

}

else {

rowValue[m] = cell.getContents().trim();

}

}

excelValue.add(rowValue);

}

// 构建1个sheet模型

EpointSheet sheet = new EpointSheet(sheetName, excelValue);

result.add(sheet);

}

}

}

catch (Exception e) {

e.printStackTrace();

}

return result;

}

/**

* 采用poi工具类来解析2007excel

*

* @param fileName

* 文件名字

* @return List<EpointSheet>

*/

private static List<EpointSheet> parse2007ExcelPoi(String fileName) {

List<EpointSheet> result = null;

try {

result = new ArrayList<EpointSheet>();

// 构造 XSSFWorkbook 对象,strPath 传入文件路径

XSSFWorkbook xwb = new XSSFWorkbook(fileName);

// 循环工作表Sheet

for (int numSheet = 0; numSheet < xwb.getNumberOfSheets(); numSheet++) {

XSSFSheet xSheet = xwb.getSheetAt(numSheet);

if (xSheet == null) {

continue;

}

// 行数

int row = xSheet.getLastRowNum();

// excel的值

List<Object[]> excelValue = new ArrayList<Object[]>();

String sheetName = xSheet.getSheetName();

// 循环行Row

for (int rowNum = 0; rowNum <= row; rowNum++) {

XSSFRow xRow = xSheet.getRow(rowNum);

if (xRow == null) {

continue;

}

// 每一行的值

Object[] rowValue = null;

// 列数

int column = xRow.getLastCellNum();

rowValue = new Object[column];

// 循环列Cell

for (int cellNum = 0; cellNum < column; cellNum++) {

XSSFCell xCell = xRow.getCell(cellNum);

if (xCell != null && !"".equals(xCell)) {

if (xCell.getCellType() == XSSFCell.CELL_TYPE_BOOLEAN) {

rowValue[cellNum] = xCell.getBooleanCellValue();

}

else if (xCell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {

try {

String s = null;

CTCellImpl impl = (CTCellImpl) xCell.getCTCell();

String mm = impl.toString();

String sign = "s=\"";

int startIndex = mm.indexOf(sign);

if (startIndex > -1) {

startIndex += sign.length();

int endIndex = mm.indexOf("\"", startIndex);

s = mm.substring(startIndex, endIndex);

}

rowValue[cellNum] = xCell.getNumericCellValue();

rowValue[cellNum] = getDateFromStr(s, rowValue[cellNum].toString());

}

catch (Exception e) {

rowValue[cellNum] = xCell.getNumericCellValue();

}

}

else {

rowValue[cellNum] = xCell.getStringCellValue();

}

}

}

excelValue.add(rowValue);

}

// 构建1个sheet模型

EpointSheet sheet = new EpointSheet(sheetName, excelValue);

result.add(sheet);

}

}

catch (IOException e) {

e.printStackTrace();

}

return result;

}

// /**

// * 解析2007版本的excel,采用最原始的java解析,根据excel文件内部的信息

// * 这种方法在处理小数时有些问题,比如5位小数,它会取数补足后面的位数,所以改成用POI来解析2007excel

// * @param fileName

// * 文件名字

// * @return List<EpointSheet> 解析好的sheet对象集合

// */

// private static List<EpointSheet> parse2007Excel(String fileName) {

// List<EpointSheet> result = null;

// try {

// // 解压.xlsx

// ZipFile xlsxFile = new ZipFile(new File(fileName));

// DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

// // 先读取sharedStrings.xml这个文件备用

// String[] sharedStrings = null;

// ZipEntry sharedStringXML = xlsxFile.getEntry("xl/sharedStrings.xml");

// if (sharedStringXML != null) {

// InputStream sharedStringXMLIS = xlsxFile.getInputStream(sharedStringXML);

// Document sharedString =

// dbf.newDocumentBuilder().parse(sharedStringXMLIS);

// NodeList str = sharedString.getElementsByTagName("t");

// sharedStrings = new String[str.getLength()];

// for (int n = 0; n < str.getLength(); n++) {

// Element element = (Element) str.item(n);

// sharedStrings
= element.getTextContent();

// }

// }

// // 找到解压文件夹里的workbook.xml,此文件中包含了这张工作表中有几个sheet

// ZipEntry workbookXML = xlsxFile.getEntry("xl/workbook.xml");

// InputStream workbookXMLIS = xlsxFile.getInputStream(workbookXML);

// Document doc = dbf.newDocumentBuilder().parse(workbookXMLIS);

// // 获取一共有几个sheet

// NodeList nl = doc.getElementsByTagName("sheet");

// result = new ArrayList<EpointSheet>();

// // 遍历所有的sheet

// for (int i = 0; i < nl.getLength(); i++) {

// Element element = (Element) nl.item(i);

// // 接着就要到解压文件夹里找到对应的name值的xml文件,比如在workbook.xml中有<sheet

// // name="Sheet1" sheetId="1" r:id="rId1" /> 节点

// // 那么就可以在解压文件夹里的xl/worksheets下找到sheet1.xml,这个xml文件夹里就是包含的表格的内容

// String sheetName = element.getAttribute("name").toLowerCase();

// // 解压获取某个sheet的信息

// ZipEntry sheetXML = xlsxFile.getEntry("xl/worksheets/" + sheetName +

// ".xml");

// if (sheetXML != null) {

// InputStream sheetXMLIS = xlsxFile.getInputStream(sheetXML);

// Document sheetdoc = dbf.newDocumentBuilder().parse(sheetXMLIS);

// // "dimension",解析行列总定义,获取总列数

// NodeList define = sheetdoc.getElementsByTagName("dimension");

// Element totalDefine = (Element) define.item(0);

// String lay = totalDefine.getAttribute("ref");

// int columnNumber = getColumnIndex(lay);

// NodeList rowdata = sheetdoc.getElementsByTagName("row");

// List<Object[]> excelValue = new ArrayList<Object[]>();

// // 解析sheet的行数据

// for (int j = 0; j < rowdata.getLength(); j++) {

// // 得到每个行

// // 行的格式:

// /*

// * <row r="1" spans="1:3">r表示第一行,spans表示有几列 <c r="A1"

// * t="s">/

// * /r表示该列的列表,t="s"个人认为是表示这个单元格的内容可以在sharedStrings

// * .xml这个文件里找到 ,对应的节点 下标就是v节点的值,即0,若没有t属性,则v的值就是该单元格的内容

// * <v>0</v> </c> <c r="B1" t="s"> <v>1</v> </c> <c

// * r="C1" t="s"> <v>2</v> </c> </row>

// */

// // <row r="3" spans="1:5">

// // <c r="E3" t="s">

// // <v>2</v>

// // </c>

// // </row>

// // <row r="5" spans="1:5">

// // <c r="D5">

// // <v>222</v>

// // </c>

// // </row>

// Element row = (Element) rowdata.item(j);

// // 根据行得到每个行中的列

// NodeList columndata = row.getElementsByTagName("c");

// Object[] rowValue = new Object[columnNumber];

// for (int k = 0; k < columndata.getLength(); k++) {

// Element column = (Element) columndata.item(k);

// NodeList values = column.getElementsByTagName("v");

// Element value = (Element) values.item(0);

// if (value != null) {

// int trueColumn = getColumnIndex(column.getAttribute("r")) - 1;

// // 如果是共享字符串则在sharedstring.xml里查找该列的值

// if (column.getAttribute("t") != null &

// column.getAttribute("t").equals("s")) {

// if (sharedStrings != null) {

// rowValue[trueColumn] =

// sharedStrings[Integer.parseInt(value.getTextContent())];

// }

// }

// else {

// Object cellValue = value.getTextContent();

// // 对于小数,2007

// cellValue = getDateFromStr(column.getAttribute("s"),

// cellValue.toString());

// rowValue[trueColumn] = cellValue;

// }

// }

// }

// excelValue.add(rowValue);

// }

// // 构建1个sheet模型

// EpointSheet sheet = new EpointSheet(sheetName, excelValue);

// result.add(sheet);

// }

// }

// }

// catch (Exception e) {

// e.printStackTrace();

// }

// return result;

// }

private static Object getDateFromStr(String s, String cellValue) {

Object date = cellValue;

// 长日期

if ("2".equals(s)) {

date = doubleDate2Str(cellValue, 1);

}

// 短日期

else if ("1".equals(s)) {

date = doubleDate2Str(cellValue, 0);

}

return date;

}

// /**

// * 根据excel的列定义来解析列数:A,B,C,D-----AA,AB,AC---AAA,AAB---

// *

// * @param columnDefine

// * 列定义

// * @return int具体的index

// */

// private static int getColumnIndex(String columnDefine) {

// String column = columnDefine;

// if (columnDefine.indexOf(":") != -1) {

// column = columnDefine.substring(columnDefine.indexOf(":") + 1,

// columnDefine.length());

// }

// // 找到第一个数字出现的位置

// int index = column.length();

// for (int i = 0; i < column.length(); i++) {

// if (Character.isDigit(column.charAt(i))) {

// index = i;

// break;

// }

// }

// // 截掉数字,成为真正的列定义

// column = column.substring(0, index);

// char[] text = column.toCharArray();

// int count = 0;

// int length = text.length;

// for (int i = 0; i < length; i++) {

// // 26的指数次幂*该字符所在位置

// switch (text[i]) {

// case 'A':

// count += Math.pow(26, length - 1 - i);

// break;

// case 'B':

// count += Math.pow(26, (length - 1 - i)) * 2;

// break;

// case 'C':

// count += Math.pow(26, (length - 1 - i)) * 3;

// break;

// case 'D':

// count += Math.pow(26, (length - 1 - i)) * 4;

// break;

// case 'E':

// count += Math.pow(26, (length - 1 - i)) * 5;

// break;

// case 'F':

// count += Math.pow(26, (length - 1 - i)) * 6;

// break;

// case 'G':

// count += Math.pow(26, (length - 1 - i)) * 7;

// break;

// case 'H':

// count += Math.pow(26, (length - 1 - i)) * 8;

// break;

// case 'I':

// count += Math.pow(26, (length - 1 - i)) * 9;

// break;

// case 'J':

// count += Math.pow(26, (length - 1 - i)) * 10;

// break;

// case 'K':

// count += Math.pow(26, (length - 1 - i)) * 11;

// break;

// case 'L':

// count += Math.pow(26, (length - 1 - i)) * 12;

// break;

// case 'M':

// count += Math.pow(26, (length - 1 - i)) * 13;

// break;

// case 'N':

// count += Math.pow(26, (length - 1 - i)) * 14;

// break;

// case 'O':

// count += Math.pow(26, (length - 1 - i)) * 15;

// break;

// case 'P':

// count += Math.pow(26, (length - 1 - i)) * 16;

// break;

// case 'Q':

// count += Math.pow(26, (length - 1 - i)) * 17;

// break;

// case 'R':

// count += Math.pow(26, (length - 1 - i)) * 18;

// break;

// case 'S':

// count += Math.pow(26, (length - 1 - i)) * 19;

// break;

// case 'T':

// count += Math.pow(26, (length - 1 - i)) * 20;

// break;

// case 'U':

// count += Math.pow(26, (length - 1 - i)) * 21;

// break;

// case 'V':

// count += Math.pow(26, (length - 1 - i)) * 22;

// break;

// case 'W':

// count += Math.pow(26, (length - 1 - i)) * 23;

// break;

// case 'X':

// count += Math.pow(26, (length - 1 - i)) * 24;

// break;

// case 'Y':

// count += Math.pow(26, (length - 1 - i)) * 25;

// break;

// case 'Z':

// count += Math.pow(26, (length - 1 - i)) * 26;

// break;

// default:

// break;

// }

// }

// return count;

// }

/**

* 转换excel中间日期类型的文本为日期格式

*

* @param datestr

* 日期的文本值

* @param type

* 0和1,0为短日期,1为长日期

* @return Date 日期

*/

private static Date doubleDate2Str(String datestr, int type) {

String sss = null;

SimpleDateFormat sdf = null;

if (type == 0) {

sss = "1900-01-01";

sdf = new SimpleDateFormat("yyyy-MM-dd");

}

else {

sss = "1900-01-01 00:00";

sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

}

Calendar c = Calendar.getInstance();

try {

c.setTime(sdf.parse(sss));

}

catch (ParseException e) {

e.printStackTrace();

}

String[] st = datestr.split("\\.");

int i1 = Integer.parseInt(st[0]);

// TODO不知道为什么多了2天--张剑峰 2011/4/7 暂时-2处理下

i1 -= 2;

c.add(Calendar.DAY_OF_MONTH, i1);

if (st.length == 2) {

String str = "0." + st[1];

long i2 = (long) (Double.parseDouble(str) * 24 * 3600);

for (int i = 0; i < (i2 / Integer.MAX_VALUE); i++) {

c.add(Calendar.SECOND, Integer.MAX_VALUE);

}

int iii = (int) (i2 % Integer.MAX_VALUE);

c.add(Calendar.SECOND, iii);

}

return c.getTime();

}

public static void main(String[] args) {

List<EpointSheet> allSheet = ExcelParser.parseExcel("d:\\test.xlsx");

if (allSheet != null) {

for (EpointSheet sheet : allSheet) {

List<Object[]> excelValue = sheet.getColumnValue();

if (excelValue != null) {

int rows = excelValue.size() + 1;

for (int i = 0; i < rows; i++) {

// 表头

if (i == 0) {

Object[] head = sheet.getHeader();

for (Object item : head) {

System.out.println("表头----------》" + item.toString());

}

}

// 列值

else {

for (Object[] item : excelValue) {

for (Object value : item) {

if (value == null) {

value = "";

}

System.out.println("列值----------》" + value.toString());

}

}

break;

}

}

}

}

}

}

}

package com.epoint.utility.excel;

import java.util.List;

/**

* epoint excel模型类

*

* @作者 komojoemary

* @version [版本号, 2010-12-2]

* @see [相关类/方法]

* @since [产品/模块版本]

*/

public class EpointSheet

{

/**

* sheet名字

*/

private String sheetName = null;

/**

* excel列头

*/

private Object[] header = null;

/**

* excel列值

*/

private List<Object[]> columnValue = null;

/**

* 是否导出所有数据

*/

private Boolean pagesAll = null;

/**

* 页码

*/

private int pageNumber = 0;

/**

* 一页记录数

*/

private int pageSize = 0;

public EpointSheet(String sheetName, List<Object[]> excelValue) {

this.sheetName = sheetName;

if (excelValue != null) {

int rows = excelValue.size();

if (rows > 0) {

header = excelValue.get(0);

excelValue.remove(0);

columnValue = excelValue;

}

}

}

public Object[] getHeader() {

return header;

}

public void setHeader(Object[] header) {

this.header = header;

}

public List<Object[]> getColumnValue() {

return columnValue;

}

public void setColumnValue(List<Object[]> columnValue) {

this.columnValue = columnValue;

}

public Boolean getPagesAll() {

return pagesAll;

}

public void setPagesAll(Boolean pagesAll) {

this.pagesAll = pagesAll;

}

public int getPageNumber() {

return pageNumber;

}

public void setPageNumber(int pageNumber) {

this.pageNumber = pageNumber;

}

public int getPageSize() {

return pageSize;

}

public void setPageSize(int pageSize) {

this.pageSize = pageSize;

}

public String getSheetName() {

return sheetName;

}

public void setSheetName(String sheetName) {

this.sheetName = sheetName;

}

}

原地址:http://www.cnblogs.com/komojoemary/archive/2011/11/06/excelParser.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: