POI技术定义

我所理解的POI即可以通过代码自动生成Word、Excel、PPT的一套apache提供的API。它与JXL最大的不同处的是,JXL只能生成Excel、简单点,POI写Excel,麻烦。本楼主在一无所知的情况下,用POI写了这个稍微好看点的Excel,差点要了我半条命,满满的都是套路~~~


1、导包

          从网上下载poi 相关jar包

 下载之后将该类包导入项目的lib中即可。

2.编写代码

(1)下边是最终生成的效果图模板

   

java poi ExcelWriter 样式怎么单独设置 java poi生成excel_数据

(2)main方法的内容

    

java poi ExcelWriter 样式怎么单独设置 java poi生成excel_合并单元格_02

 欧了,开始进入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);
			}
		}
	}



     

    (4)再附上对象集合转字符串数组集合的代码,方便大家转换

//将对象集合转换为字符数组集合(以下五个方法都是起到对象转换成字符数组的作用)
	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我个人感觉还是比较麻烦的。很多坑。。