论坛首页 Java企业应用论坛

用POI 写了个导出EXCEL 应该算通用吧

浏览 5574 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-08-18   最后修改:2012-08-18
//创建一个工作薄
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.workbook;

import org.apache.poi.ss.usermodel.Workbook;

import com.excel.type.WorkBookType;


public interface  WorkBookHandler {
	 
	public Workbook  createWorkBook(WorkBookType type);
}




// 因为里面类型可以能比较多,所以都是用接口,这样修改代码比较方法
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.workbook;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.excel.type.WorkBookType;

public class WorkBookHandlerImpl implements WorkBookHandler {

	@Override
	public Workbook  createWorkBook(WorkBookType type) {
		if(type==WorkBookType.XLS){
			return new HSSFWorkbook();
		}else if(type==WorkBookType.XLSX){
			return new XSSFWorkbook();
		}else{
			return null;
		}
	}

}


//在在工作薄里面创建一个sheet面板

/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.workbook;

import java.util.List;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

public interface SheetService {
	 List<Sheet> createSheet(Workbook wb,String... sheetNames);
}



//实现
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.workbook;

import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

public class SheetServiceImpl implements SheetService {

	@Override
	public List<Sheet> createSheet(Workbook wb, String... sheetNames) {
		String defaultName = "sheet_1";
		List<Sheet> list = new ArrayList<Sheet>();
		if(wb==null){
			return null;
		}
		if(sheetNames==null || sheetNames.length==0){
			Sheet sheet = wb.createSheet(defaultName);
			list.add(sheet);
		}
		
		for (int i = 0; i < sheetNames.length; i++) {
			Sheet sheet = wb.createSheet(defaultName);
			list.add(sheet);
		}
		return list;
	}
	
}




//创建列
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.workbook;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public interface CellService {
	 void createCells(Workbook workbook,CellData datas,Sheet sheet,HSSFCellStyle style);
}


//同样是实现
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.workbook;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import com.excel.util.Util;

public  class CellServiceImpl implements CellService {


	/**
	 *没有样式的列
	 *@param datas 数据源
	 *@param sheet excel里面的Sheet面板对象
	 */
	@Override
	public void createCells(Workbook wb,CellData dataSource,Sheet sheet,HSSFCellStyle style) {
		if(sheet==null || dataSource==null){
			return ;
		}
		//设置标题
		Row row = sheet.createRow(0);
		List<String> titles = dataSource.getTitlesList();
        
		for(int m=0;m<titles.size();m++){
			Cell cell = row.createCell(m);
			cell.setCellValue(titles.get(m));
			cell.setCellStyle(style);
		}
		Map<String,List<String>> map = dataSource.getMap();
		if(map==null || map.size()<1){
			return ;
		}
		Iterator<Entry<String,List<String>>> it = (Iterator<Entry<String,List<String>>>) map.entrySet().iterator();
		int i = 1;
		while(it.hasNext()){
			
			Entry<String,List<String>> entry = it.next();
			//第二行开始设置值
			Row rows = sheet.createRow(i);
			List<String> list = entry.getValue();
			for (int j = 0; j <list.size(); j++) {
				Cell cell = rows.createCell(j);
				String value = Util.isBigNumber(list.get(j))!=true?list.get(j):list.get(j)+"`";
				cell.setCellValue(value);
			}
			i++;
		}
	    
	}
}



//列的数据源

/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.workbook;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

public class CellData implements Serializable{

	private static final long serialVersionUID = 1L;
	/**列的名称**/
	private List<String> titlesList;
	/**根据列名称对应值**/
	private Map<String,List<String>> map;
	
	public List<String> getTitlesList() {
		return titlesList;
	}
	public void setTitlesList(List<String> titlesList) {
		this.titlesList = titlesList;
	}
	public Map<String, List<String>> getMap() {
		return map;
	}
	public void setMap(Map<String, List<String>> map) {
		this.map = map;
	}
}


//客户端调用
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.client;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import com.excel.type.WorkBookType;
import com.excel.workbook.CellData;
import com.excel.workbook.CellService;
import com.excel.workbook.CellServiceImpl;
import com.excel.workbook.GlobalStyle;
import com.excel.workbook.SheetService;
import com.excel.workbook.SheetServiceImpl;
import com.excel.workbook.WorkBookHandler;
import com.excel.workbook.WorkBookHandlerImpl;

public class ExcelClient {
	
	public void createExcel(String fileName, CellData cellDatas,WorkBookType workType){
		
		if(fileName==null || fileName.equals("")){
			return ;
		}
		if(workType==null){
			workType = WorkBookType.XLS;
		}
		
		WorkBookHandler workBook = new WorkBookHandlerImpl();
		Workbook workbook = workBook.createWorkBook(workType);
		
		SheetService sheetService = new SheetServiceImpl();	
		List<Sheet> sheets = sheetService.createSheet(workbook);
		
		CellService cellService = new CellServiceImpl();
		for (Sheet sheet2 : sheets) {
			cellService.createCells(workbook,cellDatas, sheet2,GlobalStyle.titleStyle(workbook));
		}
		FileOutputStream fileOut = null;
		BufferedOutputStream bo = null;
		try{
			fileOut = new FileOutputStream(new File(fileName));
			bo = new BufferedOutputStream(fileOut);
			workbook.write(bo);
		}catch(IOException ex){
			ex.printStackTrace();
		}finally{
			try{
				if(bo!=null){
					bo.close();
				}
				if(fileOut!=null){
					fileOut.close();
				}
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		new ExcelClient().createExcel("d:\\excel_test.xls",getCellData(),null);
	}
	
	public static CellData getCellData(){
		CellData cellDatas = new CellData();
		List<String> titles = new ArrayList<String>();
		titles.add("标题测试1");
		titles.add("标题测试2");
		titles.add("标题测试3");
		titles.add("标题测试4");
		
		Map<String,List<String>> map = new HashMap<String,List<String>>();
		List<String> vals = new ArrayList<String>();
		vals.add("123142354365423");
		vals.add("值测试2");
		vals.add("值测试3");
		vals.add("值测试4");
		
		for (int i = 0; i <10000; i++) {
			map.put(String.valueOf(i), vals);
		}
		
		cellDatas.setTitlesList(titles);
		cellDatas.setMap(map);
		
		return cellDatas;
	}
}



//样式,这里用了
引用
wdmcln
同学的代码,稍微修改了,title的样式,其它的没用 呵呵
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.workbook;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Workbook;

public class GlobalStyle {
		/**
		 * 超链接样式
		 * @return HSSFCellStyle
		 */
		public static CellStyle linkStyle(Workbook work) {
			HSSFCellStyle linkStyle = (HSSFCellStyle) work.createCellStyle();
			linkStyle.setBorderBottom((short)1);
			linkStyle.setBorderLeft((short)1);
			linkStyle.setBorderRight((short)1);
			linkStyle.setBorderTop((short)1);
			linkStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
			linkStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
			Font font = work.createFont();
			font.setFontName(HSSFFont.FONT_ARIAL);
			font.setUnderline((byte)1);
			font.setColor(HSSFColor.BLUE.index);
			linkStyle.setFont(font);
			return linkStyle;
		}
		
		/**s
		 * 单元格样式
		 * @return Workbook
		 */
		public static CellStyle nameStyle(Workbook work) {
			HSSFCellStyle nameStyle = (HSSFCellStyle) work.createCellStyle();
			nameStyle.setBorderBottom((short)1);
			nameStyle.setBorderLeft((short)1);
			nameStyle.setBorderRight((short)1);
			nameStyle.setBorderTop((short)1);
			nameStyle.setFillForegroundColor(HSSFColor.LIGHT_CORNFLOWER_BLUE.index);
			nameStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
			return nameStyle;
		}
		
		/**
		 * 时间样式
		 * @return HSSFCellStyle
		 */
		public static CellStyle dataStyle(Workbook work) {
			HSSFCellStyle dataStyle = (HSSFCellStyle) work.createCellStyle();
			dataStyle.setBorderBottom((short)1);
			dataStyle.setBorderLeft((short)1);
			dataStyle.setBorderRight((short)1);
			dataStyle.setBorderTop((short)1);
			dataStyle.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);
			dataStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
			dataStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			return dataStyle;
		}
		
		/**
		 * 标题样式
		 * @return HSSFCellStyle
		 */
		public static HSSFCellStyle titleStyle(Workbook work) {
			
	        HSSFCellStyle style = (HSSFCellStyle) work.createCellStyle();  
	        style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
	        style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
	        style.setBorderLeft((short)1);
	        style.setBorderRight((short)1);
//	        style.setAlignment(CellStyle.ALIGN_CENTER);
	        
//	        HSSFFont font = (HSSFFont) work.createFont();
			return style;
		}

}




//漏两个UTIL 补上来
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Util {
	public static boolean isNumber(String nums){
		Pattern p = Pattern.compile("[0-9]*");
		Matcher m = p.matcher(nums);
		return m.matches();
	}
	
	public static boolean isBigNumber(String nums){
		if(nums==null || nums.equals("") || nums.length()<7){
			return false;
		}
		return isNumber(nums);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(isNumber("12.123"));
	}

}



//漏了个workBookTYpe
/**
 * author:ztiny
 * data  :2012-8-18
 */
package com.excel.type;

public enum WorkBookType {
	/**xls格式的excel**/
	XLS,
	/**xlsx格式的excel**/
	XLSX
}

PS:这里说明下,只能说一般情况下通用,没考虑合并列之类的复杂情况,而且样式也值设置了标题,只能手动改代码区切换,而且没有考虑什么时候切换sheet ,别且写入数据,代码里面写的都只是按逻辑来实现的,如果多sheet的情况下,可能需要稍微的修改下代码,不过代码比较好修改,  ,这个放心,自己去扩展,或者测试下,其它情况没有想到,暂时只考虑到了这么多,欢饮拍砖,但是别投隐藏 
   发表时间:2012-08-20  
楼主的类注释有个小bug ,日期应该是date! 
0 请登录后投票
   发表时间:2012-08-20  
不通用,具有依赖性,应该将Excel文档当作一个对象来设计,也就是说得把Excel抽象成为一个对象或对象集合来处理,提供出来的也应该为接口定义,不应该包含第三方的API到接口中。

比如,一个Excel文档是一个对象,那么一个Excel有N个Sheet,第个Sheet有N个Row,N个Cell,而每个单元格有各自的style(包含样式,跨行等)....

那么定义的接口就可以是这样:
public byte[] buildExcel(List<SheetObj> sheets);

涉及到第三方API的是你实现的问题,对调用方来说不关心。
0 请登录后投票
   发表时间:2012-08-21  
hngmduyi 写道
楼主的类注释有个小bug ,日期应该是date! 

呵呵 这个确实没注意
0 请登录后投票
   发表时间:2012-08-21   最后修改:2012-08-21
ssy8110 写道
不通用,具有依赖性,应该将Excel文档当作一个对象来设计,也就是说得把Excel抽象成为一个对象或对象集合来处理,提供出来的也应该为接口定义,不应该包含第三方的API到接口中。

比如,一个Excel文档是一个对象,那么一个Excel有N个Sheet,第个Sheet有N个Row,N个Cell,而每个单元格有各自的style(包含样式,跨行等)....

那么定义的接口就可以是这样:
public byte[] buildExcel(List<SheetObj> sheets);

涉及到第三方API的是你实现的问题,对调用方来说不关心。


呵呵 ,正如我所说,封装的确实不够,你说的那样确实是比较好,继承POI的更好,可以脱离第三方API

在这里我的想法是,因为无论如何都要用poi ,不如对开发人员透明 直接用上它的,而且我这里只是封装下POI的使用,一般情况下足够了,如果把EXCEL 按照对象的方式来设计的话,那感觉用起来就比较麻烦,虽然封装的够好,但是对开发人员来说反而不如不用,主要是传递数据太复杂了,呵呵,这是我当时写的想法,当然有不足,欢迎讨论
0 请登录后投票
   发表时间:2012-11-19  
ztiny 写道
hngmduyi 写道
楼主的类注释有个小bug ,日期应该是date! 

呵呵 这个确实没注意


^_^,LZ的貌似类注释写法错误,author前面应该有个@符号,date应该有一个@符号吧
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics