根据Bean对象自动生成Excel并下载

效果展示

  • 调用 (生成一个20行的Excel表格)
// 创建对象列表
List<ShipmentOrder> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
    ShipmentOrder shipmentOrder = new ShipmentOrder();
    shipmentOrder.setDriver("driver_name_" + i);
    shipmentOrder.setPlate("plate_12356");
    shipmentOrder.setMobile("mobile_13312341234");
    shipmentOrder.setStatus(200+i);
    list.add(shipmentOrder);
}
Map model = new HashMap();
model.put("list", list);
// 生成Excel表格--订单追踪s.xls
return new ModelAndView(new dreamtec.vm.starter.core.base.ExcelExporter("订单追踪s.xls"), model);
  • 生成的Excel效果图
    image

实现思路

要实现根据javabean对象直接生成Excel并下载,主要是给定义bean对象将会用的注解来标记Excel中用到的属性,然后获取到该注解来确定该对象的值在表格中如果使用(赋值到哪里),至于下载由框架处理即可,我们主要处理bean解析到Excel的过程。

总结:
先定义一个做注解使用的Excel对象,并定义两个属性来标记所在的列和列名
再根据反射获取到对象的属性,然后根据属性Excel相关的注解来将属性的值填到表格中对应的列(不用关心所在的行,因为每个对象占一行,第几个对象就将解析到第几行)

实现步骤

  • 定义Excel注解

Excel.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Excel {
    String title() default  "" ;	// 对象所在列的列名
    int seq()  default  0 ;		// 对象所在的列
}
  • bean对象使用@Excel注解标记

ShipmentOrder.java

import dreamtec.vm.starter.core.base.Excel;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Table(name = "shipment_order")
public class ShipmentOrder extends BaseDTO {

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    private static final long serialVersionUID = 8745606121123749230L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @ApiModelProperty(value = "数据库ID", example = "")
    private Long id;

    private String warehouse; // 一般对象, 不会生成到Excel中

	// 使用Excel注解的属性, 属性的值将赋给名为'司机'的列, 该列是第一列,
    @Excel( title = "司机",seq = 0)	
    private String driver;

    @Excel( title = "车牌",seq = 1)
    private String plate;

    @Excel( title = "手机号",seq = 2)
    private String mobile;

    @Excel( title = "状态",seq = 3)
    private int status;

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }
	
	...setter getter不再赘述
}
  • 解析注解并在Excel中赋值

ExcelExporter.java

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.servlet.view.document.AbstractXlsView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

/*
 *  该对象为具体生成Excel的对象, Cotroller中使用以下代码即可:
    @RequestMapping("exportDetails")
    public ModelAndView downloadExcel() {
        List<ShipmentOrder> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            ShipmentOrder shipmentOrder = new ShipmentOrder();
            shipmentOrder.setDriver("driver_name_" + i);
            shipmentOrder.setPlate("plate_12356");
            shipmentOrder.setMobile("mobile_13312341234");
            shipmentOrder.setStatus(200+i);
            list.add(shipmentOrder);
        }
        Map model = new HashMap();
        model.put("list", list);
        return new ModelAndView(new dreamtec.vm.starter.core.base.ExcelExporter("订单追踪s.xls"), model);
    }
    * */
public class ExcelExporter extends AbstractXlsView {

    String excelName;	// 文件名
    String sheetTitle;	// 表名

    public ExcelExporter(String excelName) {
        this(excelName, excelName);
    }

    public ExcelExporter(String excelName, String sheetTitle) {
        this.excelName = excelName;
        this.sheetTitle = sheetTitle;
    }

    @Override
    protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, 
    	HttpServletRequest httpServletRequest, 
    	HttpServletResponse httpServletResponse) throws Exception {

        // 设置response方式,使执行导出时自动出现下载页面,而非直接使用excel打开
        httpServletResponse.setContentType("APPLICATION/OCTET-STREAM");
        httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" 
        	+ URLEncoder.encode(excelName, "UTF-8"));

        // 产生Excel表头
        HSSFSheet sheet = (HSSFSheet) workbook.createSheet(sheetTitle);
        //设置单元格宽度
        for (int i = 0; i <= 20; i++) {
            sheet.setColumnWidth(i, 5000);
        }
        HSSFCellStyle cellStyle = (HSSFCellStyle) workbook.createCellStyle();
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 设置单元格样式为字体居中
        HSSFFont font = (HSSFFont) workbook.createFont();
        font.setFontName("仿宋_GB2312");
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显示;
        font.setFontHeightInPoints((short) 16);//设置字体大小
        cellStyle.setFont(font);

        HSSFRow header = sheet.createRow(0); // 第0行
        header.setHeight((short) 400);//设置首行行高

		// 得到对象列表
        List<?> list = (List<?>) model.get("list");
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Object obj = list.get(i);	// 得到具体的对象
                // 遍历该对象的属性
                Field[] fields = obj.getClass().getDeclaredFields();
                for (Field field : fields) {
                    // 查看该属性的注解
                    for (Annotation annotation : field.getAnnotations()) {
                        // 存在Excel注释, 则需要将该对象导入Excel
                        if (annotation instanceof Excel) {  
                            Excel excel = (Excel) annotation;
                            int columnIdx = excel.seq();
                            if (i == 0) {   // 第一次找到, 需要先设置列名
                                String columnTitle = excel.title();
                                header.createCell(columnIdx).setCellValue(columnTitle);
                                header.getCell(columnIdx).setCellStyle(cellStyle);
                            }
                            // 赋值到该行(i+1)
                            HSSFRow row = sheet.getRow(i + 1);
                            if (row == null) {
                                row = sheet.createRow(i + 1);
                                row.setHeight((short) 300);
                            }
                            row.createCell(columnIdx).setCellValue(
                            	getFieldValueByFieldName(field.getName(), obj).toString());
                        }
                    }
                }
            }
        }
    }

    /**
     * 根据属性名获取属性值
     *
     * @param fieldName
     * @param object
     * @return
     */
    private Object getFieldValueByFieldName(String fieldName, Object object) {
        try {
            Field field = object.getClass().getDeclaredField(fieldName);
            //设置对象的访问权限,保证对private的属性的访问
            field.setAccessible(true);
            return field.get(object);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值