public class ExcelUtils {
//导出时,默认每页显示8条数据
public static final int SPLIT_COUNT = 8;
//用Poi导入,获取单元格数据
public static String getCellValue(org.apache.poi.ss.usermodel.Cell cell) {
String cellValue = null;
if (cell != null) {
switch (cell.getCellTypeEnum()) {
case BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case NUMERIC://(整数,小数,日期)
//如果是日期格式
if(HSSFDateUtil.isCellDateFormatted(cell)){
Date date = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());
cellValue = DataFormatUtils.dateToExcel(date);
}else{
//保留1位整数两位小数
DecimalFormat df = new DecimalFormat("#.##");
cellValue = df.format(cell.getNumericCellValue());
String strArr = cellValue.substring(cellValue.lastIndexOf(".")+1,cellValue.length());
//如果小数部分是两个零的话,就不要了
if(strArr.equals("00")){
cellValue = cellValue.substring(0, cellValue.lastIndexOf("."));
}
}
break;
case STRING:
cellValue = String.valueOf(cell.getStringCellValue());
break;
case ERROR:
cellValue = String.valueOf(cell.getErrorCellValue());
break;
default:
break;
}
} else {
cellValue = "";
}
return cellValue;
}
//利用poi导入excel
public static List<ArrayList<String>> initWorkbookAndReadExcelByPOI(File file, String fileName) {
//获得文件后缀名
String extension = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
//获得输入流
FileInputStream inputStream = null;
Workbook workbook = null;
List<ArrayList<String>> list = null;
try {
inputStream = new FileInputStream(file);
if ("xls".equals(extension)) {
workbook = new HSSFWorkbook(inputStream);
list = readExcelByPOI(workbook);
} else if ("xlsx".equals(extension)) {
workbook = new XSSFWorkbook(inputStream);
list = readExcelByPOI(workbook);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("服务网忙,请联系管理员");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("服务网忙,请联系管理员");
}
}
if (workbook != null) {
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("服务网忙,请联系管理员");
}
}
}
return list;
}
/**
*
* @Title: readExcelByPOI
* @Description:HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx
* @param @param workbook
* @param @return 设定文件
* @return ArrayList<ArrayList<String>> 返回类型
* @throws
*/
private static List<ArrayList<String>> readExcelByPOI(Workbook workbook) {
List<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
//封装每一行数据
ArrayList<String> rowList = null;
try {
//获取excel表格的页数
int sheetsNum = workbook.getNumberOfSheets();
for (int i = 0; i < sheetsNum; i++) {
Sheet sheet = workbook.getSheetAt(i);
if (sheet != null) {
//获得最后一行的行号(我测试的数据是两行) 这里lastRowNum=2
int lastRowNum = sheet.getLastRowNum();
//读取行 循环从1开始,是要去掉第一行标题栏
for (int j = 1; j < lastRowNum + 1; j++) {
Row row = sheet.getRow(j);
if (row != null) {
//获得最后一个单元格的索引
short lastCellNum = row.getLastCellNum();
rowList = new ArrayList<String>();
for (int k = 0; k < lastCellNum; k++) {
org.apache.poi.ss.usermodel.Cell cell = row.getCell(k);
rowList.add(ExcelUtils.getCellValue(cell));
}
list.add(rowList);
}
}
}
}
return list;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("服务网忙,请联系管理员");
}
}
/**
*
* @Title: exportExcelByPOI
* @Description: HSSF生成的Excel 97(.xls)格式本身就有每个sheet页不能超过65536条的限制。
XSSF生成Excel 2007 OOXML (.xlsx)格式,条数增加了,但是导出过程中,内存占用率却高于HSSF.
SXSSF是自3.8-beta3版本后,基于XSSF提供的低内存占用的操作EXCEL对象。其原理是可以设置或者手动将内存中的EXCEL行写到硬盘中,这样内存中只保存了少量的EXCEL行进行操作。
* @param @param fieldName 组织的excel的标题栏
* @param @param fieldData 数据
* @param @param outputStream 设定文件
* @return void 返回类型
* @throws
*/
public static void exportExcelByPOI(ArrayList<String> fieldName, ArrayList<ArrayList<String>> fieldData,OutputStream outputStream) {
SXSSFWorkbook workBook = new SXSSFWorkbook();//创建一个工作薄对象
int rows = fieldData.size();//总的记录数
int sheetNum = 0; //指定sheet的页数
if (rows % SPLIT_COUNT == 0) {
sheetNum = rows / SPLIT_COUNT;
} else {
sheetNum = rows / SPLIT_COUNT + 1;
}
for (int i = 1; i <= sheetNum; i++) {//循环2个sheet的值
SXSSFSheet sheet = workBook.createSheet("Page " + i);//使用workbook对象创建sheet对象
SXSSFRow headRow = sheet.createRow((short) 0); //创建行,0表示第一行(本例是excel的标题)
for (int j = 0; j < fieldName.size(); j++) {//循环excel的标题
SXSSFCell cell = headRow.createCell( j);//使用行对象创建列对象,0表示第1列
/**************对标题添加样式begin********************/
//设置列的宽度/
sheet.setColumnWidth(j, 6000);
CellStyle cellStyle = workBook.createCellStyle();//创建列的样式对象
Font font = workBook.createFont();//创建字体对象
//字体加粗
font.setBold(true);
//字体颜色变红
font.setColor(HSSFColor.RED.index);
//如果font中存在设置后的字体,并放置到cellStyle对象中,此时该单元格中就具有了样式字体
cellStyle.setFont(font);
/**************对标题添加样式end********************/
//添加样式
cell.setCellType(CellType.STRING);
if(fieldName.get(j) != null){
//将创建好的样式放置到对应的单元格中
cell.setCellStyle(cellStyle);
//为标题中的单元格设置值
cell.setCellValue((String) fieldName.get(j));
}else{
cell.setCellValue("-");
}
}
//分页处理excel的数据,遍历所有的结果
for (int k = 0; k < (rows < SPLIT_COUNT ? rows : SPLIT_COUNT); k++) {
//如果数据超出总的记录数的时候,就退出循环
if (((i - 1) * SPLIT_COUNT + k) >= rows)
break;
SXSSFRow row = sheet.createRow((short) (k + 1));//创建1行
//分页处理,获取每页的结果集,并将数据内容放入excel单元格
ArrayList<String> rowList = (ArrayList<String>) fieldData.get((i - 1) * SPLIT_COUNT + k);
for (int n = 0; n < rowList.size(); n++) {//遍历某一行的结果
SXSSFCell cell = row.createCell( n);//使用行创建列对象
if(rowList.get(n) != null){
cell.setCellValue((String) rowList.get(n).toString());
}else{
cell.setCellValue("");
}
}
}
}
try {
workBook.write(outputStream);
workBook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//用jxl导入
public static String getCellValue(Cell cell) {
String cellValue = null;
if (cell != null) {
jxl.CellType type = cell.getType();
if (type == jxl.CellType.DATE) {
DateCell dateCell = (DateCell) cell;
java.util.Date importdate = dateCell.getDate();/**如果excel是日期格式的话需要减去8小时*/
long eighthour = 8*60*60*1000;
/**在当前日期上减8小时*/
long time = importdate.getTime()-eighthour;
java.util.Date date = new java.util.Date();
date.setTime(time);
cellValue = DataFormatUtils.dateToExcel(date);
}else if(type == jxl.CellType.NUMBER) {
NumberCell numberCell = (NumberCell) cell;
//保留1位整数两位小数
DecimalFormat df = new DecimalFormat("#.##");
cellValue = df.format(numberCell.getValue());
} else {
cellValue = cell.getContents();
}
} else{
cellValue = "";
}
return cellValue;
}
//jxl导入
public static List<ArrayList<String>> readExcelByJXl(File file){
InputStream in = null;
jxl.Workbook workbook = null; //jxl的核心对象
List<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
try {
if (file == null) {
throw new Exception("文件为空!");
}
//将文件读入到输入流中
in = new FileInputStream(file);
//从输入流中获取WorkBook对象,加载选中的excel文件
workbook = jxl.Workbook.getWorkbook(in);
//通过workbook对象获取sheet对象,此时sheet对象是一个数组
jxl.Sheet[] sheet = workbook.getSheets();
if (sheet != null) {
for (int i = 0; i < sheet.length; i++) {
int count = i+1;
if (!sheet[i].getName().equalsIgnoreCase("Page"+count)) {
throw new Exception("指定文件中不包含名称为User的sheet,请重新指定!");
}
//使用sheet对象用来获取每1行,从1开始表示要去掉excel的标题,遍历行
for (int j = 1; j < sheet[i].getRows(); j++) {
ArrayList<String> rowList = new ArrayList<String>();
//遍历列 使用sheet对象用来获取每1列,从0开始表示从第1列开始
for (int k = 0; k < sheet[i].getColumns(); k++) {
//k表示列的号,j表示行的号
Cell cell = sheet[i].getCell(k, j);
String content = getCellValue(cell);
//将excel获取到的值赋值rowList
rowList.add(content);
}
list.add(rowList);
}
}
}
return list;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("服务网忙,请联系管理员");
} finally {
if (workbook != null) {
workbook.close();
}
if (in != null) {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("服务网忙,请联系管理员");
}
}
}
}
//用jxl导出
public static void exportExcelByJXL(ArrayList<String> fieldName, ArrayList<ArrayList<String>> fieldData,OutputStream outputStream) {
WritableWorkbook workbook = null;
//指定标题字体样式,点大小,字体粗细,斜体,下划线样式和颜色。
WritableFont head = new WritableFont(WritableFont.ARIAL,
WritableFont.DEFAULT_POINT_SIZE, WritableFont.BOLD,
false, UnderlineStyle.NO_UNDERLINE, Colour.RED);
WritableCellFormat cellFormatHead = new WritableCellFormat(head);
WritableFont data = new WritableFont(WritableFont.ARIAL,
WritableFont.DEFAULT_POINT_SIZE, WritableFont.NO_BOLD,
false, UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.BLACK);
WritableCellFormat cellFormatData = new WritableCellFormat(data);
try {
workbook = jxl.Workbook.createWorkbook(outputStream);
int rows = fieldData.size();//总的记录数
int sheetNum = 0; //指定sheet的页数
if (rows % SPLIT_COUNT == 0) {
sheetNum = rows / SPLIT_COUNT;
} else {
sheetNum = rows / SPLIT_COUNT + 1;
}
for (int i = 0; i < sheetNum; i++) {//循环2个sheet的值
//使用workbook对象创建sheet对象,是从0开始
WritableSheet sheet = workbook.createSheet("Page " + i, i);
//循环excel的标题
int columnSize = fieldName.size();
for (int j = 0; j < columnSize; j++) {
String content = fieldName.get(j);
//设置列的宽度/
CellView cellView = new CellView();
//根据内容自动设置列宽
cellView.setAutosize(true);
sheet.setColumnView(j, cellView);
//参数分别是列,行,文本内容,样式
sheet.addCell(new Label(j, 0, content, cellFormatHead));
}
//分页处理excel的数据,遍历所有的结果
for (int k = 1; k <= (rows < SPLIT_COUNT ? rows : SPLIT_COUNT); k++) {
//如果数据超出总的记录数的时候,就退出循环
if ((i * SPLIT_COUNT + k-1) >= rows)
break;
//分页处理,获取每页的结果集,并将数据内容放入excel单元格
ArrayList<String> rowList = (ArrayList<String>) fieldData.get(i * SPLIT_COUNT + k-1);
Label label = null;
for (int n = 0; n < rowList.size(); n++) {//遍历某一行的结果
if(rowList.get(n) != null){
label = new Label(n, k, rowList.get(n).toString(), cellFormatData);
}else{
label = new Label(n, k,"");
}
sheet.addCell(label);
}
}
}
workbook.write();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("服务网忙,请联系管理员");
} finally {
if (workbook !=null) {
try {
workbook.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("服务网忙,请联系管理员");
}
}
}
}
}
写的这个工具类分别用了JXL和POI,都测试了一下,都能跑,需要说明一下,JXL不支持的.XLSX的文件