JXL导出Excel通用模板

近日用注解写了一个通用的使用JXL导出成Excel的模板类,在这里记上一笔,以后方便查找使用。
第一,创建一个注解类
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Excel实体BEAN的属性注解
 * @author MrGao
 * 2010-7-12下午05:10:37
 */
@Documented  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.FIELD)
public @interface ExcelAnnotation {
 
 String name();//Excel列名
 int width();//Excel列宽
 int id();//Excel列ID
 
}

第二,实现一个比较器,用于自定义字段导出到Excel的列顺序

import java.lang.reflect.Field;
import java.util.Comparator;


@SuppressWarnings("unchecked")
public class FieldComparator implements Comparator {

    public int compare(Object arg0, Object arg1) {
        Field fieldOne = (Field)arg0;
        Field fieldTwo = (Field)arg1;
        ExcelAnnotation annoOne = fieldOne.getAnnotation(ExcelAnnotation.class);
        ExcelAnnotation annoTwo = fieldTwo.getAnnotation(ExcelAnnotation.class);
        if(annoOne==null||annoTwo==null){
            return 0;
        }
        return annoOne.id()-annoTwo.id();
    }

}

第三,实现导出功能
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.Pattern;
import jxl.format.UnderlineStyle;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

/**
 * 导出Excel文件
 *
 * @author MrGao 2010-7-13下午02:19:51
 */
public class ExcelExport {

    /**
     * 生成Excel
     *
     * @param models
     *            封装需要到处的数据BEAN结合
     * @param className
     *            导成Excel的实体BEAN包名.类名
     * @param tempPath
     *            生成Excel存放的临时路径
     * @param excelName
     *            生成的Excel名
     */
    @SuppressWarnings("unchecked")
    public static void createExcel(List models, String className,
            String tempPath, String excelName) {
        Class clasVo = null;

        try {
            clasVo = Class.forName(className);
            OutputStream os = new FileOutputStream(tempPath + "\\" + excelName
                    + ".xls");
            WritableWorkbook workbook = Workbook.createWorkbook(os);
            workbook.setColourRGB(Colour.BLUE2, 79, 129, 189);
            WritableSheet sheet = workbook.createSheet(excelName, 0);
            // jxl 最大只支持65535行 算总共需要创建多少个Sheet
            int sheetCount = models.size() % 65535;
            for (int i = 0; i < sheetCount; i++) {

            }
            // 设置行高度
            sheet.setRowView(0, 400);
            sheet.setRowView(2, 350);
            // 用于标题
            WritableFont titleFont = new WritableFont(WritableFont
                    .createFont("华文行楷"), 18, WritableFont.BOLD, false,
                    UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.TEAL);
            WritableCellFormat wcf_title = new WritableCellFormat(titleFont);
            wcf_title.setBackground(Colour.WHITE, Pattern.SOLID);
            wcf_title.setBorder(Border.RIGHT, BorderLineStyle.THIN,
                    Colour.GRAY_25);
            wcf_title.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐
            wcf_title.setAlignment(Alignment.CENTRE);

            // 用于列头
            WritableFont headFont = new WritableFont(WritableFont
                    .createFont("宋体"), 11, WritableFont.BOLD, false,
                    UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.WHITE);
            WritableCellFormat wcf_head = new WritableCellFormat(headFont);
            wcf_head.setBackground(Colour.LIGHT_BLUE, Pattern.PATTERN12);
            wcf_head.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLUE2);
            wcf_head.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐
            wcf_head.setAlignment(Alignment.CENTRE);

            // 用于正文
            WritableFont NormalFont = new WritableFont(WritableFont
                    .createFont("宋体"), 11);
            WritableCellFormat wcf_center = new WritableCellFormat(NormalFont);
            wcf_center
                    .setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLUE2);
            wcf_center.setVerticalAlignment(VerticalAlignment.CENTRE); // 垂直对齐
            wcf_center.setAlignment(Alignment.CENTRE);
            wcf_center.setWrap(true); // 是否换行

            // 获取类中所有定义的字段
            Field[] fields = clasVo.getDeclaredFields();
            // 定义集合封装注解字段
            ArrayList<Field> annoFields = new ArrayList<Field>();
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                if (field.isAnnotationPresent(ExcelAnnotation.class)) {
                    annoFields.add(field);
                }
            }
            // 将集合转换为数组,以便后面排序
            Field[] annoArray = {};
            annoArray = annoFields.toArray(annoArray);

            sheet.addCell(new Label(0, 0, excelName, wcf_title));
            sheet.mergeCells(0, 0, annoArray.length == 0 ? 1
                    : annoArray.length - 1, 1);

            // 按照注解id排序Excel列
            Arrays.sort(annoArray, new FieldComparator());
            // 写入Excel列头
            for (int i = 0; i < annoArray.length; i++) {
                Field field = annoArray[i];
                // 获取该字段的注解对象
                ExcelAnnotation anno = field
                        .getAnnotation(ExcelAnnotation.class);
                sheet.setColumnView(i, anno.width());
                sheet.addCell(new Label(i, 2, anno.name(), wcf_head));
            }

            int rowId = 3;// 写入第几行 第一行为列头 数据从第二行开始写
            for (Object ssTopModel : models) {
                // 获取该类 并获取自身方法
                Class clazz = ssTopModel.getClass();
                for (int i = 0; i < annoFields.size(); i++) {
                    Field field = annoFields.get(i);
                    String methodName = "get"
                            + field.getName().substring(0, 1).toUpperCase()
                            + field.getName().substring(1);
                    Method method = clazz.getMethod(methodName);
                    try {
                        sheet.addCell(new Label(i, rowId, method
                                .invoke(ssTopModel) == null ? "" : method
                                .invoke(ssTopModel).toString(), wcf_center));
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
                rowId++;
            }

            workbook.write();
            workbook.close();
            os.flush();
            os.close();
        } catch (WriteException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

第四,在需要导出成Excel的实体Bean字段上加注解,也许该类有许多字段,但只需要在需要导出的列上加上注解即可,如
@ExcelAnnotation(name="用户名",width=20,id=1)
    private String userName;

第五,jxl最多一个sheet只能导出65535行,暂时未对行进行判断处理,数据太大导出会包异常,以后可以修改为对65535求余,余数即为需要创建的sheet数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值