说明:的确是用JXL、HSSF、XSSF三种方式导入、导出Excel数据,但是跟所用项目的业务有所关联,摘出来比较麻烦,我就直接贴代码了。当给自己一个备份吧。
目前我知道的、会用的用来处理Excel的也就JXL和POI两种,JXL是用来处理Excel2003格式的,也只能处理这种格式。POI有HSSF和XSSF两种,前者用来且只处理Excel2003版本,后者用来处理2007版本且只处理2007版本的,要是用错了,系统会报错,譬如说:
1、org.apache.poi.openxml4j.exceptions.InvalidOperationException: Can't open the specified file:xxx
2、org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]。
这两种错基本上都是跟Excel版本有关系的。
好啦,言归正传,直接贴代码:
1、JXL读取Excel和将数据写入到Excel中:
/**
* 该方法用来读取指定的Excel文件,将其中的内容拼接成String返回到调用方法处
* @param filepath:需要读取的文件路径
* @param fieldList:参数列表
* @param viewID:指定的视图序号
* @param user:当前登录人
* */
public String readExcelInJXL(String filepath,String fieldList,String viewID,SUser user) throws Exception {
StringBuffer retuStr= new StringBuffer();
StringBuffer columnVal = new StringBuffer();
String fields = "";
String afterSql="";
String sql="";
//3、获取需要insert的表和字段数据
SView view = this.dataEngine.getView(Integer.parseInt(viewID));
Integer size = this.dataEngine.getViewDatabindView(view.getSViewId(), 2).size();//获取要求显示的字符串
//说明有添加条件(在导入数据模块,将该条件作为前执行sql)
if(view.getQuery()!=null && view.getQuery().trim().length()>0){
fields = replaceFieldList(fieldList,view.getQuery())+";";
}
//在导入数据模块,将该条件作为后执行sql
if(view.getOrdersql()!=null && view.getOrdersql().trim().length()>0){
afterSql = replaceFieldList(fieldList,view.getOrdersql())+";";
}
//拼接SQL
fields = fields+"insert into "+view.getSelectcondition()+"("+this.dataEngine.getViewColumn(view)+")";
String paramVal = getFieldList(fieldList);//获取参数键数据
paramVal +=this.dataEngine.getDefaultData(view,user);//获取默认值信息
//System.out.println(fields);
//4、读取上传的Excel文件
File excelFile = new File(filepath);
Workbook book = Workbook.getWorkbook(excelFile);//获取Excel文件对象,便于读取
//5、获取每个sheet并读取其中数据
String cellContent = "";//单元格内容
DateCell dc=null;//单元格日期类型
Sheet[] sheets = book.getSheets();//获取当前Excel下所有sheet集合
for(int j=0;j"+sheetName+"
")
.append("
2、HSSF读取Excel和将数据写入到Excel中:
/**
* 该方法用来读取指定的Excel文件,将其中的内容拼接成String返回到调用方法处
* @param filepath:需要读取的文件路径
* @param fieldList:参数列表
* @param viewID:指定的视图序号
* @param user:当前登录人
* */
public String readExcelInHSSF(String filepath,String fieldList,String viewID,SUser user) throws Exception {
StringBuffer retuStr= new StringBuffer();
StringBuffer columnVal = new StringBuffer();
String fields = "";
String afterSql="";
String sql="";
//3、获取需要insert的表和字段数据
SView view = this.dataEngine.getView(Integer.parseInt(viewID));
Integer size = this.dataEngine.getViewDatabindView(view.getSViewId(), 2).size();//获取要求显示的字符串
//说明有添加条件(在导入数据模块,将该条件作为前执行sql)
if(view.getQuery()!=null && view.getQuery().trim().length()>0){
fields = replaceFieldList(fieldList,view.getQuery())+";";
}
//在导入数据模块,将该条件作为后执行sql
if(view.getOrdersql()!=null && view.getOrdersql().trim().length()>0){
afterSql = replaceFieldList(fieldList,view.getOrdersql())+";";
}
//拼接SQL
fields = fields+"insert into "+view.getSelectcondition()+"("+this.dataEngine.getViewColumn(view)+")";
String paramVal = getFieldList(fieldList);//获取参数键数据
paramVal +=this.dataEngine.getDefaultData(view,user);//获取默认值信息
//System.out.println(fields);
//4、读取上传的Excel文件
File excelFile = new File(filepath);
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(excelFile));
HSSFWorkbook workBook = new HSSFWorkbook(fs);//获取Excel文件对象,便于读取
//5、获取每个sheet并读取其中数据
String cellContent = "";//单元格内容
HSSFSheet sheet = null;
for(int j=0;j"+sheetName+"
")
.append("
3、XSSF读取Excel和将数据写入到Excel中(与XSSF大同小异):
/**
* 该方法用来读取指定的Excel文件,将其中的内容拼接成String返回到调用方法处
* @param filepath:需要读取的文件路径
* @param fieldList:参数列表
* @param viewID:指定的视图序号
* @param user:当前登录人
* */
public String readExcelInXSSF(String filepath,String fieldList,String viewID,SUser user) throws Exception {
StringBuffer retuStr= new StringBuffer();
StringBuffer columnVal = new StringBuffer();
String fields = "";
String afterSql="";
String sql="";
//3、获取需要insert的表和字段数据
SView view = this.dataEngine.getView(Integer.parseInt(viewID));
Integer size = this.dataEngine.getViewDatabindView(view.getSViewId(), 2).size();//获取要求显示的字符串
//说明有添加条件(在导入数据模块,将该条件作为前执行sql)
if(view.getQuery()!=null && view.getQuery().trim().length()>0){
fields = replaceFieldList(fieldList,view.getQuery())+";";
}
//在导入数据模块,将该条件作为后执行sql
if(view.getOrdersql()!=null && view.getOrdersql().trim().length()>0){
afterSql = replaceFieldList(fieldList,view.getOrdersql())+";";
}
//拼接SQL
fields = fields+"insert into "+view.getSelectcondition()+"("+this.dataEngine.getViewColumn(view)+")";
String paramVal = getFieldList(fieldList);//获取参数键数据
paramVal +=this.dataEngine.getDefaultData(view,user);//获取默认值信息
//System.out.println(fields);
//4、读取上传的Excel文件
File excelFile = new File(filepath);
XSSFWorkbook workBook = new XSSFWorkbook(new FileInputStream(excelFile));//获取Excel文件对象,便于读取
//5、获取每个sheet并读取其中数据
String cellContent = "";//单元格内容
XSSFSheet sheet = null;
for(int j=0;j"+sheetName+"
")
.append("
4、用到的一些公用方法:
/**
* 该方法用来替换参数值
* @param fieldList:参数集合,格式:参数键1:参数值1;参数键2:参数值2;以此类推
* @param reg:需要进行替换的字符串
* */
private String replaceFieldList(String fieldList,String reg){
//只要双方有一个为null或者为空字符串,都返回原来的值reg
if(fieldList==null || fieldList.trim().equals("") ||
reg==null || reg.trim().equals("")){
return reg;
}
fieldList = fieldList.trim();//去除空格
reg = reg.trim();
String[] fields = fieldList.split(";");//
String[] val = null;
if(fields.length>0){//说明至少有一组
for(String f:fields){
val = f.split(":");
reg = reg.replaceAll("<"+val[0]+">", val[1]);
}
}
return reg;
}
private Parameters getParameters(String parametersStr) {
return ParametersUitls.getParametersByStrForXML(parametersStr);
}
/**
* 该方法用来获取参数键的参数值
* @param fieldList:参数集合,格式:参数键1:参数值1;参数键2:参数值2;以此类推
* */
private String getFieldList(String fieldList){
//只要双方有一个为null或者为空字符串,都返回原来的值reg
if(fieldList==null || fieldList.trim().equals("")){
return "";
}
fieldList = fieldList.trim();//去除空格
String[] fields = fieldList.split(";");//
StringBuffer result= new StringBuffer();
if(fields.length>0){//说明至少有一组
for(String f:fields){
result.append("'"+f.split(":")[1]+"'").append(",");
}
}
return result.toString();
}
/**
* 导出数据时,先判断指定目录是否存在,若不存在则新建
* 若存在,则删除指定目录下的文件,避免每次下载都生成文件导致硬盘容量不够
*/
private File initFileDir() {
String savePath = WebAppConfig.app("excelDir");//从配置文件中获取保存Excel的目录
savePath=savePath.trim();
if(savePath==null || savePath.equals("null") || savePath.length()<=0 ){
savePath = "D:"+java.io.File.separator+"bfp"+java.io.File.separator+"ed";
}
File saveDir = new File(savePath);
if(!saveDir.isDirectory()){//指定目录不存在则新建
saveDir.mkdir();
}else{//若是已经存在,那么删除里面的内容,避免每次下载都生成文件导致硬盘容量不够
deleteFiles(saveDir);
//saveDir.mkdir();
}
return saveDir;
}
/**
* 删除文件
* @param file:File类型,指定要删除的文件
* */
private void deleteFiles(File file){
Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal2.setTime(new Date());//设置当前时间
int day1=0,day2=0;
if(file.isDirectory()){
File[] files = file.listFiles();//获取指定目录下的所有文件
for(int i=0;i0){//說明是以前的文件,那麼直接刪除
deleteFiles(files[i]);
}else{//說明是今年或以後的文件
day1= cal.get(Calendar.DAY_OF_YEAR);
day2 = cal2.get(Calendar.DAY_OF_YEAR);
if((day2-day1)>0){//說明是今天之前的文件
deleteFiles(files[i]);
}
}
}
}
file.delete();//删除文件
}
/**
* 该方法用来处理单元格中的数据
* */
private String parseExcel(Cell cell) {
String result = new String();
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_NUMERIC:// 数字类型
short format = cell.getCellStyle().getDataFormat();
SimpleDateFormat sdf = null;
if(format == 14 || format == 31 || format == 57 || format == 58){ //日期
sdf = new SimpleDateFormat("yyyy-MM-dd");
}else if (format == 20 || format == 32) { //时间
sdf = new SimpleDateFormat("HH:mm");
}
//若为数字,获取到的Value会自动添加一个0,变成xxx.0,这种格式的数据不能保存到数据类型为int的字段中
Double value = cell.getNumericCellValue();
if(sdf!=null){//需要进行格式化
Date date = HSSFDateUtil.getJavaDate(value);
result = sdf.format(date);
}else{//可能是数字
Long longVal = Math.round(value);//转换成long类型,此时没有小数点
// System.out.println(longVal+"\t"+Double.parseDouble(longVal + ".0"));
if(Double.parseDouble(longVal + ".0") == value)
result = longVal.toString();
else
result = value.toString();
}
break;
case HSSFCell.CELL_TYPE_STRING:// String类型
result = cell.getRichStringCellValue().toString();
break;
case HSSFCell.CELL_TYPE_BLANK:
result = "";
default:
result = "";
break;
}
return result;
}
POI的两种方式弄了很久,也碰到了很多问题。这篇粘代码粘太多了,问题就不写在这篇了,呵呵呵!