Apache POI 4.0.1版本 Excel导出数据案例(兼容 xls 和 xlsx)

Posted 娜一抹微笑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Apache POI 4.0.1版本 Excel导出数据案例(兼容 xls 和 xlsx)相关的知识,希望对你有一定的参考价值。

实体类

package com.springbootemaildemo.excel.a;

import javax.persistence.Column;

import io.swagger.annotations.ApiModelProperty;

public class DataBean {

    @ApiModelProperty(value = "设备编码")
    @Column(name = "equip_code")
    private String equipCode;

    @ApiModelProperty(value = "设备英文名称")
    @Column(name = "equip_en")
    private String equipEn;

    @ApiModelProperty(value = "设备中文名称")
    @Column(name = "equip_cn")
    private String equipCn;
public String getEquipCode() {
        return equipCode;
    }

    public void setEquipCode(String equipCode) {
        this.equipCode = equipCode;
    }

    public String getEquipEn() {
        return equipEn;
    }

    public void setEquipEn(String equipEn) {
        this.equipEn = equipEn;
    }

    public String getEquipCn() {
        return equipCn;
    }

    public void setEquipCn(String equipCn) {
        this.equipCn = equipCn;
    }
}

控制层

package com.springbootemaildemo.excel.a;

import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@Slf4j
@RestController
@RequestMapping("/excel")
public class ExcelController {
    private static final Logger log = LoggerFactory.getLogger(ExcelController.class);

    @Autowired
    ExcelService excelServiceImpl;

    @ApiOperation(value = "导出数据", notes = "导出数据到excel文件", httpMethod = "POST")
    @PostMapping("/exportData")
    public void exportEquipmentsAlarmInfo(HttpServletResponse response) {
        log.info("到处数据开始---------------");
        excelServiceImpl.exportInfo(response);
        log.info("到处数据结束---------------");
    }
}

业务层

package com.springbootemaildemo.excel.a;

import com.springbootemaildemo.util.ApplicationException;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

@Service
public class ExcelService {
    private static final Logger log = LoggerFactory.getLogger(ExcelService.class);

    @Autowired
    EhcacheInstance ehcacheInstance;


    /**
     * 导出方法
     *
     * @param response
     */
    public void exportInfo(HttpServletResponse response) {
        // 数据为空时可以导出标题行
        List<DataBean> result = getData();
        // 设置标题行
        Map<String, String> map = ehcacheInstance.getBeanPropertyDesCollection(DataBean.class);
        map.remove("创建人");
        map.remove("创建时间");
        map.remove("修改人");
        map.remove("修改时间");
        Set<Map.Entry<String, String>> titileSet = map.entrySet();
        String[] titlesCN = new String[map.size()];
        String[] titlesEN = new String[map.size()];
        int i = 0;
        for (
                Map.Entry<String, String> entry : titileSet) {
            titlesCN[i] = entry.getKey();
            titlesEN[i] = entry.getValue();
            i++;
        }
        Workbook workbook = ExcelUtils.exportDataToWorkBook(result, titlesEN, titlesCN);
        // 将文件流输出到response 提供下载
        if (workbook != null) {
            try {
                String fileName = UUID.randomUUID().toString().replace("-", "").concat(".xlsx");
                // 设置响应内容为文件流
                response.setContentType("application/octet-stream;charset=utf-8");
                // 强制下载
                response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                response.addHeader("Cache-Control", "no-cache");
                OutputStream out = response.getOutputStream();
                workbook.write(out);
            } catch (Exception e) {
                log.error("workbook write stream to response fail", e);
                throw new ApplicationException("500", "workbook write stream to response fail");
            } finally {
                try {
                    workbook.close();
                } catch (IOException ex) {
                    log.error("workbook close fail ", ex);
                }
            }
        }
    }

    /**
     * 造数据
     *
     * @return
     */
    private List<DataBean> getData() {
        List<DataBean> list = new ArrayList<>();
        DataBean entity = new DataBean();
        entity.setEquipCn("电视");
        entity.setEquipEn("TV");
        entity.setEquipCode("TV001");
        DataBean entity2 = new DataBean();
        entity2.setEquipCn("电视");
        entity2.setEquipEn("TV");
        entity2.setEquipCode("TV001");
        list.add(entity);
        list.add(entity2);
        return list;
    }
}

 

package com.springbootemaildemo.excel.a;

import com.alibaba.fastjson.JSON;
import com.springbootemaildemo.service.impl.MailServiceImpl;
import io.swagger.annotations.ApiModelProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

@Component
public class EhcacheInstance {
    private static final Logger log = LoggerFactory.getLogger(EhcacheInstance.class);

    /**
     * 返回entity类bean属性名称和中文描述的有序键值集合 key是中文描述 value是字段名称 方便excel标题行转义
     * 增加@Cacheable缓存策略
     *
     * @param clazzType
     * @return
     */
    public Map<String, String> getBeanPropertyDesCollection(Class clazzType) {
        // 查找本类中定义的属性
        Map<String, String> titiles = new LinkedHashMap<String, String>();
        Field[] fields = clazzType.getDeclaredFields();
        for (Field field : fields) {
            ApiModelProperty prop = field.getDeclaredAnnotation(ApiModelProperty.class);
            // 未定义中文注解则默认取字段名称
            titiles.put((null != prop ? prop.value() : field.getName()), field.getName());
        }
        // 往上继承类获取属性
        Class clazz = clazzType.getSuperclass();
        while (!clazz.equals(Object.class)) {
            Field[] extralFileds = clazz.getDeclaredFields();
            for (Field field : extralFileds) {
                ApiModelProperty prop = field.getDeclaredAnnotation(ApiModelProperty.class);
                titiles.put((null != prop ? prop.value() : field.getName()), field.getName());
            }
            clazz = clazz.getSuperclass();
        }
        // 移除不需要的属性
        titiles.remove("serialVersionUID");
        // 底包中审计字段未加swagger注解,此处需手动转义 后续修改底包可移除此段代码
        titiles.remove("createdBy");
        titiles.put("创建人", "createdBy");

        titiles.remove("createDate");
        titiles.put("创建时间", "createDate");

        titiles.remove("lastUpdatedBy");
        titiles.put("修改人", "lastUpdatedBy");

        titiles.remove("lastUpdateDate");
        titiles.put("修改时间", "lastUpdateDate");
        log.info("excel title:{}", JSON.toJSONString(titiles));
        return titiles;
    }
}

 

excel工具类

package com.springbootemaildemo.excel.a;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.springbootemaildemo.util.ApplicationException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Administrator
 * @date 2020-5-16
 * excel导入导出工具类
 */
public class ExcelUtils {
    private static final Logger log = LoggerFactory.getLogger(ExcelUtils.class);
    private static final int MAXROWCOUNT = 10000;
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 导出数据到excel文件
     *
     * @param result   待存入的bean结果集
     * @param titlesEN 英文标题
     * @param titlesCN 中文标题
     */
    public static <T> Workbook exportDataToWorkBook(List<T> result, String[] titlesEN, String[] titlesCN) {
        // 内存中创建一个07版以上格式的excel
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 重命名工作簿
        XSSFSheet sheet = workbook.createSheet("data");

        //检查标题行元素是否合法 且一 一对应
        if (null == titlesEN || null == titlesCN || titlesEN.length < 1 || titlesCN.length < 1 || titlesEN.length != titlesCN.length) {
            return null;
        }
        // 创建标题行 设置样式
        Row row = sheet.createRow(0);
        CellStyle style = freeStyle(workbook);
        Cell cell = null;
        for (int i = 0; i < titlesCN.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(titlesCN[i]);
            cell.setCellStyle(style);
        }
        // 数据检查 不能超过MaxRowCount防止内存溢出
        if (null == result || result.size() < 1 || result.size() > MAXROWCOUNT) {
            return workbook;
        }
        // 填充内容
        Cell content = null;
        String cellValue = null;
        for (int i = 0; i < result.size(); i++) {
            row = sheet.createRow(i + 1);
            for (int j = 0; j < titlesEN.length; j++) {
                // 将内容按顺序赋给对应的列对象
                try {
                    cellValue = BeanUtils.getProperty(result.get(i), titlesEN[j]);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
                content = row.createCell(j);
                content.setCellType(CellType.STRING);
                content.setCellValue(cellValue);
            }
        }
        // 宽度自适应
        rejustColumnLength(sheet);
        return workbook;
    }

    /**
     * 工作簿列宽自适应
     *
     * @param sheet
     */
    private static void rejustColumnLength(XSSFSheet sheet) {
        if (null == sheet) {
            return;
        }
        Row lastRow = sheet.getRow(sheet.getLastRowNum());
        Iterator<Cell> iterator = lastRow.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            iterator.next();
            // 宽度自适应
            sheet.autoSizeColumn(i, true);
            i++;
        }
    }

    public static CellStyle freeStyle(XSSFWorkbook workbook) {
        XSSFCellStyle style = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        // 设置字体样式
        font.setFontName("宋体");
        // 设置字体大小
        font.setFontHeightInPoints((short) 12);
        font.setBold(true);
        style.setFont(font);
        // 设置标题行背景颜色  
        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
//        style.setFillPattern(CellStyle.SOLID_FOREGROUND);
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        // 水平对齐方式
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        return style;
    }
}

结果:

 

以上是关于Apache POI 4.0.1版本 Excel导出数据案例(兼容 xls 和 xlsx)的主要内容,如果未能解决你的问题,请参考以下文章

Apache POI 4.0.1版本 Excel导出数据案例(兼容 xls 和 xlsx)

java通过apache poi框架读取2007版Excel文件

SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」

Java解析Excel之POI

Apache POI 操作Excel-- Excel基础

JAVA 通过POI 模版,导出excel