Java生成操作excel(超详细,例如xml文件生成excel)

java

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

回到顶部