java导出excel通用工具(POI,类注解形式)

news/2024/7/21 5:14:04 标签: java, excel, 数据库

        通过给类定义注解(设置名称,设置kv转换值),然后利用设置的名称和传入的数据进行导出。

只需要在项目添加两个工具类就可以实现excel导出功能。

1、单sheet

        步骤:1、根据业务需求定义导出的类,并设置表头名称。
                   2、调用工具类                                     

 定义类:

java">@Data
public class ScDetailsReviewExcelVo {
    //年份
    @ExcelIO(value = "年份")
    private String examineYear;
    /**考核批次*/
    @ExcelIO(value = "考核批次")
    private String batchName;
    //姓名
    @ExcelIO(value = "姓名")
    private String realname;
    //科室
    @ExcelIO(value = "科室")
    private String departName;
    /**考核总分*/
    @ExcelIO(value = "考核总分")
    private String examineScore;
    /**个人能力得分*/
    @ExcelIO(value = "个人能力得分")
    private String personnelScore;
    /**工作业绩得分*/
    @ExcelIO(value = "工作业绩得分")
    private String postScore;
    /**额外工作得分*/
    @ExcelIO(value = "额外工作得分")
    private String otherScore;
    /**状态*/
    @ExcelIO(value = "状态",kv="0-未提交;1-已完成;2-已退回;3-已归档")
    private Integer userState;
}

调用方式:

java">    @Override
    public void exprotExcel(HttpServletResponse response, ScDetailsReview scDetailsReview) {
        //获取数据
        List<ScDetailsReviewExcelVo> list=scDetailsReviewMapper.selectForExcel(scDetailsReview);
        //调用工具
        ExcelUtil<ScDetailsReviewExcelVo> excelVoExcelUtil=new ExcelUtil<>(ScDetailsReviewExcelVo.class);
        //导出数据
        excelVoExcelUtil.getExcel(list,response,"打分");
    }

2、多sheet

        步骤:1、定义大类作为参数对象。
                   2、在大类中设置List子类,且各List对应各sheet页数据,设置List泛型中的属性为其注
                        解表头名称(下列例子中只展示了一个大类和其中的一个子类)
                   3、使用工具类进行调用。

        

定义的类:       

java">@Data
public class ScPerformanceForChildExcelVo {

    //个人能力
    private List<ScPersonalDetailedExcelVo> scPersonalDetailedExcelVoList=new ArrayList<>();
    //工作业绩
    private List<ScPostDetailedExcelVo> scPostDetailedExcelVoList=new ArrayList<>();
    //额外
    private List<ScOtherDetailedExcelVo> scOtherDetailedExcelVoList=new ArrayList<>();

}
java">@Data
public class ScPersonalDetailedExcelVo {
    /**类别*/
    @ExcelIO(value = "类别")
    private String category;
    /**考评指标*/
    @ExcelIO(value = "考评指标")
    private String assessmentIndex;
    /**考评要点*/
    @ExcelIO(value = "考评要点")
    private String keyPoint;
    /**评分参考细则*/
    @ExcelIO(value = "评分参考细则")
    private String detailedRules;
    /**总分分值*/
    @ExcelIO(value = "总分分值")
    private String ruleScore;
    /**得分*/
    @ExcelIO(value = "得分")
    private String personnelUserScore;
}

调用方式:

java">    @Override
    public void exprotExcel(HttpServletResponse response, ScDetailsReview scDetailsReview) {
        //个人能力
        List<ScPersonalDetailedExcelVo> personalDetailedExcelVoList= scPersonalDetailedService.selectExcel(scDetailsReview);
        //工作业绩
        List<ScPostDetailedExcelVo> scPostDetailedExcelVoList= scPostDetailedService.selectExcel(scDetailsReview);
        //额外
        List<ScOtherDetailedExcelVo> scOtherDetailedExcelVoList= scOtherDetailedService.selectExcel(scDetailsReview);

        ScPerformanceForChildExcelVo scPerformanceForChildExcelVo=new ScPerformanceForChildExcelVo();
        scPerformanceForChildExcelVo.setScPersonalDetailedExcelVoList(personalDetailedExcelVoList);
        scPerformanceForChildExcelVo.setScPostDetailedExcelVoList(scPostDetailedExcelVoList);
        scPerformanceForChildExcelVo.setScOtherDetailedExcelVoList(scOtherDetailedExcelVoList);

        ExcelUtil<ScPerformanceForChildExcelVo> scPerformanceForChildExcelVoExcelUtil=new ExcelUtil<>(ScPerformanceForChildExcelVo.class);
        scPerformanceForChildExcelVoExcelUtil.getExcels(scPerformanceForChildExcelVo,response);

    }

3、工具类

注解类:

java">package org.jeecg.utils;

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

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelIO {
    /** 字段名称 */
    String value();

    /** 导出映射,格式如:0-未知;1-男;2-女 */
    String kv() default "";
}

ExcelUtil:

java">package org.jeecg.utils;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExcelUtil<T> {
    //泛型
    public Class<T> clazz;

    public Workbook workbook;

    //sheet对象
    public Sheet sheet;

    //标题行总列数
    private Integer tableNames;

    //样式集合
    private Map<String,CellStyle> styleMap=new HashMap<>();

    //需要导出字段
    private List<Field> fieldList=new ArrayList<>();

    public ExcelUtil(Class<T> clazz)
    {
        this.clazz = clazz;
    }

    //创建样式
    private void setStyleMap(){
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        Font titleFont = workbook.createFont();
        titleFont.setFontName("宋体");
        titleFont.setFontHeightInPoints((short) 9);
        titleFont.setBold(true);
        style.setFont(titleFont);
        style.setWrapText(true);
        //标题样式
        styleMap.put("title", style);

    }

    //设置单元格宽度
    private void setWidth(Sheet sheet,Integer colNum){
        for (int i = 0; i < colNum; i++) {
            sheet.autoSizeColumn(i);
//            int columnWidth = sheet.getColumnWidth(i);
//            sheet.setColumnWidth(colNum,Math.min(sheet.getColumnWidth(i)+1000,15*256));
        }
    }

    //创建表头
    private void setTableName(Class clazz,Sheet sheet,Integer rowNum){
        //创建标题
        List<String> tiltes=new ArrayList<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //获取字段属性
            ExcelIO annotation = field.getAnnotation(ExcelIO.class);
            if(null!=annotation){
                String value = annotation.value();
                //需要的标题
                tiltes.add(value);
                //需要的字段
                fieldList.add(field);
            }
        }
        //写入标题
        tableNames=tiltes.size();
        Row row = sheet.createRow(rowNum);
        for (int i = 0; i < tableNames; i++) {
            Cell cell = row.createCell(i);
            cell.setCellValue(tiltes.get(i));
            cell.setCellStyle(styleMap.get("title"));
        }
    }

    //创建标题行
    private void setTilte(String tilte){
        //创建标题
        Row row = sheet.createRow(0);
        Cell cell = row.createCell(0);
        cell.setCellValue(tilte);
        cell.setCellStyle(styleMap.get("title"));
        //合并
        sheet.addMergedRegion(new CellRangeAddress(0,0,0,tableNames-1));
    }

    //写入数据
    private void setData(List<T> data,Integer rowNum){
        for (Object datum : data) {
            Row row = sheet.createRow(rowNum);
            rowNum++;
            for (Integer integer = 0; integer < tableNames; integer++) {
                Cell cell = row.createCell(integer);
                Field field = fieldList.get(integer);
                cell.setCellValue(changeValue(field,datum));
            }
        }
    }

    //写入数据
    private void setDataForChildeSheet(List<Object> data,Sheet sheet,Integer rowNum){
        for (Object datum : data) {
            Row row = sheet.createRow(rowNum);
            rowNum++;
            for (Integer integer = 0; integer < tableNames; integer++) {
                Cell cell = row.createCell(integer);
                Field field = fieldList.get(integer);
                cell.setCellValue(changeValue(field,datum));
            }
        }
    }

    //有需要转换的值
    private String changeValue(Field field,Object data){
        try {
            field.setAccessible(true);
            String filed = null==field.get(data)?"":field.get(data).toString();
            if(null==filed){
                return "";
            }

            ExcelIO annotation = field.getAnnotation(ExcelIO.class);
            if(null!=annotation){
                String value = annotation.kv();
                if(null==value || "".equals(value)){
                    return filed;
                }
                String[] split = value.split(";");
                for (String s : split) {
                    String[] split1 = s.split("-");
                    if(split1.length>=2){
                        if(split1[0].equals(filed)){
                            return split1[1];
                        }
                    }
                }
            }
            return "";
        } catch (IllegalAccessException e) {
            return "";
        }
    }

    //多sheet页其中一个
    private void setSheetData(Sheet sheet1, Class<?> genericClass, List<Object> o) {
        //创建标题
        setTableName(genericClass,sheet1,0);
        //写数据
        setDataForChildeSheet(o,sheet1,1);
        //设置宽度
        setWidth(sheet1,tableNames);
        //清除存在的数据
        fieldList.clear();
        tableNames=0;
    }

    //导出excel
    public void getExcel(List<T> data, HttpServletResponse response,String name){
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 创建一个新的工作薄
        workbook = new XSSFWorkbook();
        // 创建一个工作表
        sheet = workbook.createSheet("Sheet1");
        //初始化样式
        setStyleMap();
        //创建表头
        setTableName(clazz,sheet,1);
        //创建标题
        setTilte(name);
        //写入数据
        setData(data,2);
        //设置宽度
        setWidth(sheet,tableNames);

        //返回给前端
        try {
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    //导出多个sheet页,传入的data的内部是多个list,list泛型就是各个sheet的数据,且泛型需要用excle注解进行设置
    public void getExcels(T data, HttpServletResponse response){
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 创建一个新的工作薄
        workbook = new XSSFWorkbook();
        //初始化样式
        setStyleMap();
        //获取子类class对象
        Field[] declaredFields = clazz.getDeclaredFields();
        Integer i=0;
        for (Field declaredField : declaredFields) {
            Type genericType = declaredField.getGenericType();
            if (genericType instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) genericType;
                Type[] typeArguments = parameterizedType.getActualTypeArguments();
                if (typeArguments.length > 0) {
                    //子类class对象
                    Class<?> genericClass = (Class<?>) typeArguments[0];
                    try {
                        declaredField.setAccessible(true);
                        //获取子类数据
                        List<Object> o = (List)declaredField.get(data);
                        if(null!=o && o.size()>0){
                            // 创建子工作表
                            Sheet sheet1 = workbook.createSheet("Sheet"+i);
                            i++;
                            //为子工作表赋值
                            setSheetData(sheet1,genericClass,o);
                        }
                    } catch (IllegalAccessException e) {
                        return;
                    }
                }
            }
        }

        //返回给前端
        try {
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

}


http://www.niftyadmin.cn/n/5266043.html

相关文章

java发起http、https请求,并携带cookie、header,post参数放body并可选关闭ssl证书验证,高可用版

公司有个需求是发起https请求对接国家数据接口&#xff0c;需要带header、cookie&#xff0c;并关闭ssl证书验证&#xff0c;搜了很多文章&#xff0c;都说用HttpsURLConnection发起请求&#xff0c;但不知为啥在封装body参数的时候一直报400封装出错&#xff0c;也欢迎指出不足…

uniapp组件map地图组件使用

在uniapp中&#xff0c;可以使用uni-app官方提供的map组件来实现地图功能。下面是一个简单的使用示例&#xff1a; 在页面中引入map组件&#xff0c;在template中添加以下代码&#xff1a; <template><view><!-- map组件 --><map :longitude"longi…

23.12.15 《CLR via C#》 笔记8

第十一章 事件 事件是在类中定义的一种成员&#xff0c;定义了事件成员的类型可以&#xff1a; 方法能登记对事件的关注方法能注销对事件的关注事件发生时&#xff0c;登记了的方法会收到通知 设计要公开事件的类型 定义类型&#xff08;容纳要发给事件接收者的附加信息&#…

MQ入门—centos 7安装RabbitMQ 安装

三&#xff1a;RabbitMQ 安装 1.环境准备 Linux 的 CentOS 7.x 版本。Xftp 传输安装包到 Linux。Xshell 连接 Linux&#xff0c;进行解压安装。 RabbitMQ安装包 链接&#xff1a;https://pan.baidu.com/s/1ZYVI4YZlvMrj458jakla9A 提取码&#xff1a;dyto xshell安装包 链接&…

Graylog解决超出ES搜索最大窗口限制问题

今天在查询日志的时候graylog报了一个错&#xff1a; While retrieving data for this widget, the following error(s) occurred: Unable to perform search query: Elasticsearch exception [typeillegal_argument_exception, reasonResult window is too large, from size …

Vue中实现分布式动态路由的基本实现步骤介绍

设想一下&#xff0c;我们在做一个体量非常大的项目&#xff0c;这个项目有很多的模块和相当多的页面。当我们想修改一个路由的时候&#xff0c;我们打开了router文件夹下的index.js文件时&#xff0c;一串长到鼠标滚轮需要滚大半天才滚到底的路由简直让人头皮发麻。 在开始之前…

git变更关联的远程仓库

git变更关联的远程仓库 git 将本地关联的远程仓库1变更为新建的远程仓库2 1、移除本地的远程仓库关联关系 git remote remove origin 2、添加新的远程仓库地址&#xff1a; git remote add origin gitgithub.com:github-xiaobai/66-test-cc.git 3、生成本机的ssh-key(如果已…

深入理解人工智能中的图神经网络:原理、应用与未来展望

导言&#xff1a; 图神经网络&#xff08;Graph Neural Networks, GNNs&#xff09;作为人工智能领域的一项前沿技术&#xff0c;在社交网络分析、推荐系统、生物信息学等多个领域展现出卓越的性能。本文将深入剖析图神经网络的原理、当前应用场景以及未来可能的发展方向。 1.…