您的位置:首页 > 运维架构 > Apache

Apache POI组件操作Excel(导入和导出)

2014-04-25 11:12 507 查看
 

Apache的POI组件是Java操作Microsoft Office办公套件的强大API,其中对Word,Excel和PowperPoint都有支持,当然使用较多的还是Excel,因为Word和PowerPoint用程序动态操作的应用较少。那么本文就结合POI来介绍一下操作Excel的方法。

这里介绍两种方法实现excel的操作。代码都有注释,可以很清楚的看懂,一种是循环遍历excel表格,这个要自己定位一个excel的起点。另外一种是通过java反射机制实现的,根据表头来实现映射。具体代码如下:

第一种:

 

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
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.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.util.Region;

public class ExcelUtils {

/**
* 读取EXCEL
* @param firstrow 从第几行开始读取
* @return 读取后返回数组
*/
@SuppressWarnings("deprecation")
public static String[][] importExcel(File file, int firstrow)
throws FileNotFoundException, IOException {
List<String[]> result = new ArrayList<String[]>();
int rowSize = 0;
BufferedInputStream in = new BufferedInputStream(new FileInputStream(
file));
POIFSFileSystem fs = new POIFSFileSystem(in);
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFCell cell = null;
for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {
HSSFSheet st = wb.getSheetAt(sheetIndex);
for (int rowIndex = firstrow; rowIndex <= st.getLastRowNum(); rowIndex++) {
HSSFRow row = st.getRow(rowIndex);
if (row == null) {
continue;
}
int tempRowSize = row.getLastCellNum() + 1;
if (tempRowSize > rowSize) {
rowSize = tempRowSize;
}
String[] values = new String[rowSize];
Arrays.fill(values, "");
boolean hasValue = false;

for (short columnIndex = 0; columnIndex <= row.getLastCellNum(); columnIndex++) {
String value = "";
cell = row.getCell(columnIndex);
if (cell != null) {
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING://读取的格式为字符串
value = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_NUMERIC://读取的格式为数组
//如果格式为日期格式,自定义格式输出
if (HSSFDateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
if (date != null) {
value = new SimpleDateFormat("yyyy-MM-dd")
.format(date);
} else {
value = "";
}
} else {
//如果格式为数值,自定义格式输出
value = new DecimalFormat().format(cell
.getNumericCellValue());
}
break;
case HSSFCell.CELL_TYPE_FORMULA:
// 导入时如果为公式生成的数据则无值
value = "";
break;
// 导入时如果为空
case HSSFCell.CELL_TYPE_BLANK:
break;
case HSSFCell.CELL_TYPE_ERROR:
value = "";
break;
// 导入时如果为BOOLEAN型 自定义格式输出
case HSSFCell.CELL_TYPE_BOOLEAN:
value = (cell.getBooleanCellValue() == true ? "Y"
: "N");
break;
default:
value = "";
}
}

values[columnIndex] = rightTrim(value);
hasValue = true;
}

if (hasValue) {
result.add(values);
}
}

in.close();
String[][] returnArray = new String[result.size()][rowSize];
for (int i = 0; i < returnArray.length; i++) {
returnArray[i] = (String[]) result.get(i);
}
return returnArray;
}
return null;

}

/**
* 去掉字符串右边的空格
*
* @param str 要处理的字符串
* @return 处理后的字符串
*/
public static String rightTrim(String str) {
if (str == null) {
return "";
}
int length = str.length();
for (int i = length - 1; i >= 0; i--) {
if (str.charAt(i) != 0x20) {
break;
}
length--;
}
return str.substring(0, length);
}

/**
* 创建通用EXCEL头部
*
* @param headString 头部显示的字符
* @param colSum 该报表的列数
*/
@SuppressWarnings("deprecation")
public void createNormalHead(String headString, int colSum,HSSFSheet sheet,HSSFWorkbook wb) {

HSSFRow row1 = sheet.createRow(0);

// 设置第一行
HSSFCell cell = row1.createCell(0);
row1.setHeight((short) 800);

// 定义单元格为字符串类型
cell.setCellType(HSSFCell.ENCODING_UTF_16);
cell.setCellValue(new HSSFRichTextString(headString));

// 指定合并区域
sheet.addMergedRegion(new Region(0, (short) 0, 0, (short) colSum));

HSSFCellStyle cellStyle = wb.createCellStyle();

cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐
//cellStyle.setWrapText(true);// 指定单元格自动换行

// 设置单元格字体
HSSFFont font = wb.createFont();
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
font.setFontName("宋体");
font.setFontHeight((short) 300);
cellStyle.setFont(font);

cell.setCellStyle(cellStyle);
}

/**
* 创建通用报表第二行的格式
*
*/
public HSSFCellStyle getCellStyle(HSSFWorkbook wb) {
// 创建单元格样式
HSSFCellStyle cellStyle = wb.createCellStyle();
// 指定单元格居中对齐
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 指定单元格垂直居中对齐
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
// 指定当单元格内容显示不下时自动换行
//cellStyle.setWrapText(true);
// 设置单元格字体
HSSFFont font = wb.createFont();
font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
font.setFontName("宋体");
font.setFontHeight((short) 200);
//font.setFontHeightInPoints((short) 22);
cellStyle.setFont(font);
return cellStyle;

}

}

第二种:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
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.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;

public class ExcelUtil<T> {
/**
* 从excel导入,返回一个list集合
*
* @author
* @param file
*            导入的excel文件
* @param pattern
* @return
* */
Class<T> clazz;

public ExcelUtil(Class<T> clazz) {
this.clazz = clazz;
}

@SuppressWarnings("unchecked")
public Collection<T> importExcel(File file, String... pattern)
throws Exception {
Collection<T> dist = new ArrayList<T>();
try {
/**
* 类反射得到调用方法
*/
// 得到目标目标类的所有的字段列表
Field filed[] = clazz.getDeclaredFields();
// 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中
Map fieldmap = new HashMap();
// 循环读取所有字段
for (int i = 0; i < filed.length; i++) {
Field f = filed[i];
// 得到单个字段上的Annotation
ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
// 如果标识了Annotationd的话
if (exa != null) {
// 构造设置了Annotation的字段的Setter方法
String fieldname = f.getName();
String setMethodName = "set"
+ fieldname.substring(0, 1).toUpperCase()
+ fieldname.substring(1);
// 构造调用的method,
Method setMethod = clazz.getMethod(setMethodName,
new Class[] { f.getType() });
// 将这个method以Annotaion的名字为key来存入。
fieldmap.put(exa.exportName(), setMethod);
}
}
/**
* excel的解析开始
*/
// 将传入的File构造为FileInputStream;
FileInputStream in = new FileInputStream(file);
// // 得到工作表
HSSFWorkbook book = new HSSFWorkbook(in);
// // 得到第一页
HSSFSheet sheet = book.getSheetAt(0);
// // 得到第一面的所有行
Iterator<Row> row = sheet.rowIterator();

/**
* 标题解析
*/
// 得到第一行,也就是标题行
Row title = row.next();
// 得到第一行的所有列
Iterator<Cell> cellTitle = title.cellIterator();
// 将标题的文字内容放入到一个map中。
Map titlemap = new HashMap();
// 从标题第一列开始
int i = 0;
// 循环标题所有的列
while (cellTitle.hasNext()) {
Cell cell = cellTitle.next();
String value = cell.getStringCellValue();
// 还是把表头trim一下
value = value.trim();
titlemap.put(i, value);
i = i + 1;
}
/**
* 解析内容行
*/
// 用来格式化日期的DateFormat
SimpleDateFormat sf;
if (pattern.length < 1) {
sf = new SimpleDateFormat("yyyy-MM-dd");
} else
sf = new SimpleDateFormat(pattern[0]);
while (row.hasNext()) {
// 标题下的第一行
Row rown = row.next();

// 行的所有列
Iterator<Cell> cellbody = rown.cellIterator();
// 得到传入类的实例
T tObject = clazz.newInstance();
int k = 0;
// 遍历一行的列
while (cellbody.hasNext()) {
Cell cell = cellbody.next();
// 这里得到此列的对应的标题
String titleString = (String) titlemap.get(k);
// 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值
if (fieldmap.containsKey(titleString)) {
Method setMethod = (Method) fieldmap.get(titleString);
// 得到setter方法的参数
Type[] ts = setMethod.getGenericParameterTypes();
// 只要一个参数
String xclass = ts[0].toString();
// 判断参数类型
try {
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_NUMERIC: // 数字
if (xclass.equals("class java.lang.String")) {
if ((cell.getNumericCellValue() + "")
.indexOf(".") > 0) {
setMethod
.invoke(tObject,
(cell.getNumericCellValue() + "")
.substring(
0,
(cell.getNumericCellValue() + "")
.lastIndexOf(".")));
}
} else if (xclass
.equals("class java.lang.Integer")) {
setMethod.invoke(tObject,
(int) cell.getNumericCellValue());
} else if (xclass.equals("int")) {
setMethod.invoke(tObject,
(int) cell.getNumericCellValue());
}
break;
case HSSFCell.CELL_TYPE_STRING: // 字符串
if (xclass.equals("class java.lang.Integer")) {
setMethod.invoke(tObject,
Integer.parseInt(cell
.getStringCellValue()));
} else if (xclass
.equals("class java.lang.String")) {
setMethod.invoke(tObject, cell
.getStringCellValue().trim());
} else if (xclass.equals("int")) {
int temp = Integer.parseInt(cell
.getStringCellValue());
setMethod.invoke(tObject, temp);
}
break;
case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
Boolean boolname = true;
if (cell.getStringCellValue().equals("否")) {
boolname = false;
}
setMethod.invoke(tObject, boolname);
break;
case HSSFCell.CELL_TYPE_FORMULA: // 公式
System.out.print(cell.getCellFormula() + "   ");
break;
case HSSFCell.CELL_TYPE_BLANK: // 空值
System.out.println(" ");
break;
case HSSFCell.CELL_TYPE_ERROR: // 故障
System.out.println(" ");
break;
default:
System.out.print("未知类型   ");
break;
}
} catch (Exception e) {// 转换出错
e.printStackTrace();

}
}
// 下一列
k = k + 1;
}
dist.add(tObject);
}
} catch (Exception e) {
e.printStackTrace();
// 将异常抛出去
throw e;
}
return dist;
}

// 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

/**
* 导出到excel中去,
*
* @author Administrator
* @param title
*            excel的工作表名
* @param fileName
*            excel 文件名
* @param dateset
*            导出的数据集合
* @param out
*            输出流
* @throws IOException
*/
@SuppressWarnings({ "static-access" })
public void exportExcel(String title, String fileName, List<T> dataset, String totalMoney,
HttpServletResponse response) throws IOException {
OutputStream out = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
response.setContentType("application/ms-excel;charset=GB2312");
response.setHeader("Content-disposition", "attachment; filename="
+ new String(fileName.getBytes("gb2312"), "iso8859-1") + ".xls");
// 声明一个工作薄
try {
HSSFWorkbook workbook = new HSSFWorkbook();
// 首先检查数据看是否是正确的
if (dataset == null || dataset.size() == 0 || title == null
|| out == null) {
throw new Exception("传入的数据不对!");
}
// 取得实际泛型类
T ts = (T) dataset.get(0);
Class<?> tCls = ts.getClass();
// 生成一个表格
HSSFSheet sheet = workbook.createSheet(title);
// 设置表格默认列宽度为15个字节
sheet.setDefaultColumnWidth(15);
// 生成一个样式
HSSFCellStyle style = workbook.createCellStyle();
// 设置标题样式
style = this.setHeadStyle(workbook, style);

// 得到所有字段

Field filed[] = ts.getClass().getDeclaredFields();
// 标题
List<String> exportfieldtile = new ArrayList<String>();
// 导出的字段的get方法
List<Method> methodObj = new ArrayList<Method>();
// 遍历整个filed
for (int i = 0; i < filed.length; i++) {
Field f = filed[i];
ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
// 如果设置了annottion
if (exa != null) {
String exprot = exa.exportName();
// 添加到标题
exportfieldtile.add(exprot);
// 添加到需要导出的字段的方法
String fieldname = f.getName();
String getMethodName = "get"
+ fieldname.substring(0, 1).toUpperCase()
+ fieldname.substring(1);

Method getMethod = tCls.getMethod(getMethodName,
new Class[] {});

methodObj.add(getMethod);
}
}
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, exportfieldtile
.size() - 1));
HSSFRow titleRow = sheet.createRow(0);
HSSFCell titleCell = titleRow.createCell(0);
titleCell.setCellValue(title);
titleCell.setCellStyle(this.setTitleStyle(workbook,
workbook.createCellStyle()));
// 产生表格标题行
HSSFRow row = sheet.createRow(1);
for (int i = 0; i < exportfieldtile.size(); i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(style);
HSSFRichTextString text = new HSSFRichTextString(
exportfieldtile.get(i));
cell.setCellValue(text);
}

int index = 1;

// 循环整个list
for (int j = 0; j < dataset.size(); j++) {
// 从第二行开始写,第一行是标题
T t = (T) dataset.get(j);
row = sheet.createRow(index + 1);
for (int k = 0; k < methodObj.size(); k++) {
HSSFCell cell = row.createCell(k);
Method getMethod = methodObj.get(k);
Object value = getMethod.invoke(t, new Object[] {});
String textValue = getValue(value);
cell.setCellValue(textValue);
}
index++;
}

//总的项目笔数
HSSFRow totalNumRow = sheet.createRow(index + 2);
HSSFCell totalNumCellTitle = totalNumRow.createCell(0);
totalNumCellTitle.setCellStyle(setStatStyle(workbook, workbook.createCellStyle()));
totalNumCellTitle.setCellValue("项目笔数");
HSSFCell totalNumCell = totalNumRow.createCell(1);
totalNumCell.setCellStyle(setStatStyle(workbook, workbook.createCellStyle()));
totalNumCell.setCellValue(dataset.size());

//总金额
HSSFRow totalMoneyRow = sheet.createRow(index + 3);
HSSFCell totalMoneyCellTitle = totalMoneyRow.createCell(0);
totalMoneyCellTitle.setCellStyle(setStatStyle(workbook, workbook.createCellStyle()));
totalMoneyCellTitle.setCellValue("总金额");
HSSFCell totalMoneyCell = totalMoneyRow.createCell(1);
totalMoneyCell.setCellStyle(setStatStyle(workbook, workbook.createCellStyle()));
totalMoneyCell.setCellValue(totalMoney + "万元");
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
}

}

public String getValue(Object value) {
String textValue = "";
if (value == null)
return textValue;

if (value instanceof Boolean) {
boolean bValue = (Boolean) value;
textValue = "是";
if (!bValue) {
textValue = "否";
}
} else if (value instanceof Date) {
Date date = (Date) value;

textValue = sdf.format(date);
} else
textValue = value.toString();

return textValue;
}

/**
* 初始化导出的excel标题的样式
* */
public static HSSFCellStyle setTitleStyle(HSSFWorkbook workbook,
HSSFCellStyle style) {

style.setFillForegroundColor(HSSFColor.WHITE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 生成字体
HSSFFont font = workbook.createFont();
font.setColor(HSSFColor.BLACK.index);
font.setFontHeightInPoints((short) 16);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样样式
style.setFont(font);
return style;

}

/**
* 统计部分的样式
* @param workbook
* @param style
* @return
*/
public static HSSFCellStyle setStatStyle(HSSFWorkbook workbook,
HSSFCellStyle style) {

style.setFillForegroundColor(HSSFColor.WHITE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
style.setBorderBottom(HSSFCellStyle.BORDER_NONE);
style.setBorderLeft(HSSFCellStyle.BORDER_NONE);
style.setBorderRight(HSSFCellStyle.BORDER_NONE);
style.setBorderTop(HSSFCellStyle.BORDER_NONE);
style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
// 生成字体
HSSFFont font = workbook.createFont();
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样样式
style.setFont(font);
return style;

}

/**
* 初始化导出的excel样式
* */
public static HSSFCellStyle setHeadStyle(HSSFWorkbook workbook,
HSSFCellStyle style) {

style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 生成字体
HSSFFont font = workbook.createFont();
font.setColor(HSSFColor.VIOLET.index);
font.setFontHeightInPoints((short) 12);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样样式
style.setFont(font);
return style;

}

public static HSSFCellStyle setbodyStyle(HSSFWorkbook workbook,
HSSFCellStyle style2) {
style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
// 生成字体
HSSFFont font2 = workbook.createFont();
font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
// 把字体应用到当前的样样式
style2.setFont(font2);
return style2;
}
}


 

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用于Excel导出时给每个pojo对象的字段添加字段名称,作为excel的表头
*
* */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAnnotation {
// excel导出时标题显示的名字,如果没有设置Annotation属性,将不会被导出和导入
public String exportName();
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JAVA POI