Java生成操作excel(超详细,例如xml文件生成excel)
import java.io.BufferedInputStream;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.lang.reflect.Field;
import java.util.HashMap;
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.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableImage;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
public class ExcelUtil {
private static WritableSheet sheet = null;
private static WritableSheet sheetToMap = null;
private static WritableSheet sheetToMerge = null;
private static Workbook rwork = null ;
private static WritableWorkbook wwb = null ;
private static Map<String,String> indexMap = null ;
/**
* @param 用来代替传统的使用IReport生成Excel
* @param jxl操作excel1
* @param 只替换Paremeter的值
* @param 2012-03-23
* @param List的值和顺序完全按照Bean的属性和值来排列的,如果需要修改排列顺序,那么请修改Bean属性的排列顺序
* @param String realPath :读取模版路径
* @param String outPath :输出模版路径
* @param Map<String,String> map :需要替换的Parameter
* @return
* */
public static void jExcelTemplate(String realPath,Map<String,String> map,HttpServletResponse response) {
try {
jxlDocTemplateAll(realPath,map,null,0,0,null,null,response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
/**
* @param 用来代替传统的使用IReport生成Excel
* @param jxl操作excel1
* @param 只替换List的值
* @param List的值和顺序完全按照Bean的属性和值来排列的,如果需要修改排列顺序,那么请修改Bean属性的排列顺序
* @param 需要设置坐标,即List循环的起始坐标
* @param 2012-03-23
* @param String realPath :读取模版路径
* @param String outPath :输出模版路径
* @param List<?> list :循环任意类型的List
* @param list可以没有指定的泛型,但必须是指定的Model
* @param list必须要指定初始化的坐标
* @return
* */
public static void jExcelTemplate(String realPath,List<?> list,int x,int y,HttpServletResponse response) {
try {
jxlDocTemplateAll(realPath,null,list,x,y,null,null,response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
/**
* @param 用来代替传统的使用IReport生成Excel
* @param jxl操作excel1
* @param 2012-03-23
* @param 替换Paremeter和List的值
* @param Paremeter即传如的Map<String,String>,且必须的String类型的
* @param Paremeter必须且最少有一个和模版上的值对应上,否则会报错
* @param List的值和顺序完全按照Bean的属性和值来排列的,如果需要修改排列顺序,那么请修改Bean属性的排列顺序
* @param 需要设置坐标,即List循环的起始坐标
* @param String realPath :读取模版路径
* @param String outPath :输出模版路径
* @param Map<String,String> map :需要替换的Parameter
* @param List<?> list :循环任意类型的List
* @param list可以没有指定的泛型,但必须是指定的Model
* @param list必须要指定初始化的坐标
* @return
* */
public static void jExcelTemplate(String realPath,Map<String,String> map,List<?> list,int x,int y,HttpServletResponse response) {
try {
jxlDocTemplateAll(realPath,map,list,x,y,null,null,response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
/**
* @param 用来代替传统的使用IReport生成Excel
* @param jxl操作excel1
* @param 2012-03-23
* @param 替换Paremeter和List的值,指定合并的单元格
* @param Paremeter即传如的Map<String,String>,且必须的String类型的
* @param Paremeter必须且最少有一个和模版上的值对应上,否则会报错
* @param List的值和顺序完全按照Bean的属性和值来排列的,如果需要修改排列顺序,那么请修改Bean属性的排列顺序
* @param 需要设置坐标,即List循环的起始坐标
* @param String realPath :读取模版路径
* @param String outPath :输出模版路径
* @param Map<String,String> map :需要替换的Parameter
* @param List<?> list :循环任意类型的List
* @param list可以没有指定的泛型,但必须是指定的Model
* @param list必须要指定初始化的坐标
* @param 允许合并多个单元格,并且属性是居中,自动换行的
* @param 合并的单元格如果想替换成指定内容,需要对传入的List<JXLExcelModel> 中 JXLExcelModel.mergeText赋值
* @return
* */
public static void jExcelTemplate(String realPath,Map<String,String> map,List<?> list,int x,int y,List<JXLExcelModel> jxlList,HttpServletResponse response) {
try {
jxlDocTemplateAll(realPath,map,list,x,y,jxlList,null,response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
/**
* @param 用来代替传统的使用IReport生成Excel
* @param jxl操作excel1
* @param 2012-03-23
* @param 替换Paremeter和List的值,指定合并的单元格
* @param Paremeter即传如的Map<String,String>,且必须的String类型的
* @param Paremeter必须且最少有一个和模版上的值对应上,否则会报错
* @param List的值和顺序完全按照Bean的属性和值来排列的,如果需要修改排列顺序,那么请修改Bean属性的排列顺序
* @param 需要设置坐标,即List循环的起始坐标
* @param String realPath :读取模版路径
* @param String outPath :输出模版路径
* @param Map<String,String> map :需要替换的Parameter
* @param List<?> list :循环任意类型的List
* @param list可以没有指定的泛型,但必须是指定的Model
* @param list必须要指定初始化的坐标
* @param 允许合并多个单元格,并且属性是居中,自动换行的
* @param 合并的单元格如果想替换成指定内容,需要对传入的List<JXLExcelModel> 中 JXLExcelModel.mergeText赋值
* @return
* */
public static void jExcelTemplate(String realPath,Map<String,String> map,List<?> list,int x,int y,List<JXLExcelModel> jxlList,int[][] mergeInt,HttpServletResponse response) {
try {
jxlDocTemplateAll(realPath,map,list,x,y,jxlList,mergeInt,response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
/**
* @param 用来代替传统的使用IReport生成Excel
* @param jxl操作excel1
* @param 操作List,Map,合并单元格,合并单元格填充的值
* @param List的值和顺序完全按照Bean的属性和值来排列的,如果需要修改排列顺序,那么请修改Bean属性的排列顺序
* @param String realPath :读取模版路径
* @param String outPath :输出模版路径
* @param Map<String,String> map :需要替换的Parameter
* @param List<?> list :循环任意类型的List
* @param list可以没有指定的泛型,但必须是指定的Model
* @param list必须要指定初始化的坐标
* @param 允许合并多个单元格,并且属性是居中,自动换行的
* @param 合并的单元格如果想替换成指定内容,需要对传入的List<JXLExcelModel> 中 JXLExcelModel.mergeText赋值
* @return
* */
public static void jExcelTemplate(String realPath,Map<String,String> map,List<?> list,List<JXLExcelModel> jxlList,HttpServletResponse response) {
try {
jxlDocTemplateAllMoreList(realPath,map,list,jxlList,null,response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
/**
* @param 用来代替传统的使用IReport生成Excel
* @param jxl操作excel1
* @param 操作List,Map,合并单元格,合并单元格填充的值
* @param List的值和顺序完全按照Bean的属性和值来排列的,如果需要修改排列顺序,那么请修改Bean属性的排列顺序
* @param String realPath :读取模版路径
* @param String outPath :输出模版路径
* @param Map<String,String> map :需要替换的Parameter
* @param List<?> list :循环任意类型的List
* @param list可以没有指定的泛型,但必须是指定的Model
* @param list必须要指定初始化的坐标
* @param 允许合并多个单元格,并且属性是居中,自动换行的
* @param 合并的单元格如果想替换成指定内容,需要对传入的List<JXLExcelModel> 中 JXLExcelModel.mergeText赋值
* @param int[][] mergeInt :对指定列的上下行进行合并
* @return
* */
public static void jExcelTemplate(String realPath,Map<String,String> map,List<?> list,List<JXLExcelModel> jxlList,int[] [] mergeInt,HttpServletResponse response) {
try {
jxlDocTemplateAllMoreList(realPath,map,list,jxlList,mergeInt,response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
/*
* 2012-03-23
* 这个方法能遍历多个List表格
* */
@SuppressWarnings("unchecked")
public static void jxlDocTemplateAllMoreList(String realPath,Map<String,String> map,List<?> list,List<JXLExcelModel> jxlList,int[][] mergeInt,HttpServletResponse response) throws WriteException {
try {
String outPath = realPath.substring(0, realPath.length() - 4) + "_bak.xls" ;
boolean merge = false ; //判断是否有单元格要进行合并
if(jxlList != null) {
merge = true ;
}
if(fileExist(realPath)) {
//1.找到模版文件并加载
HSSFWorkbook rwb = new HSSFWorkbook(new FileInputStream(realPath)) ;
//2.得到要修改的Parameter,并记录坐标 开始-------------------------
HSSFSheet sht = rwb.getSheetAt(0) ;
Map<String,String> indexMap = new HashMap<String,String>() ;
/*
* 判断是否有需要替换的Paremeter
* 通过map来遍历得到要替换对象在excel中的坐标并保存在(indexMap)坐标map中
* 格式 x|y
* */
if(map != null) {
String indexList = "" ;
for(String value:map.keySet()) {//遍历是否存在要替换的Parameter坐标,并记录在Map中 格式: x|y
try {
indexList = getCellindex(sht, value) ;
//cell = getCellindex(sht, value);
} catch(java.lang.RuntimeException e) {
continue ;
}
indexMap.put(value, indexList) ;
}
}
//2.得到要修改的Parameter,并记录坐标 结束-------------------------
//3.读取Excel模版文件,加载到WritableWorkbook中,使其允许修改操作
rwork = Workbook.getWorkbook(new File(realPath)) ; //读取模版文件
wwb = Workbook.createWorkbook(new FileOutputStream(outPath),rwork) ; //修改模版
//4.读取工作表
WritableSheet sheet = wwb.getSheet(0) ;
//查找工作表,如果没有获得相应工作表,先创建一个名为test的工作表
if(sheet == null) {
sheet = wwb.createSheet("test", 0) ;
}
if(map != null) {
//5.先替换模版中的Parameter值 开始 ---------------------------------------------
for(String value:indexMap.keySet()) {
int x = Integer.parseInt(indexMap.get(value).split("#")[0]) ;
int y = Integer.parseInt(indexMap.get(value).split("#")[1]) ;
WritableCellFormat wc1 = new WritableCellFormat();
wc1.setAlignment(Alignment.CENTRE); // 设置居中
wc1.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
Label label01 = null ;
label01 = new Label(y,x,map.get(value),wc1) ;
sheet.addCell(label01) ;
}
//5.先替换模版中的Parameter值 结束 ---------------------------------------------
}
/*
* 6.通过list循环插入列值 开始---------------------------------------------
* 通过反射来得到List对象的属性和值
* */
if(list != null) {
for(int listSi = 0 ; listSi < list.size() - 2 ; listSi += 3 ) {
List<Object> listValue = ReflectUtil.getAllFieldAndValue((List<Object>)list.get(listSi)) ;
List<Object[]> dataValueList = (List<Object[]>) listValue.get(2) ;
for(int i = 0 ; i < dataValueList.size() ; i ++ ) {
WritableCellFormat wc2 = new WritableCellFormat();
wc2.setAlignment(Alignment.CENTRE); // 设置居中
wc2.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc2.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
int iii = Integer.parseInt(list.get(listSi + 2 ).toString()) ;
int www = Integer.parseInt(list.get(listSi + 1 ).toString()) ;
sheet.insertRow(iii) ; //在指定位置插入一新行,用以插入数据
Label label02 = null ;
Object[] object = dataValueList.get(i) ;
for(int num = 0 ; num < object.length ; num ++ ) {
String value = "" ;
if(object[num] != null ) {
value = object[num].toString() ;
}
label02 = new Label(www + num , iii, value ,wc2) ;
sheet.addCell(label02) ;
}
www += 1 ;
}
}
}
//6.通过list循环插入列值 结束---------------------------------------------
//7.对指定单元格进行合并 开始-----------------------------------------
if(merge) {
JXLExcelModel jxlModel = null ;
for(int jj = 0 ; jj < jxlList.size() ; jj ++ ) {
WritableCellFormat wc3 = new WritableCellFormat();
wc3.setAlignment(Alignment.CENTRE); // 设置居中
wc3.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc3.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc3.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc3.setWrap(true) ; //设置单元格属性为自动换行
jxlModel = jxlList.get(jj) ;
sheet.mergeCells(jxlModel.getStartX(), jxlModel.getStartY(), jxlModel.getEndX(), jxlModel.getEndY());
/*
* 如果有单元格进行合并,判断是否有需要填充的值
* */
if(jxlModel.getMergeText() != null) {
sheet.addCell(new Label(jxlModel.getStartX(),jxlModel.getStartY(),jxlModel.getMergeText(),wc3)) ;
}
}
}
//7.对指定样式进行合并 结束-----------------------------------------
//response.wait(wwb) ;
try {
//8.将编辑好的Excel存放到输出到指定的目录下
wwb.write() ;
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
System.out.println("线程异常") ;
}
} else {
System.out.println("模版文件不存在 !!!") ;
}
} catch(Exception e) {
System.out.println(e) ;
} finally {
//9.关闭wwb,以释放内存
if(rwork != null) {
rwork.close() ;
}
if(wwb != null) {
try {
wwb.close() ;
} catch (WriteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
String outPath = realPath.substring(0, realPath.length() - 4) + "_bak.xls" ;
HSSFWorkbook rwb2 = null ;
//8.对指定列进行上下行合并 开始----------------------------------------------------------
if(mergeInt != null && list.size() > 0) {
try {
rwb2 = new HSSFWorkbook(new FileInputStream(outPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
HSSFSheet sht2 = rwb2.getSheetAt(0) ;
HSSFRow rows = null ;
HSSFCell cl = null ;
HSSFRow rows2 = null ;
HSSFCell cl2 = null ;
Workbook rwork2 = null ;
WritableWorkbook wwb2 = null ;
try {
rwork2 = Workbook.getWorkbook(new File(outPath)) ;
} catch (BiffException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //读取模版文件
try {
wwb2 = Workbook.createWorkbook(new FileOutputStream(outPath),rwork2) ;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //修改模版
WritableSheet sheet2 = wwb2.getSheet(0) ;
WritableCellFormat wc4 = new WritableCellFormat();
wc4.setAlignment(Alignment.CENTRE);
wc4.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc4.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc4.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc4.setWrap(true) ; //设置单元格属性为自动换行
for(int mergeM = 0 ; mergeM < mergeInt.length ; mergeM ++ ) {
int maxMergeInt = 0 ;
for(int mergeMin = mergeInt[mergeM][1] ; mergeMin < (mergeInt[mergeM][1] + mergeInt[mergeM][2]) - 1 ;) {
//这里是指定行
rows = sht2.getRow(mergeMin) ; //rows得到当前行的数据
if(rows == null) {
continue ;
} else {
cl = rows.getCell(mergeInt[mergeM][0]) ;
maxMergeInt = 1 ;
//从本行起开始遍历行,一直到和本行值不一样为止
for(int maxMergeIntSize = mergeMin ; maxMergeIntSize < (mergeInt[mergeM][1] + mergeInt[mergeM][2]) - 1 ; maxMergeIntSize ++ ) {
//循环到下N行,如果本行的值是相同的;
rows2 = sht2.getRow(mergeMin + maxMergeInt) ;
cl2 = rows2.getCell(mergeInt[mergeM][0]) ;
if(cl != null && cl2 != null) {
if(!cl.getRichStringCellValue().toString().equals("") && cl.getRichStringCellValue().toString().trim().equals(cl2.getRichStringCellValue().toString().trim())) {
maxMergeInt ++ ;
} else {
break ;
}
}
}
rows2 = sht2.getRow(mergeMin + maxMergeInt - 1) ;
cl2 = rows2.getCell(mergeInt[mergeM][0]) ;
if(cl != null && cl2 != null) {
if(!cl.getRichStringCellValue().toString().equals("") && cl.getRichStringCellValue().toString().trim().equals(cl2.getRichStringCellValue().toString().trim())) {
//如果列的上下行相等,得到X,Y坐标,并进行合并
try {
sheet2.mergeCells(mergeInt[mergeM][0], mergeMin, mergeInt[mergeM][0], mergeMin + maxMergeInt - 1) ;
sheet2.addCell(new Label(mergeInt[mergeM][0], mergeMin - 1 ,cl2.getRichStringCellValue().toString(),wc4)) ;
} catch (WriteException e) {
e.printStackTrace();
} // 设置居中
} else {
}
}
}
mergeMin += maxMergeInt ;
}
}
try {
wwb2.write() ;
rwork2.close() ;
try {
wwb2.close() ;
} catch (WriteException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//8.通过流实现文件下载
try {
//response = ServletActionContext.getResponse();
//String path = getRequest().getParameter("fileName");
// path是指欲下载的文件的路径。
File file = new File(outPath);
// 取得文件名。
String filename = file.getName();
// 以流的形式下载文件。
InputStream fis = new BufferedInputStream(new FileInputStream(outPath));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.setHeader("Content-Type", "application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(), "ISO8859-1"));
response.addHeader("Content-Length", "" + file.length());
// response.setContentType("application/octet-stream");
OutputStream toClient = response.getOutputStream();
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (IOException ex) {
System.out.println(ex) ;
}
}
}
/*
*
* 2012-03-29
* 这个方法只能遍历一个List表格
* 其中
* 1.1
* 1.3.2
* 待优化
* */
@SuppressWarnings("unchecked")
public static void jxlDocTemplateAll(String realPath,Map<String,String> map,List<?> list,int listX,int listY,List<JXLExcelModel> jxlList,int[][] mergeInt,HttpServletResponse response) throws WriteException {
//1:读取Excel模版文件,加载到WritableWorkbook中 开始 ----------------------------------------
try {
//1.1:设置输出模版的文件名,以_bak.xls结尾(待优化)
String outPath = realPath.substring(0, realPath.length() - 4) + "_bak.xls" ;
//1.2: 判断是否有单元格要进行合并 开始-----------------------------
boolean merge = false ;
if(jxlList != null) {
/* List<JXLExcelModel> jxlList
JXLExcelModel这个Model中设置需要
合并单元格的起始X轴
合并单元格的起始Y轴
合并单元格的结束X轴
合并单元格的结束Y轴
*/
merge = true ;
}
//1.2: 判断是否有单元格要进行合并 结束-----------------------------
//1.3: 判断文件是否存在,如果存在才进行操作
if(fileExist(realPath)) {
//1.3.1 找到模版文件并加载,HSSFWorkbook只能读取,不能修改
HSSFWorkbook rwb = new HSSFWorkbook(new FileInputStream(realPath)) ;
//1.3.2 得到模版中的工作表(待优化),本文只能对模版中的第一个工作表进行修改,应该设置为可配置项
HSSFSheet sht = rwb.getSheetAt(0) ;
//1.3.3 初始化Map indexMap , 用来存储需要合并的单元格的坐标
Map<String,String> indexMap = null ;
/* 1.3.4
* 判断是否有需要替换的Paremeter 开始-------------------------------
* 通过map来遍历得到要替换对象在excel中的坐标并保存在(indexMap)坐标map中
* 格式 x|y
* */
if(map != null) {
indexMap = new HashMap<String,String>() ;
String indexList = "" ;
for(String value:map.keySet()) {//遍历是否存在要替换的Parameter坐标,并记录在Map中 格式: x|y
try {
//1.3.5 通过方法getCellindex(工作表,要比较的值) 得到在excel中详细坐标的核心方法
indexList = getCellindex(sht, value) ;
} catch(java.lang.RuntimeException e) {
continue ;
}
//1.3.6 向indexMap插入得到的值
indexMap.put(value, indexList) ;
}
}
// 1.3.4 判断是否有需要替换的Paremeter 结束-------------------------------
// 1.4.1 Workbook rwork 读取的模版只能读取不能修改
rwork = Workbook.getWorkbook(new File(realPath)) ; //读取模版文件
// 1.4.2 WritableWorkbook wwb 通过创建WritableWorkbook,并加载rwork 来实现修改EXCEL的操作
wwb = Workbook.createWorkbook(new FileOutputStream(outPath),rwork) ; //修改模版
//1.4.3 读取工作表
WritableSheet sheet = wwb.getSheet(0) ;
//1.4.4 查找工作表,如果没有获得相应工作表,先创建一个名为test的工作表
if(sheet == null) {
sheet = wwb.createSheet("test", 0) ;
}
//1.5 判断是否有需要替换的字段,如果有,进行替换操作 开始 ------------------------------------------
if(map != null) {
//1.5.1 先替换模版中的Parameter值 开始 ---------------------------------------------
WritableCellFormat wc1 = new WritableCellFormat();
//wc1.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
//wc1.setBackground(jxl.format.Colour.BLACK); // 设置单元格的背景颜色
wc1.setAlignment(Alignment.CENTRE); // 设置居中
// wc1.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc1.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
for(String value:indexMap.keySet()) {
//得到x轴坐标
int x = Integer.parseInt(indexMap.get(value).split("#")[0]) ;
//得到y轴坐标
int y = Integer.parseInt(indexMap.get(value).split("#")[1]) ;
//wc.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
//wc.setBackground(jxl.format.Colour.BLACK); // 设置单元格的背景颜色
//WritableFont wfont = new WritableFont(WritableFont.createFont("宋体"), 14);
//WritableCellFormat font = new WritableCellFormat(wfont);
Label label01 = null ;
label01 = new Label(y,x,map.get(value),wc1) ;
sheet.addCell(label01) ;
}
//1.5.1 先替换模版中的Parameter值 结束 ---------------------------------------------
}
//1.5 判断是否有需要替换的字段,如果有,进行替换操作 结束 ------------------------------------------
//1.6 通过list循环插入列值 开始-------------------------------------------------------------------
if(list != null && list.size() > 0) {
//1.6.1 通过反射得到list的所有列和值,并返回一个二维数组的list, list[0]返回类型 list[1]返回get方法 list[2]返回值
List<Object> listValue = ReflectUtil.getAllFieldAndValue(list) ;
//1.6.2 只要返回值的list
List<Object[]> dataValueList = (List<Object[]>) listValue.get(2) ;
WritableCellFormat wc2 = new WritableCellFormat();
wc2.setAlignment(Alignment.CENTRE); // 设置居中
wc2.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc2.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc2.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc2.setWrap(true) ; //设置单元格属性为自动换行
for(int i = 0 ; i < dataValueList.size() ; i ++ ) {
sheet.insertRow(listY) ; //在指定位置插入一新行,用以插入数据
Label label02 = null ;
Object[] object = dataValueList.get(i) ;
for(int num = 0 ; num < object.length ; num ++ ) {
String value = "" ;
if(object[num] != null ) {
value = object[num].toString() ;
}
label02 = new Label(listX + num , listY, value ,wc2) ;
sheet.addCell(label02) ;
}
listY += 1 ;
}
}
//1.6 通过list循环插入列值 结束---------------------------------------------
//1.7 对指定单元格进行合并 开始-----------------------------------------
if(merge) {
JXLExcelModel jxlModel = null ;
WritableCellFormat wc3 = new WritableCellFormat() ;
wc3.setAlignment(Alignment.CENTRE); // 设置居中
wc3.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc3.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc3.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc3.setWrap(true) ; //设置单元格属性为自动换行
for(int jj = 0 ; jj < jxlList.size() ; jj ++ ) {
//sheet.mergeCells(0, 5, 0, (5 + getList().size()));
jxlModel = jxlList.get(jj) ;
sheet.mergeCells(jxlModel.getStartX(), jxlModel.getStartY(), jxlModel.getEndX(), jxlModel.getEndY());
/*
* 如果有单元格进行合并,判断是否有需要填充的值
* */
if(jxlModel.getMergeText() != null) {
sheet.addCell(new Label(jxlModel.getStartX(),jxlModel.getStartY(),jxlModel.getMergeText(),wc3)) ;
}
}
}
//1.7 对指定样式进行合并 结束-----------------------------------------
try {
wwb.write() ;
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
System.out.println("线程异常") ;
}
} else {
System.out.println("模版文件不存在 !!!") ;
}
} catch(Exception e) {
System.out.println(e) ;
} finally {
//9.关闭wwb,以释放内存
if(rwork != null) {
rwork.close() ;
}
if(wwb != null) {
try {
wwb.close() ;
} catch (WriteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
String outPath = realPath.substring(0, realPath.length() - 4) + "_bak.xls" ;
HSSFWorkbook rwb2 = null ;
//8.对指定列进行上下行合并 开始----------------------------------------------------------
if(mergeInt != null && list.size() > 0) {
try {
rwb2 = new HSSFWorkbook(new FileInputStream(outPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
HSSFSheet sht2 = rwb2.getSheetAt(0) ;
HSSFRow rows = null ;
HSSFCell cl = null ;
HSSFRow rows2 = null ;
HSSFCell cl2 = null ;
Workbook rwork2 = null ;
WritableWorkbook wwb2 = null ;
try {
rwork2 = Workbook.getWorkbook(new File(outPath)) ;
} catch (BiffException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //读取模版文件
try {
wwb2 = Workbook.createWorkbook(new FileOutputStream(outPath),rwork2) ;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //修改模版
WritableSheet sheet2 = wwb2.getSheet(0) ;
WritableCellFormat wc4 = new WritableCellFormat();
wc4.setAlignment(Alignment.CENTRE);
wc4.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc4.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc4.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc4.setWrap(true) ; //设置单元格属性为自动换行
//一列合并 {0,4,350} 0:列 1:行 2:长度
for(int mergeM = 0 ; mergeM < mergeInt.length ; mergeM ++ ) {//合并列数
int maxMergeInt = 0 ;
for(int mergeMin = mergeInt[mergeM][1] ; mergeMin < (mergeInt[mergeM][1] + mergeInt[mergeM][2]) - 1 ; ) {//一列一列执行
//这里是指定行
rows = sht2.getRow(mergeMin) ; //rows得到当前行的数据
if(rows == null) {
continue ;
} else {
cl = rows.getCell(mergeInt[mergeM][0]) ;//{0,4,350}
maxMergeInt = 1 ;
//从本行起开始遍历行,一直到和本行值不一样为止
for(int maxMergeIntSize = mergeMin ; maxMergeIntSize < (mergeInt[mergeM][1] + mergeInt[mergeM][2]) - 1 ; maxMergeIntSize ++ ) {
//循环到下N行,如果本行的值是相同的;
rows2 = sht2.getRow(mergeMin + maxMergeInt) ;
cl2 = rows2.getCell(mergeInt[mergeM][0]) ;
if(cl != null && cl2 != null) {
if(!cl.getRichStringCellValue().toString().equals("") && cl.getRichStringCellValue().toString().trim().equals(cl2.getRichStringCellValue().toString().trim())) {
maxMergeInt ++ ;
} else {
continue ;
}
}
}
rows2 = sht2.getRow(mergeMin + maxMergeInt - 1) ;
cl2 = rows2.getCell(mergeInt[mergeM][0]) ;
if(cl != null && cl2 != null) {
if(!cl.getRichStringCellValue().toString().equals("") && cl.getRichStringCellValue().toString().trim().equals(cl2.getRichStringCellValue().toString().trim())) {
//如果列的上下行相等,得到X,Y坐标,并进行合并
try {
sheet2.mergeCells(mergeInt[mergeM][0], mergeMin, mergeInt[mergeM][0], mergeMin + maxMergeInt - 1) ;
sheet2.addCell(new Label(mergeInt[mergeM][0], mergeMin ,cl2.getRichStringCellValue().toString(),wc4)) ;
} catch (WriteException e) {
e.printStackTrace();
} // 设置居中
} else {
}
}
}
mergeMin += maxMergeInt ;
}
}
try {
wwb2.write() ;
rwork2.close() ;
try {
wwb2.close() ;
} catch (WriteException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//8.通过流实现文件下载
try {
//response = ServletActionContext.getResponse();
//String path = getRequest().getParameter("fileName");
// path是指欲下载的文件的路径。
File file = new File(outPath);
// 取得文件名。
String filename = file.getName();
// 以流的形式下载文件。
InputStream fis = new BufferedInputStream(new FileInputStream(outPath));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.setHeader("Content-Type", "application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(), "ISO8859-1"));
response.addHeader("Content-Length", "" + file.length());
// response.setContentType("application/octet-stream");
OutputStream toClient = response.getOutputStream();
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (IOException ex) {
System.out.println(ex) ;
}
}
}
/*
//1 测试用的2003版excel文档路径
String filePath = "C:\\temp\\test.xls" ;
//2 模拟生成List<?>
List<?> list = com.JXLTestMain.getTestList1() ;
//将参数传入JXL处理类中生成新的Excel
/*
* 设立 JXLListModel 是为了实现将要遍历的List<?>指定到sheet和显示指定的列
* 如果 JXLListModel.sheet 不初始值则默认遍历到第一个sheet中
* 如果 JXLListModel.listShow 不初始值则默认显示list所有列
*
//String[] listCol = {"getId","getName","getAddress","getSchool","getClasses"} ;
String[] listCol = {"getId","getName","getAddress","getSchool"} ;
//替换指定的值
Map<String,String> map = new HashMap<String,String>() ;
map.put("test", "测试用的Test") ;
map.put("list", "测试用的List") ;
map.put("map", "测试用的Map") ;
List<JXLListModel> tempList = new ArrayList<JXLListModel>() ;
JXLListModel listModel = new JXLListModel() ;
//listModel.setSheet(0) ;
listModel.setList(list) ;
listModel.setListX(0) ;
listModel.setListY(1) ;
listModel.setDisplayColumn(listCol) ;
tempList.add(listModel) ;
String[] listCol2 = {"getId","getName","getAddress","getSchool","getClasses"} ;
listModel = new JXLListModel() ;
listModel.setSheet(1) ;
listModel.setList(list) ;
listModel.setListX(0) ;
listModel.setListY(2) ;
listModel.setDisplayColumn(listCol2) ;
tempList.add(listModel) ;
List<JXLExcelModel> jxlModel = new ArrayList<JXLExcelModel>() ;
JXLExcelModel model = new JXLExcelModel() ;
model.setSheet(0) ;
model.setStartX(0) ;
model.setStartY(2) ;
model.setEndX(1) ;
model.setEndY(16) ;
model.setMergeText("测试合并1") ;
jxlModel.add(model) ;
model = new JXLExcelModel() ;
model.setSheet(1) ;
model.setStartX(0) ;
model.setStartY(2) ;
model.setEndX(1) ;
model.setEndY(16) ;
model.setMergeText("测试合并2") ;
jxlModel.add(model) ;
int[][] mergeInt = {{2,1,100,0},{2,2,100,1}} ;
com.ExcelImplTest.setExcelTest(filePath, map, tempList, jxlModel, mergeInt) ;
*/
/*
* String[][] insertImages : 插入图片 insertImage参数为 {{x,y,ImageUrl,width,height,Sheet},{x,y,ImageUrl,width,height,Sheet}}
* X轴,Y轴,图片路径,宽度,高度,工作簿
* String[][] insertImages = {{"0","0","C://Image//image.jpg","100","100","0"}} ;全参数
* String[][] insertImages = {{"C://Image//image.jpg","100","100","0"}} ;
* String[][] insertImages = {{"0","0","C://Image//image.jpg""0"}} ;
* String[][] insertImages = {{"0","0","C://Image//image.jpg"}} ;
* String[][] insertImages = {{"C://Image//image.jpg","0"}} ;
* String[][] insertImages = {{"C://Image//image.jpg"}} ;
* */
public static void setExcel(String filePath, Map<String,String> map, List<JXLListModel> listModel, List<JXLExcelModel> jxlList, int[][] mergeInt,String[][] insertImages, HttpServletResponse response) {
try {
jxlDocTemplateAll(filePath, map, listModel, jxlList, mergeInt,insertImages, response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
public static void setExcel(String filePath,String outPath, Map<String,String> map, List<JXLListModel> listModel, List<JXLExcelModel> jxlList, int[][] mergeInt, HttpServletResponse response) {
try {
jxlDocTemplateAll(filePath,outPath, map, listModel, jxlList, mergeInt, null, response) ;
} catch (WriteException e) {
e.printStackTrace();
}
}
/*
* <p>
* 命名定义:
* workBookNumber : 工作表个数
* listModel : 要处理的工作簿整合的List
* </p>
* */
@SuppressWarnings("unchecked")
public static void jxlDocTemplateAll(String filePath,Map<String,String> map, List<JXLListModel> listModel, List<JXLExcelModel> jxlList,int[][] mergeInt,String[][] insertImages, HttpServletResponse response) throws WriteException {
//1:读取Excel模版文件,加载到WritableWorkbook中 开始 ----------------------------------------
//1.1:设置输出模版的文件名,以_bak.xls结尾(待优化)
String outPath = filePath.substring(0, filePath.length() - 4) + "_bak.xls" ;
try {
//1.2: 判断是否有单元格要进行合并 开始-----------------------------
boolean merge = false ;
if(jxlList != null) {
/* JXLModel这个Model中设置需要
指定工作簿,如果是空的话默认为0
合并单元格的起始X轴
合并单元格的起始Y轴
合并单元格的结束X轴
合并单元格的结束Y轴
*/
merge = true ;
}
//1.2: 判断是否有单元格要进行合并 结束-----------------------------
//1.3: 判断文件是否存在,如果存在才进行操作
if(fileExist(filePath)) {
/* 1.4 开始============================================================================================
* <p>
* 此操作作用于List<JXLListModel>中的参数有多个,说明了我们定义了一个EXCEL中有多个工作簿<sheet>需要操作。
* 因此List<JXLListModel>.size() 为需要处理的工作表次数,我们用for循环来实现操作各个工作表内容。
* </p>
*/
JXLListModel list = null ; //定义JXL处理模型
// 1.4.1 Workbook rwork 读取的模版只能读取不能修改
rwork = Workbook.getWorkbook(new File(filePath)) ; //读取模版文件
// 1.4.2 WritableWorkbook wwb 通过创建WritableWorkbook,并加载rwork 来实现修改EXCEL的操作
wwb = Workbook.createWorkbook(new FileOutputStream(outPath),rwork) ; //修改模版
for(int sheetNumber = 0 ; sheetNumber < wwb.getSheets().length ; sheetNumber ++ ) {
// 1.4.3 将指定的Map值替换到EXCEL所有的工作簿中 开始------------------------------------------------
if(map != null) {
/*
* <p>
* 我们开始获取工作簿中需要替换的坐标。
* sheet每次读取时加载一次。
* 获取坐标的格式设定为:
* Map<String,String>
* 其中key为要替换的名称,value格式为坐标轴x|y
* </p>
* */
//1.4.3 读取工作表
sheetToMap = wwb.getSheet(sheetNumber) ;
setIndexMap(filePath, map, sheetNumber) ;
setMap(map) ;
}
// 1.4.3 将指定的Map值替换到EXCEL所有的工作簿中 结束------------------------------------------------
}
if(listModel != null) {
for(int workBookNumber = 0 ; workBookNumber < listModel.size() ; workBookNumber ++ ) {
list = listModel.get(workBookNumber) ; //初始化第N个工作簿
/*
* <p>
* 将JXLListModel拆分,我们能得到以下参数:
* int sheet ; 需要操作的第几个工作簿
* List<?> list ; 需要遍历的List
* int listX ; 初始化此List的X轴坐标
* int listY ; 初始化此List的Y轴坐标
* </p>
*/
//1.4.3 读取工作表
sheet = wwb.getSheet(list.getSheet()) ;
//1.4.4 查找工作表,如果没有找到EXCEL中第N个工作簿,我们将自动在最后创建一个新的名为test的工作簿
if(sheet == null) {
sheet = wwb.createSheet("test", workBookNumber) ;
}
//1.4.5 遍历list到EXCEL指定工作簿中开始===========================================================
if(list != null) {
if(list.getList().size() > 0) {
setList(list.getList(), list.getListX(), list.getListY(), list.getDisplayColumn()) ;
}
}
//1.4.5 遍历list到EXCEL指定工作簿中结束===========================================================
}
}
/*
* 1.4 结束============================================================================================
* */
//1.7 对指定单元格进行合并 开始-----------------------------------------
if(merge) {
JXLExcelModel jxlModel = null ;
WritableCellFormat wc3 = new WritableCellFormat() ;
wc3.setAlignment(Alignment.CENTRE); // 设置居中
wc3.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
// wc3.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc3.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc3.setWrap(true) ; //设置单元格属性为自动换行
for(int jj = 0 ; jj < jxlList.size() ; jj ++ ) {
//sheet.mergeCells(0, 5, 0, (5 + getList().size()));
jxlModel = jxlList.get(jj) ;
//1.4.3 读取工作表
sheetToMerge = wwb.getSheet(jxlModel.getSheet()) ;
//1.4.4 查找工作表,如果没有找到EXCEL中第N个工作簿,我们将自动在最后创建一个新的名为test的工作簿
if(sheetToMerge == null) {
sheetToMerge = wwb.createSheet("test", 0) ;
}
sheetToMerge.mergeCells(jxlModel.getStartX(), jxlModel.getStartY(), jxlModel.getEndX(), jxlModel.getEndY());
/* 如果有单元格进行合并,判断是否有需要填充的值
*/
if(jxlModel.getMergeText() != null) {
if(jxlModel.getFontFormat() != null) {
WritableCellFormat wc4 = jxlModel.getFontFormat() ; //取得自定义的单元格属性
sheetToMerge.addCell(new Label(jxlModel.getStartX(),jxlModel.getStartY(),jxlModel.getMergeText(),wc4)) ;
} else {
sheetToMerge.addCell(new Label(jxlModel.getStartX(),jxlModel.getStartY(),jxlModel.getMergeText(),wc3)) ;
}
}
}
}
//1.7 对指定样式进行合并 结束-----------------------------------------
//1.8 插入图片 开始----------------------------------------------------
if(insertImages != null) {
if(insertImages.length > 0) {
//1.8.1 循环插入图片 开始----------------------------------------------
for(int insertImageInt = 0 ; insertImageInt < insertImages.length ; insertImageInt ++) {
//读取图片、插入图片
insertImage(insertImages[insertImageInt]) ;
}
//1.8.1 循环插入图片 结束----------------------------------------------
}
}
//1.8 插入图片 结束----------------------------------------------------
try {
wwb.write() ;
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
System.out.println("线程异常") ;
}
} else {
System.out.println("模版文件不存在 !!!") ;
}
} catch(Exception e) {
System.out.println(e) ;
} finally {
//9.关闭wwb,以释放内存
if(rwork != null) {
rwork.close() ;
}
if(wwb != null) {
try {
wwb.close() ;
} catch (WriteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/*for(int mergeSize = 0 ; mergeSize < mergeInt.length ; mergeSize ++) {
setMergeColumn(outPath, mergeInt, mergeSize) ;
}*/
//8.通过流实现文件下载
if(response != null){
try {
//response = ServletActionContext.getResponse();
//String path = getRequest().getParameter("fileName");
// path是指欲下载的文件的路径。
File file = new File(outPath);
// 取得文件名。
String filename = file.getName();
// 以流的形式下载文件。
InputStream fis = new BufferedInputStream(new FileInputStream(outPath));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.setHeader("Content-Type", "application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(), "ISO8859-1"));
response.addHeader("Content-Length", "" + file.length());
// response.setContentType("application/octet-stream");
OutputStream toClient = response.getOutputStream();
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (IOException ex) {
System.out.println(ex) ;
}
}
}
}
/*
* <p>
* 命名定义:
* workBookNumber : 工作表个数
* listModel : 要处理的工作簿整合的List
* </p>
* */
@SuppressWarnings("unchecked")
public static void jxlDocTemplateAll(String filePath,String outPath,Map<String,String> map, List<JXLListModel> listModel, List<JXLExcelModel> jxlList,int[][] mergeInt,String[][] insertImages, HttpServletResponse response) throws WriteException {
//1:读取Excel模版文件,加载到WritableWorkbook中 开始 ----------------------------------------
try {
//1.2: 判断是否有单元格要进行合并 开始-----------------------------
boolean merge = false ;
if(jxlList != null) {
/* JXLModel这个Model中设置需要
指定工作簿,如果是空的话默认为0
合并单元格的起始X轴
合并单元格的起始Y轴
合并单元格的结束X轴
合并单元格的结束Y轴
*/
merge = true ;
}
//1.2: 判断是否有单元格要进行合并 结束-----------------------------
//1.3: 判断文件是否存在,如果存在才进行操作
if(fileExist(filePath)) {
/* 1.4 开始============================================================================================
* <p>
* 此操作作用于List<JXLListModel>中的参数有多个,说明了我们定义了一个EXCEL中有多个工作簿<sheet>需要操作。
* 因此List<JXLListModel>.size() 为需要处理的工作表次数,我们用for循环来实现操作各个工作表内容。
* </p>
*/
JXLListModel list = null ; //定义JXL处理模型
// 1.4.1 Workbook rwork 读取的模版只能读取不能修改
rwork = Workbook.getWorkbook(new File(filePath)) ; //读取模版文件
// 1.4.2 WritableWorkbook wwb 通过创建WritableWorkbook,并加载rwork 来实现修改EXCEL的操作
wwb = Workbook.createWorkbook(new FileOutputStream(outPath),rwork) ; //修改模版
for(int sheetNumber = 0 ; sheetNumber < wwb.getSheets().length ; sheetNumber ++ ) {
// 1.4.3 将指定的Map值替换到EXCEL所有的工作簿中 开始------------------------------------------------
if(map != null) {
/*
* <p>
* 我们开始获取工作簿中需要替换的坐标。
* sheet每次读取时加载一次。
* 获取坐标的格式设定为:
* Map<String,String>
* 其中key为要替换的名称,value格式为坐标轴x|y
* </p>
* */
//1.4.3 读取工作表
sheetToMap = wwb.getSheet(sheetNumber) ;
setIndexMap(filePath, map, sheetNumber) ;
setMap(map) ;
}
// 1.4.3 将指定的Map值替换到EXCEL所有的工作簿中 结束------------------------------------------------
}
if(listModel != null) {
for(int workBookNumber = 0 ; workBookNumber < listModel.size() ; workBookNumber ++ ) {
list = listModel.get(workBookNumber) ; //初始化第N个工作簿
/*
* <p>
* 将JXLListModel拆分,我们能得到以下参数:
* int sheet ; 需要操作的第几个工作簿
* List<?> list ; 需要遍历的List
* int listX ; 初始化此List的X轴坐标
* int listY ; 初始化此List的Y轴坐标
* </p>
*/
//1.4.3 读取工作表
sheet = wwb.getSheet(list.getSheet()) ;
//1.4.4 查找工作表,如果没有找到EXCEL中第N个工作簿,我们将自动在最后创建一个新的名为test的工作簿
if(sheet == null) {
sheet = wwb.createSheet("test", workBookNumber) ;
}
//1.4.5 遍历list到EXCEL指定工作簿中开始===========================================================
if(list != null) {
if(list.getList().size() > 0) {
setList(list.getList(), list.getListX(), list.getListY(), list.getDisplayColumn()) ;
}
}
//1.4.5 遍历list到EXCEL指定工作簿中结束===========================================================
}
}
/*
* 1.4 结束============================================================================================
* */
//1.7 对指定单元格进行合并 开始-----------------------------------------
if(merge) {
JXLExcelModel jxlModel = null ;
WritableCellFormat wc3 = new WritableCellFormat() ;
wc3.setAlignment(Alignment.CENTRE); // 设置居中
wc3.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
// wc3.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc3.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc3.setWrap(true) ; //设置单元格属性为自动换行
for(int jj = 0 ; jj < jxlList.size() ; jj ++ ) {
//sheet.mergeCells(0, 5, 0, (5 + getList().size()));
jxlModel = jxlList.get(jj) ;
//1.4.3 读取工作表
sheetToMerge = wwb.getSheet(jxlModel.getSheet()) ;
//1.4.4 查找工作表,如果没有找到EXCEL中第N个工作簿,我们将自动在最后创建一个新的名为test的工作簿
if(sheetToMerge == null) {
sheetToMerge = wwb.createSheet("test", 0) ;
}
sheetToMerge.mergeCells(jxlModel.getStartX(), jxlModel.getStartY(), jxlModel.getEndX(), jxlModel.getEndY());
/* 如果有单元格进行合并,判断是否有需要填充的值
*/
if(jxlModel.getMergeText() != null) {
if(jxlModel.getFontFormat() != null) {
WritableCellFormat wc4 = jxlModel.getFontFormat() ; //取得自定义的单元格属性
sheetToMerge.addCell(new Label(jxlModel.getStartX(),jxlModel.getStartY(),jxlModel.getMergeText(),wc4)) ;
} else {
sheetToMerge.addCell(new Label(jxlModel.getStartX(),jxlModel.getStartY(),jxlModel.getMergeText(),wc3)) ;
}
}
}
}
//1.7 对指定样式进行合并 结束-----------------------------------------
//1.8 插入图片 开始----------------------------------------------------
if(insertImages != null) {
if(insertImages.length > 0) {
//1.8.1 循环插入图片 开始----------------------------------------------
for(int insertImageInt = 0 ; insertImageInt < insertImages.length ; insertImageInt ++) {
//读取图片、插入图片
insertImage(insertImages[insertImageInt]) ;
}
//1.8.1 循环插入图片 结束----------------------------------------------
}
}
//1.8 插入图片 结束----------------------------------------------------
try {
wwb.write() ;
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
System.out.println("线程异常") ;
}
} else {
System.out.println("模版文件不存在 !!!") ;
}
} catch(Exception e) {
System.out.println(e) ;
} finally {
//9.关闭wwb,以释放内存
if(rwork != null) {
rwork.close() ;
}
if(wwb != null) {
try {
wwb.close() ;
} catch (WriteException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/*for(int mergeSize = 0 ; mergeSize < mergeInt.length ; mergeSize ++) {
setMergeColumn(outPath, mergeInt, mergeSize) ;
}*/
//8.通过流实现文件下载
if(response != null){
try {
//response = ServletActionContext.getResponse();
//String path = getRequest().getParameter("fileName");
// path是指欲下载的文件的路径。
File file = new File(outPath);
// 取得文件名。
String filename = file.getName();
// 以流的形式下载文件。
InputStream fis = new BufferedInputStream(new FileInputStream(outPath));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.setHeader("Content-Type", "application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(), "ISO8859-1"));
response.addHeader("Content-Length", "" + file.length());
// response.setContentType("application/octet-stream");
OutputStream toClient = response.getOutputStream();
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (IOException ex) {
System.out.println(ex) ;
}
}
}
}
private static boolean isIntager(String str) {
try {
Integer.parseInt(str) ;
return true ;
} catch(java.lang.NumberFormatException e) {
return false ;
}
}
//插入图片
private static void insertImage(String[] imageAttribute) {
try {
@SuppressWarnings("unused")
boolean imagUrl = false ; //是否有图片路径
@SuppressWarnings("unused")
String filePath = "" ;
boolean imgSheet = false ; //是否指定工作簿
int imgSheetInt = 0 ;
boolean imgXY = false ; //是否制定坐标
int imgX = 0 ,imgY = 0 ;
boolean imgWH = false ; //是否指定宽、高
int imgWidth = 0 ,imgHeight = 0 ;
int ii = imageAttribute.length ;
if(ii == 1) {
imagUrl = true ;
filePath = imageAttribute[0] ;
} else if(ii == 2) {
imagUrl = true ;
filePath = imageAttribute[0] ;
imgSheet = true ;
imgSheetInt = Integer.parseInt(imageAttribute[1]) ;
} else if(ii == 3){
if(isIntager(imageAttribute[0])) { // X Y URL
imgXY = true ;
imagUrl = true ;
imgX = Integer.parseInt(imageAttribute[0]) ;
imgY = Integer.parseInt(imageAttribute[1]) ;
filePath = imageAttribute[2] ;
} else {
imgWH = true ;
imagUrl = true ;
filePath = imageAttribute[0] ;
imgWidth = Integer.parseInt(imageAttribute[1]) ;
imgHeight = Integer.parseInt(imageAttribute[2]) ;
}
} else if(ii == 4) {
if(isIntager(imageAttribute[0])) { // X Y URL
imgXY = true ;
imagUrl = true ;
imgSheet = true ;
imgX = Integer.parseInt(imageAttribute[0]) ;
imgY = Integer.parseInt(imageAttribute[1]) ;
filePath = imageAttribute[2] ;
imgSheetInt = Integer.parseInt(imageAttribute[3]) ;
} else {
imgWH = true ;
imagUrl = true ;
imgSheet = true ;
filePath = imageAttribute[0] ;
imgWidth = Integer.parseInt(imageAttribute[1]) ;
imgHeight = Integer.parseInt(imageAttribute[2]) ;
imgSheetInt = Integer.parseInt(imageAttribute[3]) ;
}
} else {
imgXY = true ;
imagUrl = true ;
imgWH = true ;
imgSheet = true ;
imgX = Integer.parseInt(imageAttribute[0]) ;
imgY = Integer.parseInt(imageAttribute[1]) ;
filePath = imageAttribute[2] ;
imgWidth = Integer.parseInt(imageAttribute[3]) ;
imgHeight = Integer.parseInt(imageAttribute[4]) ;
imgSheetInt = Integer.parseInt(imageAttribute[5]) ;
}
sheet = wwb.getSheet((imgSheet == true?imgSheetInt:0)) ;
if(fileExist(imageAttribute[0])) {
File image = new File(imageAttribute[0]) ; //得到文件
java.awt.image.BufferedImage bi7 = null ; //创建Image容器
try
{
bi7 = javax.imageio.ImageIO.read(image) ; //通过路径得到图片
}
catch (IOException e)
{
e.printStackTrace();
}
if(bi7 != null) { //得到图片
int picWidth = imgWH == true?imgWidth: bi7.getWidth() ; // 图片宽
int picHeight =imgWH == true?imgHeight: bi7.getHeight() ; // 图片高
// 输入参数, 图片显示的位置
double picBeginCol = 1.2;
double picBeginRow = 1.2;
double picCellWidth = 0.0; // 是 cell的跨越个数, 可小数
double picCellHeight = 0.0;
int _picWidth = picWidth * 32 ; // pic的宽度,循环递减, 是jxl的宽度单位, 32/15
for(int x=0; x< 1234; x++)
{
int bc = (int)Math.floor( picBeginCol + x ); // 3.6 to 3 // 本次循环所在cell位置
int v = sheet.getColumnView( bc ).getSize(); //本次cell宽,jxl单位
double _offset0 = 0.0; // >= 0 // 离左边的偏移量, 仅 x = 0 的时候才用
if( 0 == x )
_offset0 = ( picBeginCol - bc ) * v ; //
if( 0.0 + _offset0 + _picWidth > v ) // _picWidth 剩余长度超过一个cell时
{
// 计算本次cell内, pic 所占 ratio值, 累加到 picCellWidth
double _ratio = 1.0;
if( 0 == x )
_ratio = ( 0.0 + v - _offset0 ) / v;
picCellWidth += _ratio;
_picWidth -= (int)( 0.0 + v - _offset0 ); // int
} else {// _picWidth 剩余长度在一个cell内时
double _ratio = 0.0;
if( v != 0 )
_ratio = ( 0.0 + _picWidth ) / v;
picCellWidth += _ratio;
break;
}
if( x >= 1233 )
{}
}
int _picHeight = picHeight * 15 ; // pic的高度,循环递减, 是jxl的高度单位, 32/15
for(int x=0; x< 1234; x++)
{
int bc = (int)Math.floor( picBeginRow + x ); // 3.6 to 3 // 本次循环所在cell位置
int v = sheet.getRowView( bc ).getSize(); //本次cell高,jxl单位
double _offset0 = 0.0; // >= 0 // 离顶部的偏移量, 仅 x = 0 的时候才用
if( 0 == x )
_offset0 = ( picBeginRow - bc ) * v ; //
if( 0.0 + _offset0 + _picHeight > v ) // _picHeight 剩余长度超过一个cell时
{
// 计算本次cell内, pic 所占 ratio值, 累加到 picCellHeight
double _ratio = 1.0;
if( 0 == x )
_ratio = ( 0.0 + v - _offset0 ) / v;
// picCellHeight += 1.0;
picCellHeight += _ratio;
_picHeight -= (int)( 0.0 + v - _offset0 ); // int
} else { // _picHeight 剩余长度在一个cell内时
double _ratio = 0.0;
if( v != 0 )
_ratio = ( 0.0 + _picHeight ) / v;
picCellHeight += _ratio;
break;
}
if( x >= 1233 )
{}
}
WritableImage wimage = new WritableImage((imgXY == true?imgX:0), (imgXY == true?imgY:0), picCellWidth, picCellHeight, image);
sheet.addImage(wimage);
wwb.write() ;
}
}
//sheet = wwb.getSheet(list.getSheet()) ;
} catch(Exception e) {
e.printStackTrace() ;
}
}
@SuppressWarnings("unused")
private static void setMergeColumn(final String outPath, final int[][] mergeInt, final int mergeSize) throws WriteException {
HSSFWorkbook rwb2 = null ;
//8.对指定列进行上下行合并 开始----------------------------------------------------------
if(mergeInt != null) {
try {
rwb2 = new HSSFWorkbook(new FileInputStream(outPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
HSSFSheet sht2 = rwb2.getSheetAt(mergeSize) ;
HSSFRow rows = null ;
HSSFCell cl = null ;
HSSFRow rows2 = null ;
HSSFCell cl2 = null ;
Workbook rwork2 = null ;
WritableWorkbook wwb2 = null ;
try {
rwork2 = Workbook.getWorkbook(new File(outPath)) ;
} catch (BiffException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //读取模版文件
try {
wwb2 = Workbook.createWorkbook(new FileOutputStream(outPath),rwork2) ;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //修改模版
WritableSheet sheet2 = null ;
WritableCellFormat wc4 = new WritableCellFormat();
wc4.setAlignment(Alignment.CENTRE);
wc4.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc4.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc4.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc4.setWrap(true) ; //设置单元格属性为自动换行
sheet2 = wwb2.getSheet(mergeSize) ;
for(int mergeM = 0 ; mergeM < mergeInt.length ; mergeM ++ ) {
int maxMergeInt = 0 ;
for(int mergeMin = mergeInt[mergeM][1] ; mergeMin < (mergeInt[mergeM][1] + mergeInt[mergeM][2]) - 1 ;) {
//这里是指定行
rows = sht2.getRow(mergeMin) ; //rows得到当前行的数据
if(rows == null) {
continue ;
} else {
cl = rows.getCell(mergeInt[mergeM][0]) ;
maxMergeInt = 1 ;
//从本行起开始遍历行,一直到和本行值不一样为止
for(int maxMergeIntSize = mergeMin ; maxMergeIntSize < (mergeInt[mergeM][1] + mergeInt[mergeM][2]) - 1 ; maxMergeIntSize ++ ) {
//循环到下N行,如果本行的值是相同的;
rows2 = sht2.getRow(mergeMin + maxMergeInt) ;
//System.out.println((short)mergeInt[mergeM][0] + " | " + mergeM + " | " + mergeMin + " | " + maxMergeInt) ;
try {
cl2 = rows2.getCell(mergeInt[mergeM][0]) ;
} catch(java.lang.NullPointerException e) {
//cl2 = rows2.getCell((short)(mergeInt[mergeM][0])) ;
break ;
}
if(cl != null && cl2 != null) {
if(!cl.getRichStringCellValue().toString().equals("") && cl.getRichStringCellValue().toString().trim().equals(cl2.getRichStringCellValue().toString().trim())) {
maxMergeInt ++ ;
} else {
break ;
}
}
}
rows2 = sht2.getRow(mergeMin + maxMergeInt - 1) ;
cl2 = rows2.getCell(mergeInt[mergeM][0]) ;
if(cl != null && cl2 != null) {
if(!cl.getRichStringCellValue().toString().equals("") && cl.getRichStringCellValue().toString().trim().equals(cl2.getRichStringCellValue().toString().trim())) {
//如果列的上下行相等,得到X,Y坐标,并进行合并
try {
sheet2.mergeCells(mergeInt[mergeM][0], mergeMin, mergeInt[mergeM][0], mergeMin + maxMergeInt - 1) ;
sheet2.addCell(new Label(mergeInt[mergeM][0], mergeMin ,cl2.getRichStringCellValue().toString(),wc4)) ;
} catch (WriteException e) {
e.printStackTrace();
} // 设置居中
} else {
}
}
}
mergeMin += maxMergeInt ;
}
}
try {
wwb2.write() ;
rwork2.close() ;
try {
wwb2.close() ;
} catch (WriteException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//设置indexMap坐标(用于指定sheet中的map)
@SuppressWarnings("unused")
private static void setIndexMap(final String filePath, final Map<String,String> map, final int sheetNum) {
try {
HSSFWorkbook rwb = new HSSFWorkbook(new FileInputStream(filePath)) ;
//1.3.2 得到模版中的工作表(待优化),本文只能对模版中的第一个工作表进行修改,应该设置为可配置项
HSSFSheet sht = rwb.getSheetAt(sheetNum) ;
if(sht == null) {
sht = rwb.getSheetAt(0) ;
}
indexMap = new HashMap<String,String>() ;
String indexList = "" ;
for(String value:map.keySet()) {//遍历是否存在要替换的Parameter坐标,并记录在Map中 格式: x|y
try {
//1.3.5 通过方法getCellindex(工作表,要比较的值) 得到在excel中详细坐标的核心方法
indexList = getCellindex(sht, value) ;
} catch(java.lang.RuntimeException e) {
continue ;
}
//1.3.6 向indexMap插入得到的值
indexMap.put(value, indexList) ;
}
} catch(Exception e) {
System.out.println(" == 设置坐标失败 == ") ;
}
}
//遍历Map到excel中
@SuppressWarnings("unused")
private static void setMap(final Map<String,String> map) {
try {
WritableCellFormat wc1 = new WritableCellFormat();
wc1.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
//wc1.setBackground(jxl.format.Colour.BLACK); // 设置单元格的背景颜色
wc1.setAlignment(Alignment.CENTRE); // 设置居中
wc1.setBorder(Border.ALL, BorderLineStyle.NONE); // 设置边框线
wc1.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
for(String value:indexMap.keySet()) {
//得到x轴坐标
int x = Integer.parseInt(indexMap.get(value).split("#")[0]) ;
//得到y轴坐标
int y = Integer.parseInt(indexMap.get(value).split("#")[1]) ;
//wc.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
//wc.setBackground(jxl.format.Colour.BLACK); // 设置单元格的背景颜色
//WritableFont wfont = new WritableFont(WritableFont.createFont("宋体"), 14);
//WritableCellFormat font = new WritableCellFormat(wfont);
Label label01 = null ;
label01 = new Label(y,x,map.get(value),wc1) ;
//author wdx 20130326
if(x==0){ //判断是否是第一行,第一行为大标题,可能对其他的表格式有影响
WritableFont wfont = new WritableFont(WritableFont.createFont("宋体"), 20);
WritableCellFormat font = new WritableCellFormat(wfont);
if(value.equals("head")){
font.setBackground(jxl.format.Colour.GRAY_25);
font.setBorder(Border.BOTTOM, BorderLineStyle.THIN);
font.setFont(new WritableFont(WritableFont.createFont("Arial"), 20,WritableFont.BOLD)) ;
}
font.setAlignment(Alignment.CENTRE);
label01.setCellFormat(font);
}else{
WritableCellFormat wc2 = new WritableCellFormat();
//修改打印表单作为参数能添加边框
wc2.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
//wc1.setBackground(jxl.format.Colour.BLACK); // 设置单元格的背景颜色
wc2.setAlignment(Alignment.CENTRE); // 设置居中
wc2.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc2.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
if(map.get(value).equals("签证送办日期")||map.get(value).equals("签证返回日期")||map.get(value).equals("签证受理日期")){
wc2.setBorder(Border.TOP, BorderLineStyle.THIN);
}
if(value.equals("total")){
wc2.setVerticalAlignment(jxl.format.VerticalAlignment.TOP);//上下居中
wc2.setFont(new WritableFont(WritableFont.createFont("Arial"), 20,WritableFont.BOLD)) ;
}
label01.setCellFormat(wc2);
}
sheetToMap.addCell(label01) ;
}
} catch(Exception e) {
System.out.println(" == 遍历sheet Map 失败 == ") ;
}
}
//遍历List<?>到excel中
@SuppressWarnings("unchecked")
private static void setList(List<?> list, int listX, int listY, String[] displayColumm) {
try {
//1.6.1 通过反射得到list的所有列和值,并返回一个二维数组的list, list[0]返回类型 list[1]返回get方法 list[2]返回值
List<Object> listValue = ReflectUtil.getAllFieldAndValue2(list,displayColumm) ;
//1.6.2 只要返回值的list
List<Object[]> dataValueList = (List<Object[]>) listValue.get(2) ;
WritableCellFormat wc2 = new WritableCellFormat();
wc2.setAlignment(Alignment.CENTRE); // 设置居中
wc2.setFont(new WritableFont(WritableFont.createFont("宋体"), 12)) ;
wc2.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wc2.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);//上下居中
wc2.setWrap(true) ; //设置单元格属性为自动换行
for(int i = 0 ; i < dataValueList.size() ; i ++ ) {
sheet.insertRow(listY) ; //在指定位置插入一新行,用以插入数据
Label label02 = null ;
Object[] object = dataValueList.get(i) ;
for(int num = 0 ; num < object.length ; num ++ ) {
String value = "" ;
if(object[num] != null ) {
value = object[num].toString() ;
}
label02 = new Label(listX + num , listY, value ,wc2) ;
sheet.addCell(label02) ;
}
listY += 1 ;
}
} catch(Exception e) {
System.out.println(" == 遍历List<?> 出错 == ") ;
}
}
/*
* 通过Field遍历Object Bean的值
* */
public static Object[] field2Value(Field[] f, Object o) throws Exception {
Object[] value = new Object[f.length];
for (int i = 0; i < f.length; i++) {
//try {
value[i] = f[i].get(o);
//System.out.println(value[i]);
// } catch(Exception e) {
// value[i] = "" ;
// }
}
return value;
}
/**
* 判断XML文件是否存在.
* @param fileName
* @return
*/
private static boolean fileExist(String realPath) {
java.io.File objFile = new java.io.File(realPath) ;
if (objFile.exists()) {
return true;
} else {
return false;
}
}
/**
* 查找匹配的单元格
* @param sheet
* @param value 根据此参数查找单元格的值
* @param 必须在EXCEL表中存在要替换的Paremeter值
* @return Cell
*/
public static String getCellindex(HSSFSheet sheet,String value) {
String list = "" ;
HSSFCell cell = null;
HSSFRow rows = null ;
HSSFCell cl = null ;
for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
//Row row = sheet.getRow(i);
rows = sheet.getRow(i) ;
if (rows == null) {
continue;
} else {
for (int j = rows.getFirstCellNum(); j < rows.getLastCellNum(); j++) {
cl = rows.getCell(j) ;
if (cl == null) {
continue;
} else {
if (String.valueOf(cl.getRichStringCellValue()).equals(value.trim())) {
cell = cl;
list = i + "#" + j ;
break ;
} else {
continue;
}
}
}
}
}
if (cell == null) {
throw new RuntimeException("没有比配的单元格");
}
return list ;
}
}
以上是 Java生成操作excel(超详细,例如xml文件生成excel) 的全部内容, 来源链接: utcz.com/z/391214.html