使用JXL导出和解析EXCEL文件

   前些日子在做一个项目时,经常需要将一些数据导出到EXCEL文件中,而且操作很类似--一个标题,然后是子标题接着是一个列表。于是对其进行抽象,写了另一个类,完成了关键的处理。
package cn.com.tweb.common.excel;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import cn.com.tweb.common.Constant;
import cn.com.tweb.common.StringUtil;
/**
 *  生成EXCEL文件
 * 
 * @author ZHANGWEIGUO
 * @version Revision: 1.0  Date: 2008-10-24  
 * @see 
 * @see
 */
public class ExportExcel {

	/**
	 * 生成EXCEL文件到本地目录,最简的参数列表
	 * 
	 * @param data
	 * @param path
	 * @return
	 */
	public static int exportExcelToFileSystem(List<String[]> data, String path) {
		int result = 1;
        
		int colsNum=0;
		// 先判断是否传入原始数据
		if (data == null || data.size() == 0) {
			result = Constant.EXPORT_EXCEL_NO_DATA;			
		} else {						
			// 根据传入的文件名路径,先生成一个文件
			File exportFile = null;
			try {
				exportFile = new File(path + "/" + "test.xls");
				if (exportFile == null) {
					result = Constant.EXPORT_EXCEL_NOFILE_EXCEPTION;
				}
			} catch (Exception ex) {
				result = Constant.EXPORT_EXCEL_NOFILE_EXCEPTION;
				ex.printStackTrace();
			}

			// 如果能生成文件,就进行生成EXCEL文件的操作
			if (exportFile != null) {
				// 生成EXCEL文件
				WritableWorkbook wwb = null;
				try {
					wwb = Workbook.createWorkbook(exportFile);
					Label lable = new Label(0, 0, "学生信息列表", ExcelProperties.getHeader());				
					// 创建EXCEL工作表
					WritableSheet ws = wwb.createSheet("默认", 0);
					ws.addCell(lable);
					// 取得LIST中的数组大小
					colsNum=data.get(0).length;
					// 参数的含义为:左列,左行,右列,右行 合并成一个单元格
					ws.mergeCells(0, 0, colsNum-1, 0);
					int flag = 0;
					for (String temp[] : data) {
						if (colsNum == temp.length) {
							for (int i = 0; i < temp.length; i++) {
								lable = new Label(i, flag + 1, temp[i],
										ExcelProperties.getNormolCell());
								ws.addCell(lable);

								System.out.println("flag" + flag + " --  "
										+ temp[i]);
							}
							flag++;
						}else{
							result=Constant.EXPORT_EXCEL_ARRAYNOTHESAME_EXCEPTION;
						}
					}
					// 列宽的处理还需要动态的来设置,属性数据从参数总获取
					ws.setColumnView(0, 40);
					ws.setColumnView(1, 35);
					ws.setColumnView(2, 20);
					ws.setColumnView(3, 80);
					ws.setColumnView(4, 30);
					
					// 写EXCEL
					wwb.write();
					// 关闭资源
					wwb.close();
				} catch (IOException e) {
					result = Constant.EXPORT_EXCEL_NOFILE_EXCEPTION;
					e.printStackTrace();
				} catch (RowsExceededException e) {
					result = Constant.EXPORT_EXCEL_SYSTEM_EXCEPTION;
					e.printStackTrace();
				} catch (WriteException e) {
					result = Constant.EXPORT_EXCEL_SYSTEM_EXCEPTION;
					e.printStackTrace();
				}
			}
		}
		return result;
	}
	
	/**
	 * 生成EXCEL文件到本地目录,带比较全面的参数列表
	 * 
	 * @param title 标题
	 * @param hasInnerTitle 子标题,如果传入NULL,就不生成子标题。
	 * @param colsSize 每列的宽度,如果传入的列数和LIST中的数组长度不一致,将会按默认的宽度处理
	 * @param data EXCEL列表数据源
	 * @param path 文件存放路径
	 * @return
	 */
	public static int exportExcelToFileSystem(String title,
			String innerTitle, int[] colsSize, List<String[]> data,
			String path) {
		int result = 1;
        
		int colsNum=0;
		// 先判断是否传入原始数据
		if (data == null || data.size() == 0) {
			result = Constant.EXPORT_EXCEL_NO_DATA;			
		} else {						
			// 根据传入的文件名路径,先生成一个文件
			File exportFile = null;
			try {
				exportFile = new File(path + "/" + "document.xls");
				if (exportFile == null) {
					result = Constant.EXPORT_EXCEL_NOFILE_EXCEPTION;
				}
			} catch (Exception ex) {
				result = Constant.EXPORT_EXCEL_NOFILE_EXCEPTION;
				ex.printStackTrace();
			}

			// 如果能生成文件,就进行生成EXCEL文件的操作
			if (exportFile != null) {
				// 生成EXCEL文件
				WritableWorkbook wwb = null;
				try {
					wwb = Workbook.createWorkbook(exportFile);
					Label lable = new Label(0, 0, "学生信息列表", ExcelProperties.getHeader());				
					// 创建EXCEL工作表
					WritableSheet ws = wwb.createSheet("默认", 0);
					ws.addCell(lable);
					// 取得LIST中的数组大小
					colsNum=data.get(0).length;
					// 参数的含义为:左列,左行,右列,右行 合并成一个单元格
					ws.mergeCells(0, 0, colsNum-1, 0);
					// 处理内标题
					if(!StringUtil.isNullOrEmpty(innerTitle)){
						lable = new Label(0, 1, innerTitle, ExcelProperties.getHeaderInner());
						ws.addCell(lable);
						ws.mergeCells(0, 1, colsNum-1, 1);
					}
										
					int flag = 0;
					for (String temp[] : data) {
						if (colsNum == temp.length) {
							for (int i = 0; i < temp.length; i++) {
								lable = new Label(i, flag + ExcelProperties.dataRowBeginSize(!StringUtil.isNullOrEmpty(innerTitle)), temp[i],
										ExcelProperties.getNormolCell());
								ws.addCell(lable);
							}
							flag++;
						}else{
							result=Constant.EXPORT_EXCEL_ARRAYNOTHESAME_EXCEPTION;
						}
					}
					
					// 
					if (result != Constant.EXPORT_EXCEL_ARRAYNOTHESAME_EXCEPTION) {
						// 设置列宽
						if (colsSize.length == colsNum) {
							for (int i = 0; i < colsSize.length; i++) {
								ws.setColumnView(i, colsSize[i]);
							}
						} else {
							// 设置默认的宽度
							for (int i = 0; i < colsNum; i++) {
								ws.setColumnView(i, 20);
							}
							result = Constant.EXPORT_EXCEL_ARRAYNOTHESAME_EXCEPTION;
						}
					}				
					// 写EXCEL
					wwb.write();
					// 关闭资源
					wwb.close();
				} catch (IOException e) {
					result = Constant.EXPORT_EXCEL_NOFILE_EXCEPTION;
					e.printStackTrace();
				} catch (RowsExceededException e) {
					result = Constant.EXPORT_EXCEL_SYSTEM_EXCEPTION;
					e.printStackTrace();
				} catch (WriteException e) {
					result = Constant.EXPORT_EXCEL_SYSTEM_EXCEPTION;
					e.printStackTrace();
				}
			}
		}
		return result;
	}
	
	/**
	 * 生成EXCEL通过浏览器导出到客户端,带比较全面的参数列表,在WEB项目中使用
	 * 
	 * @param title 标题
	 * @param hasInnerTitle 子标题,如果传入NULL,就不生成子标题。
	 * @param colsSize 每列的宽度,如果传入的列数和LIST中的数组长度不一致,将会按默认的宽度处理
	 * @param data EXCEL列表数据源
	 * @param path 文件存放路径
	 * @return
	 */
	public static int exportExcelInWeb(String title,
			String innerTitle, int[] colsSize, List<String[]> data,
			OutputStream os) {
		int result = 1;
        
		int colsNum=0;
		// 先判断是否传入原始数据
		if (data == null || data.size() == 0) {
			result = Constant.EXPORT_EXCEL_NO_DATA;			
		} else {						
			// 判断传入的流			
			if (os != null) {
				// 生成EXCEL文件
				WritableWorkbook wwb = null;
				try {
					wwb = Workbook.createWorkbook(os);
					Label lable = new Label(0, 0, "学生信息列表", ExcelProperties.getHeader());				
					// 创建EXCEL工作表
					WritableSheet ws = wwb.createSheet("默认", 0);
					ws.addCell(lable);
					// 取得LIST中的数组大小
					colsNum=data.get(0).length;
					// 参数的含义为:左列,左行,右列,右行 合并成一个单元格
					ws.mergeCells(0, 0, colsNum-1, 0);
					// 处理内标题
					if(!StringUtil.isNullOrEmpty(innerTitle)){
						lable = new Label(0, 1, innerTitle, ExcelProperties.getHeaderInner());
						ws.addCell(lable);
						ws.mergeCells(0, 1, colsNum-1, 1);
					}
										
					int flag = 0;
					for (String temp[] : data) {
						if (colsNum == temp.length) {
							for (int i = 0; i < temp.length; i++) {
								lable = new Label(i, flag + ExcelProperties.dataRowBeginSize(!StringUtil.isNullOrEmpty(innerTitle)), temp[i],
										ExcelProperties.getNormolCell());
								ws.addCell(lable);
							}
							flag++;
						}else{
							result=Constant.EXPORT_EXCEL_ARRAYNOTHESAME_EXCEPTION;
						}
					}
					
					// 
					if (result != Constant.EXPORT_EXCEL_ARRAYNOTHESAME_EXCEPTION) {
						// 设置列宽
						if (colsSize.length == colsNum) {
							for (int i = 0; i < colsSize.length; i++) {
								ws.setColumnView(i, colsSize[i]);
							}
						} else {
							// 设置默认的宽度
							for (int i = 0; i < colsNum; i++) {
								ws.setColumnView(i, 20);
							}
							result = Constant.EXPORT_EXCEL_ARRAYNOTHESAME_EXCEPTION;
						}
					}				
					
					wwb.write();
					wwb.close();
					os.close();
				} catch (IOException e) {
					result = Constant.EXPORT_EXCEL_NOFILE_EXCEPTION;
					e.printStackTrace();
				} catch (RowsExceededException e) {
					result = Constant.EXPORT_EXCEL_SYSTEM_EXCEPTION;
					e.printStackTrace();
				} catch (WriteException e) {
					result = Constant.EXPORT_EXCEL_SYSTEM_EXCEPTION;
					e.printStackTrace();
				}
			}else{
				result = Constant.EXPORT_EXCEL_NULL_OUTPUTSTREAM_EXCEPTION;
			}
		}
		return result;
	}
}


使用模拟数据的ArrayList对象,在main()方法中进行测试可以生成下面的EXCE文件,代码如下:
package test;

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

public class DataMock {

	/**
	 * 模拟数据
	 * 
	 * @return
	 */
	public static List<String[]> getListData() {
		List<String[]> list = new ArrayList<String[]>();
		String[] temp=null;
		temp=new String[5];
		temp[0]="姓名";
		temp[1]="年龄";
		temp[2]="性别";
		temp[3]="身高";
		temp[4]="爱好";
		for (int i = 0; i < 50; i++) {
			temp=new String[5];
			temp[0]="学生"+i;
			temp[1]="12";
			temp[2]=i%2==0?"男":"女";
			temp[3]="1.60"+(i/10*3);
			temp[4]="篮球,乒乓球";
			list.add(temp);
		}
		return list;
	}

}


调用的代码:
int result=ExportExcel.exportExcelToFileSystem("学生信息管理","(TWEB集团附属小学)",new int[]{24,24,18,16,20},DataMock.getListData(), "d:\\");
		System.out.println("result:"+result);

运行以后就可以在D盘生成一个EXCEL。

在C/S项目中,通过输出流直接向客户端输出,JSP代码里或Web框架的Action里调用代码为:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@page import="java.io.OutputStream"%>
<%@page import="cn.com.tweb.common.excel.ExportExcel"%>
<%@page import="test.DataMock"%>
<%@page import="cn.com.tweb.common.StringUtil"%>
<%  

  // 设定输出文件头
  response.setCharacterEncoding("GBK");
  // 当文件名为中文时请用StringUtil类的toUtf8String()方法进行转码
  response.setHeader("Content-disposition",
			"attachment;  filename="+StringUtil.toUtf8String("学生信息管理列表.xls"));
  // 定义输出类型
  response.setContentType("application/vnd.ms-excel");               
  OutputStream os = response.getOutputStream();
      
  int result=ExportExcel.exportExcelInWeb("学生信息管理","(拓旗集团附属小学)",
            new int[]{24,24,18,16,20},DataMock.getListData(),os);
  System.out.println("-------------(result:"+result+")-------------");
%>


常量接口类的代码为:
package cn.com.tweb.common;
/**
 * 常量接口,以EXPORT_EXCEL_开头的变量,值大于0的都是导出EXCEL成功
 * 
 * @author ZHANGWEIGUO
 * @version Revision: 1001  Date: 2006-09-03 05:00:21 +0800 
 * @see 
 * @see
 */
public interface Constant {
	// 成功导出EXCEL文件
	public static final int EXPORT_EXCEL_SUCCESS=1;
	
	// 没有数据
	public static final int EXPORT_EXCEL_NO_DATA=-1;

	// 系统异常
	public static final int EXPORT_EXCEL_SYSTEM_EXCEPTION=-2;
	
	// 其他异常
	public static final int EXPORT_EXCEL_OTHER_EXCEPTION=-3;
	
	// 文件路径和文件名无效
	public static final int EXPORT_EXCEL_NOFILE_EXCEPTION=-4;
	
	// 集合对象中的数组存放的数据个数不一致
	public static final int EXPORT_EXCEL_ARRAYNOTHESAME_EXCEPTION=-5;
	
	// 传入的OUTPUTSTREAM为空
	public static final int EXPORT_EXCEL_NULL_OUTPUTSTREAM_EXCEPTION=-6;
	
	// 宽度设置参数有误,按默认值设定宽度
	public static final int EXPORT_EXCEL_COLSNUM_NOTRIGHT=2;
	
}

解析EXCEL文件的代码如下:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;

import org.apache.commons.fileupload.FileItem;

public class ParseExcel {
	
	/**
	 *  用COMMON UPLOAD进行EXCEL文件上传,得到fileItem对象,这里
	 * 进行解析,返回集合对象。该方法适合在JAVA工程中使用。
	 * 
	 * @param fileItem
	 * @param beginIndex 正式数据的起始行 例如EXCEL文件
	 *  有大标题和小标题和列标题,那么该参数应为 4
	 * @return
	 * @throws BiffException
	 * @throws IOException
	 */
	public static List<String[]> redExcel(FileItem fileItem,int beginIndex){
		// 保存结果集
		List<String[]> result=null;
		// 保存EXCEL每行的所有单元格中的数据
		String[] temp=null;
		try {
			if (fileItem != null) {
				Workbook workBook = Workbook.getWorkbook(fileItem
						.getInputStream());
				Sheet sheet = workBook.getSheet(0);
				Cell cell = null;
				int rowSize = sheet.getRows();
				int colSize = sheet.getColumns();

				result = new ArrayList<String[]>();
				for (int i = beginIndex - 1; i < rowSize; i++) {
					temp = new String[colSize];
					for (int t = 0; t < colSize; t++) {						
						// 保存EXCEL每行的所有单元格中的数据,在内循环外面进行定义
						cell = sheet.getCell(t, i);
						String content = "";
						if (cell.getContents() != null) {
							// 去空格,特殊字符和回车键盘
							content = cell.getContents().replace("%", "")
									.replace("|", "").replace(" ", "")
									.replaceAll("\\n", "")
									.replaceAll("\\r", "").trim();

						}
						temp[t] = content;
					}
					// 将每列的的数据存入结果集中
					result.add(temp);
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}
	
	/**
	 *  用COMMON UPLOAD进行EXCEL文件上传,得到fileItem对象,这里
	 * 进行解析,返回集合对象。该方法适合在WEB项目中使用。
	 * 
	 * @param fileItem
	 * @param beginIndex 正式数据的起始行 例如EXCEL文件
	 *  有大标题和小标题和列标题,那么该参数应为 4
	 * @return
	 * @throws BiffException
	 * @throws IOException
	 */
	public static List<String[]> redExcel(File file,int beginIndex){
		// 保存结果集
		List<String[]> result=null;
		// 保存EXCEL每行的所有单元格中的数据
		String[] temp=null;
		try {
			Workbook workBook = Workbook.getWorkbook(file);
			Sheet sheet = workBook.getSheet(0);
			Cell cell = null;
			int rowSize = sheet.getRows();
			int colSize = sheet.getColumns();
			
			result=new ArrayList<String[]>();
			for (int i = beginIndex-1; i < rowSize; i++) {
				// 保存EXCEL每行的所有单元格中的数据
				temp=new String[colSize];
				for (int t = 0; t < colSize; t++) {				    
					cell = sheet.getCell(t, i);
					String content="";
					if (cell.getContents()!=null) {
						// 去空格,特殊字符和回车键盘
						content = cell.getContents().replace("%", "")
								.replace("|", "")
								.replace(" ", "")
								.replaceAll("\\n", "")
								.replaceAll("\\r", "").trim();
						
					}
					temp[t]=content;					
				}
				// 将每列的的数据存入结果集中
				result.add(temp);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}	
}

你可能感兴趣的:(Web,单元测试,Excel,OS,项目管理)