1、HelloPOI
在我们实际的开发中,常常有需要导入导出excel和word的要求,POI便是一个很好的解决方案。
Apache的Jakata项目的POI子项目,目前比较成熟的是HSSF接口,处理MSExcel对象。它不象我们仅仅是用csv生成的没有格式的可以由Excel转换的东西,而是真正的Excel对象,你可以控制一些属性如sheet,cell等等。
首先,理解一下一个Excel的文件的组织形式,一个Excel文件对应于一个workbook(HSSFWorkbook),一个workbook可以有多个sheet(HSSFSheet)组成,一个sheet是由多个row(HSSFRow)组成,一个row是由多个cell(HSSFCell)组成。
HSSF是指Excel2007年以前的版本,XSSF是指Excel2007年版本以后的版本。
2、例子
POIExcelUtil.java
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.io.OutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
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.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class POIExcelUtil {
private int totalRows = 0; // 总行数
private int totalCells = 0; // 总列数
private OutputStream out = null;
private HSSFWorkbook workbook = null;
private HSSFSheet sheet = null;
private HSSFRow row = null; // 定制浮点数格式
private static String NUMBER_FORMAT = "#,##0.00";// 定制日期格式
private static String DATE_FORMAT = "m/d/yy"; // "m/d/yy h:mm"
public POIExcelUtil() {
}
// 根据文件名读取excel文件
public List<ArrayList<String>> read(String fileName, int sheetNo,
int beginRowNo, int endRowNo) {
List<ArrayList<String>> dataLst = new ArrayList<ArrayList<String>>();
// 检查文件名是否为空或者是否是Excel格式的文件
if (fileName == null || !fileName.matches("^.+\\.(?i)((xls)|(xlsx))$")) {
return dataLst;
}
boolean isExcel2003 = true; // 对文件的合法性进行验
if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
isExcel2003 = false;
} // 检查文件是否存在
File file = new File(fileName);
if (file == null || !file.exists()) {
return dataLst;
}
try { // 读取excel
dataLst = read(new FileInputStream(file), isExcel2003, sheetNo,
beginRowNo, endRowNo);
} catch (Exception ex) {
ex.printStackTrace();
}
return dataLst;
}
// 根据流读取Excel文件
public List<ArrayList<String>> read(InputStream inputStream,
boolean isExcel2003, int sheetNo, int beginRowNo, int endRowNo) {
List<ArrayList<String>> dataLst = null;
try {
// 根据版本选择创建Workbook的方式
Workbook wb = isExcel2003 ? new HSSFWorkbook(inputStream)
: new HSSFWorkbook(inputStream);
dataLst = read(wb, sheetNo, beginRowNo, endRowNo);
} catch (IOException e) {
e.printStackTrace();
}
return dataLst;
}
// 得到总行数
public int getTotalRows() {
return totalRows;
}
// 得到总列数
public int getTotalCells() {
return totalCells;
}
// 读取数据
private List<ArrayList<String>> read(Workbook wb, int sheetNo,
int beginRowNo, int endRowNo) {
List<ArrayList<String>> dataLst = new ArrayList<ArrayList<String>>();
Sheet sheet = wb.getSheetAt(sheetNo - 1);// 得到第一个shell
this.totalRows = sheet.getPhysicalNumberOfRows();
if (this.totalRows >= 1 && sheet.getRow(0) != null) {
this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
}
// 循环Excel的行
// for (int r = 0; r < this.totalRows; r++) {
for (int r = beginRowNo - 1; r < endRowNo; r++) {
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
ArrayList<String> rowLst = new ArrayList<String>();
// 循环Excel的列
for (short c = 0; c < this.getTotalCells(); c++) {
Cell cell = row.getCell(c);
String cellValue = "";
if (cell == null) {
rowLst.add(cellValue);
continue;
}
// 处理数字型的,自动去零
if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
// 在excel里,日期也是数字,在此要进行判断
if (HSSFDateUtil.isCellDateFormatted(cell)) {
cellValue = DateUtil
.get4yMdHms(cell.getDateCellValue());
} else {
cellValue = getRightStr(cell.getNumericCellValue() + "");
}
} else if (Cell.CELL_TYPE_STRING == cell.getCellType()) { // 处理字符串型
cellValue = cell.getStringCellValue();
} else if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) { // 处理布尔型
cellValue = cell.getBooleanCellValue() + "";
} else { // 其它数据类型
cellValue = cell.toString() + "";
}
rowLst.add(cellValue);
}
dataLst.add(rowLst);
}
return dataLst;
}
// 正确地处理整数后自动加零的情况
private String getRightStr(String sNum) {
DecimalFormat decimalFormat = new DecimalFormat("#.000000");
String resultStr = decimalFormat.format(new Double(sNum));
if (resultStr.matches("^[-+]?\\d+\\.[0]+$")) {
resultStr = resultStr.substring(0, resultStr.indexOf("."));
}
return resultStr;
}
/**
* 初始化write
*/
public void initWrite(OutputStream out) {
this.out = out;
this.workbook = new HSSFWorkbook();
this.sheet = workbook.createSheet();
}
/**
* 导出Excel文件
* @throws Exception
*/
public void export() throws Exception {
try {
workbook.write(out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
throw new Exception("生成导出Excel文件出错! ", e);
} catch (IOException e) {
throw new Exception("写入Excel文件出错! ", e);
}
}
/**
* 增加一行
* @param index 行号
*/
public void createRow(int index) {
this.row = this.sheet.createRow(index);
}
/**
* 设置单元格
* @param index 列号
* @param value 单元格填充值
*/
public void setCell(int index, int value) {
HSSFCell cell = this.row.createCell(index);
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
cell.setCellValue(value);
}
/**
* 设置单元格
* @param index 列号
* @param value 单元格填充值
*/
public void setCell(int index, double value) {
HSSFCell cell = this.row.createCell(index);
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
cell.setCellValue(value);
HSSFCellStyle cellStyle = workbook.createCellStyle(); // 建立新的cell样式
HSSFDataFormat format = workbook.createDataFormat();
cellStyle.setDataFormat(format.getFormat(NUMBER_FORMAT)); // 设置cell样式为定制的浮点数格式
cell.setCellStyle(cellStyle); // 设置该cell浮点数的显示格式
}
/**
* 设置单元格
* @param index 列号
* @param value 单元格填充值
*/
public void setCell(int index, String value) {
HSSFCell cell = this.row.createCell(index);
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue(value);
}
/**
* 设置单元格
* @param index 列号
* @param value 单元格填充值
*/
public void setCell(int index, Calendar value) {
HSSFCell cell = this.row.createCell(index);
cell.setCellValue(value.getTime());
HSSFCellStyle cellStyle = workbook.createCellStyle(); // 建立新的cell样式
cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat(DATE_FORMAT)); // 设置cell样式为定制的日期格式
cell.setCellStyle(cellStyle); // 设置该cell日期的显示格式
}
public static void main(String[] args) throws Exception {
POIExcelUtil e = new POIExcelUtil();
System.out.println(" 开始导出Excel文件 ");
File f = new File("d://哈喽.xlsx");
try {
e.initWrite(new FileOutputStream(f));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
e.createRow(0);
e.setCell(0, "试题编码 ");
e.setCell(1, "题型");
e.setCell(2, "分值");
e.setCell(3, "难度");
e.setCell(4, "级别");
e.setCell(5, "知识点");
for(int i=1;i<10;i++)
{
e.createRow(i);
e.setCell(0, "t"+i);
e.setCell(1, 1+i);
e.setCell(2, 3.0+i);
e.setCell(3, 1+i);
e.setCell(4, "重要"+i);
e.setCell(5, "专业"+i);
}
try {
e.export();
System.out.println(" 导出Excel文件[成功] ");
} catch (Exception ex) {
System.out.println(" 导出Excel文件[失败] ");
ex.printStackTrace();
}
}
}
DateUtil.java
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
// 得到当前的时间
public static Date getDate() {
Calendar canlendar = Calendar.getInstance();
return canlendar.getTime();
}
// 提到指定的millis得到时间
public static Date getDate(long millis) {
Calendar canlendar = Calendar.getInstance();
canlendar.clear();
canlendar.setTimeInMillis(millis);
return canlendar.getTime();
}
public static long getMillis() {
return Calendar.getInstance().getTimeInMillis();
}
// 得到指定日期的字符串(yyyy-MM-dd HH:mm:ss.SSS)
public static String getDateFormate(Date date, String formate) {
try {
SimpleDateFormat simpleDateFormate = new SimpleDateFormat(formate);
return simpleDateFormate.format(date);
} catch (Exception e) {
}
return "";
}
// 根据日期得到YYYY-MM-DD HH:MM:SS.SSS格式字符串
public static String get4yMdHmsS(Date date) {
return DateUtil.getDateFormate(date, "yyyy-MM-dd HH:mm:ss.SSS");
}
// 根据日期得到YYYY-MM-DD HH:MM:SS格式字符串
public static String get4yMdHms(Date date) {
return DateUtil.getDateFormate(date, "yyyy-MM-dd HH:mm:ss");
}
// 根据日期得到YYYY-MM-DD HH:MM格式字符串
public static String get4yMdHm(Date date) {
return DateUtil.getDateFormate(date, "yyyy-MM-dd HH:mm");
}
// 根据日期得到YYYY-MM-DD格式字符串
public static String get4yMd(Date date) {
return DateUtil.getDateFormate(date, "yyyy-MM-dd");
}
// 把指定字符(yyyy-MM-dd HH:mm:ss.SSS)串转成Date
public static Date parse4yMdHmsS(String sDate) {
return DateUtil.parseDate(sDate, "yyyy-MM-dd HH:mm:ss.SSS");
}
// 把指定字符(yyyy-MM-dd HH:mm:ss)串转成Date
public static Date parse4yMdHms(String sDate) {
return DateUtil.parseDate(sDate, "yyyy-MM-dd HH:mm:ss");
}
// 把指定字符(yyyy-MM-dd HH:mm)串转成Date
public static Date parse4yMdHm(String sDate) {
return DateUtil.parseDate(sDate, "yyyy-MM-dd HH:mm");
}
// 把指定字符(yyyy-MM-dd)串转成Date
public static Date parse4yMd(String sDate) {
return DateUtil.parseDate(sDate, "yyyy-MM-dd");
}
// 根据指定格式,把字符串转成日期
public static Date parseDate(String sDate, String formate) {
SimpleDateFormat simpleDateFormate = new SimpleDateFormat(formate);
try {
return simpleDateFormate.parse(sDate);
} catch (ParseException e) {
return null;
}
}
// 两个长整型的时间相差(时间的毫秒数),可以得到指定的毫秒数,秒数,分钟数,天数
public static double getDifTwoTime(Date minuendTime, Date subtrahendTime,
String tdatestr) {
if (minuendTime == null || subtrahendTime != null) {
return DateUtil.getDifTwoTime(minuendTime.getTime(),
subtrahendTime.getTime(), tdatestr);
}
return 0;
}
// 两个长整型的时间相差(时间的毫秒数),可以得到指定的毫秒数,秒数,分钟数,天数
public static double getDifTwoTime(long minuendTime, long subtrahendTime,
String tdatestr) {
if (tdatestr == null || tdatestr.equals("")) {
tdatestr = "MS";
}
double temp = 1;
/** 毫秒数 */
if ("MS".equalsIgnoreCase(tdatestr)) {
temp = 1;
}
/** 得到秒 */
if ("S".equalsIgnoreCase(tdatestr)) {
temp = 1000;
}
/** 得到分 */
if ("M".equalsIgnoreCase(tdatestr)) {
temp = 1000 * 60;
}
/** 得到小时 */
if ("H".equalsIgnoreCase(tdatestr)) {
temp = 1000 * 60 * 60;
}
/** 得到天 */
if ("D".equalsIgnoreCase(tdatestr)) {
temp = 1000 * 60 * 60 * 24;
}
return (minuendTime - subtrahendTime) / temp;
}
// 从日期中得到指定部分(YYYY/MM/DD/HH/SS/SSS)数字
public static int getPartOfTime(Date date, String part) {
Calendar canlendar = Calendar.getInstance();
canlendar.clear();
canlendar.setTime(date);
if (part.equalsIgnoreCase("Y")) {// 得到年
return canlendar.get(Calendar.YEAR);
}
if (part.equalsIgnoreCase("M")) {// 得到月
return canlendar.get(Calendar.MONTH) + 1;
}
if (part.equalsIgnoreCase("D")) {// 得到日
return canlendar.get(Calendar.DAY_OF_MONTH);
}
if (part.equalsIgnoreCase("H")) {// 得到时
return canlendar.get(Calendar.HOUR_OF_DAY);
}
if (part.equalsIgnoreCase("M")) {// 得到分
return canlendar.get(Calendar.MINUTE);
}
if (part.equalsIgnoreCase("S")) {// 得到秒
return canlendar.get(Calendar.SECOND);
}
if (part.equalsIgnoreCase("MS")) {// 得到毫秒
return canlendar.get(Calendar.MILLISECOND);
}
return -1;
}
}