POI技术定义
我所理解的POI即可以通过代码自动生成Word、Excel、PPT的一套apache提供的API。它与JXL最大的不同处的是,JXL只能生成Excel、简单点,POI写Excel,麻烦。本楼主在一无所知的情况下,用POI写了这个稍微好看点的Excel,差点要了我半条命,满满的都是套路~~~
1、导包
从网上下载poi 相关jar包点击打开链接(http://download.csdn.net/detail/pumpkin09/7077011)
下载之后将该类包导入项目的lib中即可。
2.编写代码
(1)下边是最终生成的效果图模板
(2)main方法的内容
(3)欧了,开始进入createExcel方法看具体的逻辑
/*
* 创建excel的入口方法,附带字体格式修改功能,调用该方法生成Excel,如果数据为对象集合,
* 请调用本类最下边的转换字符串数组方法(注意不要忘了保证集合第一条数组里存的是标题,之后才是数据),转换后再调用生成excel
*/
public static boolean createExcel(String outputPath,String sheetName,String headName,List
data,Map
style){
boolean result = false;
int length = data.get(0).length; //得到生成Excel的列数
if(data == null || data.size() == 0 || data.get(0).length == 0){
System.out.println("没有数据可生成excel");
return result;
}
HSSFWorkbook hw = new HSSFWorkbook(); //创建Excel对象
HSSFSheet hs = hw.createSheet(sheetName); //创建sheet对象
result = exportExcel(outputPath,headName,data,style,hw,hs);
return result;
} /*
* 创建excel的入口方法,默认字体格式,调用该方法生成Excel,如果数据为对象集合,
* 请调用本类最下边的转换字符串数组方法(注意不要忘了保证集合第一条数组里存的是标题,之后才是数据),转换后再调用生成excel
*/
public static boolean createExcel(String outputPath,String sheetName,String headName,List
data){
Map
style = new HashMap
(); style.put("top", new String[]{"宋体","25","#1256cc","#ffffff","粗体"}); //默认带合并单元格大标题,格式为蓝色粗体,无背景,字体大小为30 style.put("title", new String[]{"黑体","15","#000000","#cccccc","粗体"}); //默认带字段值小标题,格式为黑色粗体,灰色网格背景,字体大小为15 style.put("content", new String[]{"宋体","10","#000000","#ffffff","常规"}); //默认内容,格式为宋体常规,无背景,字体大小为10 return createExcel(outputPath,sheetName,headName,data,style); }
在这里要说明一下,方法中的参数style,是自定义excel的属性,可以选字体,颜色等等,第二步中调用的createExcel方法实际上是调用了下边的这个个默认的createExcel重载方法。
/*
* 创建excel的入口方法,默认字体格式,调用该方法生成Excel,如果数据为对象集合,
* 请调用本类最下边的转换字符串数组方法(注意不要忘了保证集合第一条数组里存的是标题,之后才是数据),转换后再调用生成excel
*/
public static boolean createExcel(String outputPath,String sheetName,String headName,List
data){
Map
style = new HashMap
();
style.put("top", new String[]{"宋体","25","#1256cc","#ffffff","粗体"}); //默认带合并单元格大标题,格式为蓝色粗体,无背景,字体大小为30
style.put("title", new String[]{"黑体","15","#000000","#cccccc","粗体"}); //默认带字段值小标题,格式为黑色粗体,灰色网格背景,字体大小为15
style.put("content", new String[]{"宋体","10","#000000","#ffffff","常规"}); //默认内容,格式为宋体常规,无背景,字体大小为10
return createExcel(outputPath,sheetName,headName,data,style);
}
在该默认方法中对生成的excel有默认的设置,效果即上图excel样板。
以下为调整属性的方法
/*
* 导出excel,excel字体样式修改方法
*/
@SuppressWarnings("deprecation")
public static boolean exportExcel(String outputPath,String headName,List
data,Map
formStyle,Workbook wb,Sheet hs){
FileOutputStream fs = null;
try {
File file = new File(outputPath);
if(!file.exists()){
file.getParentFile().mkdirs();
}
fs = new FileOutputStream(file);
//设置大标题合并单元格范围(开始行,结束行,开始列,结束列)默认从0开始
CellRangeAddress ar = new CellRangeAddress(0, 3,(short)0, (short)(data.get(0).length-1));
hs.addMergedRegion(ar); //合并单元格
String[] topForm = formStyle.get("top");
createCellTitle(0,3,(short)0, (short)(data.get(0).length-1),hs,wb,headName,topForm);
/*
* 注意下边这个格子样式(styleContent)一定要放在下边for循环之外设置,
* 是因为changeColor方法用到一个静态变量a,如果放在里边,频繁的去设置格子样式,
* 会导致a不断变化,造成背景颜色和字体颜色会乱
*/
String[] titleForm = formStyle.get("title");
short titleHeight = Short.valueOf(titleForm[1]);
CellStyle styleContent = designCellStyle(wb,titleForm[0],titleHeight,titleForm[2],titleForm[3],titleForm[4]);
//在大标题下第一行开始写字段名(小标题)并修改字体样式
Row hrTitle = hs.createRow(4);
for(int i = 0;i
colLength){
hs.setColumnWidth(j, contentL); //自动设置列宽
}
celContent.setCellValue(contentV); //在格子中赋值
celContent.setCellStyle(sty); //将该格子应用此样式
}
hrContent.setHeightInPoints(contentHeight+(short)6); //将内容数据行高设置为(内容字体高度+6)
}
wb.write(fs);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}finally{
if(fs !=null){
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
* 设置字体格式
* form为字体样式 例如:楷体
* formHeight 为字体大小
* color为字体颜色
* bold 为字体加粗或常规
* 返回值为cellStyle,可以将该类型添加到一个cell里,即对该cell可以调整字体格式
*/
public static CellStyle designCellStyle(Workbook wb,String form,short formHeight,String colorForm,String colorBack,String bold){
//创建一个字体
Font font = wb.createFont();
//设置字体高度
font.setFontHeightInPoints(formHeight);
//设置字体样式
font.setFontName(form);
font.setColor(changeColor(colorForm,wb));
short boldValue = (short)0;
if("加粗".equals(bold)){
boldValue = Font.BOLDWEIGHT_BOLD;
}else if("常规".equals(bold)){
boldValue = Font.BOLDWEIGHT_NORMAL;
}
font.setBoldweight(boldValue);
// //设置是否使用斜体
// font.setItalic(true);
// //设置是否删除线通过字体
// font.setStrikeout(true);
//将创建的Font设置给CellStyle,所以需要创建一个新的Font
CellStyle style = wb.createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER_SELECTION); //设置字体水平居中
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //设置字体垂直居中
style.setFont(font);
style.setFillPattern(CellStyle.SOLID_FOREGROUND); //设置背景色没有这一步,下一步将没有作用,纯色使用前景颜色填充
style.setFillForegroundColor(changeColor(colorBack,wb)); //设置前景颜色(不能设置成背景颜色)
style.setBorderBottom((short)1);
style.setBorderLeft((short)1);
style.setBorderTop((short)1);
style.setBorderRight((short)1);
return style;
}
/**
* 自动调整字体颜色逻辑
* str传入的是十六进制格式调整颜色
*
*/
static int a = 0;
public static short changeColor(String str,Workbook wb){
a++;
short value = (short)(HSSFColor.BLACK.index+a);
//处理把它转换成十六进制并放入一个数
int[] color=new int[3];
color[0]=Integer.parseInt(str.substring(1, 3), 16);
color[1]=Integer.parseInt(str.substring(3, 5), 16);
color[2]=Integer.parseInt(str.substring(5, 7), 16);
//自定义颜色
HSSFPalette palette = ((HSSFWorkbook) wb).getCustomPalette();
palette.setColorAtIndex(value,(byte)color[0], (byte)color[1], (byte)color[2]);
//将自定义的颜色引入进来
return value;
}
public static void createCellTitle(int rowFrom,int rowTo,short colFrom,short colTo,Sheet hs,Workbook wb,String headName,String[] topForm){
for(int i = rowFrom;i<=rowTo;i++){
Row rowTitle = hs.createRow(i);
for(short j = colFrom;j<=colTo;j++){
Cell cellTitle = rowTitle.createCell(j);
CellStyle style = wb.createCellStyle();
style.setBorderBottom((short)1);
style.setBorderLeft((short)1);
style.setBorderTop((short)1);
style.setBorderRight((short)1);
if(i == rowFrom && j== colFrom){
cellTitle.setCellValue(headName);
short topheight = Short.valueOf(topForm[1]);
rowTitle.setHeightInPoints(topheight); //将大标题的行高设置为(字体高度+5)
style = designCellStyle(wb,topForm[0],topheight,topForm[2],topForm[3],topForm[4]);
cellTitle.setCellStyle(style); //将大标题单元格应用此样式
continue;
}
cellTitle.setCellStyle(style);
}
}
}
//将对象集合转换为字符数组集合(以下五个方法都是起到对象转换成字符数组的作用)
public static List
ObjectChangeToStringArray(List list){
List
resultList = new ArrayList
();
for(Object obj:list){
String[] colNames = columnResult(obj.getClass());
if(colNames != null || colNames.length !=0){ //如果有属性名,说明是对象
}
String result = "";
for(String cname:colNames){
String methodName = getRefMethodName(cname,false);
String value = (String)ref(obj,methodName,null,false,false) ;
result +=(value+",");
}
String [] resultArray = result.substring(0, result.lastIndexOf(",")).split(",");
resultList.add(resultArray);
}
return resultList;
}
public static String[] columnResult(Class cla){
Field[] fields=cla.getDeclaredFields();
if(fields.length>0){
String before="";
for(Field f:fields){
before+=(f.getName()+"/");
}
String[] columns=before.split("/");
return columns;
}
return null;
}
private static Object ref(Object obj,String mName,Object value,boolean isSet,boolean isClob){
if(mName == null) return null;
Object ret = null;
try{
Method method = null;
Class
c = obj.getClass();
method = isSet
? c.getMethod(mName,new Class[]{isClob?java.sql.Clob.class:String.class})
: c.getMethod(mName);
if(method != null){
if(isSet){
method.invoke(obj,new Object[]{value});
}else{
ret = method.invoke(obj);
}
}
}catch(Exception e){
e.printStackTrace();
}
return ret;
}
private static String toFirstUpperCase(String src){
String f = src.substring(0,1);
return f.toUpperCase() + src.substring(1,src.length());
}
private static String getRefMethodName(String name,boolean isSet){
return (isSet?"set":"get") + toFirstUpperCase(name);
}
3.全部代码
empty
因为时间紧迫具体我没有细说,总是POI写Excel我个人感觉还是比较麻烦的。很多坑。。