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

news2024/11/17 22:38:11

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

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

1、单sheet

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

 定义类:

@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;
}

调用方式:

    @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、使用工具类进行调用。

        

定义的类:       

@Data
public class ScPerformanceForChildExcelVo {

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

}
@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;
}

调用方式:

    @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、工具类

注解类:

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:

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.coloradmin.cn/o/1314007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络快速刷题

自用//奈奎斯特定理和香农定理计算题 参考博客&#xff1a;UDP协议是什么&#xff1f;作用是什么&#xff1f; 肝了&#xff0c;整理了8张图详解ARP原理 【网络协议详解】——FTP系统协议&#xff08;学习笔记&#xff09; 在OSI参考模型中&am…

论文自己改过后怎么降重 papergpt

大家好&#xff0c;今天来聊聊论文自己改过后怎么降重&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 论文自己改过后如何降重 在论文修改过程中&#xff0c;我们往往会对…

力扣785.判断二分图

存在一个 无向图 &#xff0c;图中有 n 个节点。其中每个节点都有一个介于 0 到 n - 1 之间的唯一编号。给你一个二维数组 graph &#xff0c;其中 graph[u] 是一个节点数组&#xff0c;由节点 u 的邻接节点组成。形式上&#xff0c;对于 graph[u] 中的每个 v &#xff0c;都存…

[蓝桥杯刷题]合并区间、最长不连续子序列、最长不重复数组长度

前言 ⭐Hello!这里是欧_aita的博客。 ⭐今日语录: 成功的关键在于对目标的持久追求。 ⭐个人主页&#xff1a;欧_aita ψ(._. )>⭐个人专栏&#xff1a; 数据结构与算法 数据库 文章目录 前言合并区间问题&#x1f4d5;现实应用大致思路代码实现代码讲解 最长不连续子序列&a…

Python封装ADB获取Android设备wifi地址的方法

一、代码实现 import subprocessimport re import subprocessfrom common.logger import loggerdef get_device_wifi_address(udid):ip_command fadb -s {udid} shell ip routeresult subprocess.check_output(ip_command, shellTrue, textTrue)# 提取 IP 地址ip_address r…

Python多态原理及实现

对于弱类型的语言来说&#xff0c;变量并没有声明类型&#xff0c;因此同一个变量完全可以在不同的时间引用不同的对象。当同一个变量在调用同一个方法时&#xff0c;完全可能呈现出多种行为&#xff08;具体呈现出哪种行为由该变量所引用的对象来决定&#xff09;&#xff0c;…

跟随鼠标动态显示线上点的值(基于Qt的开源绘图控件QCustomPlot进行二次开发)

本文为转载 原文链接&#xff1a; 采用Qt快速绘制多条曲线&#xff08;折线&#xff09;&#xff0c;跟随鼠标动态显示线上点的值&#xff08;基于Qt的开源绘图控件QCustomPlot进行二次开发&#xff09; 内容如下 QCustomPlot是一个开源的基于Qt的第三方绘图库&#xff0c;能…

功能测试转向自动化测试 。10 年 心路历程——愿测试人不再迷茫

十年测试心路历程&#xff1a; 由于历史原因&#xff0c;大部分测试人员&#xff0c;最开始接触都是纯功能界面测试&#xff0c;随着工作年限&#xff0c;会接触到一些常用测试工具&#xff0c;比如抓包&#xff0c;数据库&#xff0c;linux 等。 我大学学的计算机专业&#…

Linux环境下HTTP请求的代码详解与实例

嘿&#xff0c;Linux狂热者们&#xff0c;是时候让我们在这个充满激情的平台上探索一下HTTP协议的奥秘了。我知道&#xff0c;对于这个我们每天都在使用&#xff0c;但却可能没深入了解过的HTTP&#xff0c;你们一定充满了好奇和期待。那么&#xff0c;让我们一起踏上这趟探索之…

【Docker】实战:nginx、redis

▒ 目录 ▒ &#x1f6eb; 导读开发环境 1️⃣ Nginx 拉取 Nginx 镜像nginx.conf启动 Nginx访问 Nginx 2️⃣ redis拉取 Redis 镜像启动 Redis 容器测试 Redis &#x1f4d6; 参考资料 &#x1f6eb; 导读 开发环境 版本号描述文章日期2023-12-15操作系统Win10 - 22H222621.2…

VR虚拟仿真技术应用到外事警察岗位技能培训的场景及优势

VR治安民警常态化工作实战教学演练是一种利用VR虚拟现实制作和web3d开发技术进行治安民警培训和实战演练的新型教学模式。相较于传统的培训方式&#xff0c;VR治安民警常态化工作实战教学演练具有以下优点&#xff1a; VR实战是一种完全虚拟的实战训练方式&#xff0c;他可以根…

Apache Flume(4):日志文件监控

1 案例说明 企业中应用程序部署后会将日志写入到文件中&#xff0c;可以使用Flume从各个日志文件将日志收集到日志中心以便于查找和分析。 2 使用Exec Soucre Exec Source Exec Source通过指定命令监控文件的变化&#xff0c;加粗属性为必须设置的。 属性名默认值说明chan…

如何用DETR(detection transformer)训练自己的数据集,并推理图片

前言 这里我分享一下官方写的DETR的预测代码&#xff0c;其实就是github上DETR官方写的一个Jupyter notebook&#xff0c;可能需要梯子才能访问&#xff0c;这里我贴出来。因为DETR比较难训练&#xff0c;我觉得可以用官方的预训练模型来看看效果。 如果要用自己训练的模型来…

MYSQl基础操作命令合集与详解

MySQL入门 先来个总结 SQL语言分类 DDL&#xff08;Data Definition Language&#xff09; - 数据定义语言: 用于定义和管理数据库结构&#xff0c;包括创建、修改和删除数据库对象。 示例&#xff1a;CREATE, ALTER, DROP等语句。 DML&#xff08;Data Manipulation Lan…

FC-13A(用于汽车应用的kHz范围晶体单元,低轮廓贴片)

FC-13A晶体非常适合用在汽车导航系统设计中的应用&#xff0c;是一种具有优异的频率性能和AEC-Q200标准认证的汽车工业级高精度晶体,FC-13A是一款尺寸为3.2 1.5 0.9mm&#xff0c;频率范围32.768KHz耐高温晶振&#xff0c;频率温度系数仅为-0.04ppm/℃&#xff0c;并且其老化…

Java基础面试题小结

基础面试题 Java语言简介 Java是1995年由sun公司推出的一门高级语言&#xff0c;该语言具备如下特点: 简单易学&#xff0c;相较于C语言和C&#xff0c;没有指针的概念&#xff0c;所以操作和使用是会相对容易一些。平台无关性&#xff0c;即Java程序可以通过Java虚拟机在不…

牛客网SQL训练2—SQL基础进阶

文章目录 一、基本查询二、数据过滤三&#xff1a;函数四&#xff1a;分组聚合五&#xff1a;子查询六&#xff1a;多表连接七&#xff1a;组合查询八&#xff1a;技能专项-case when使用九&#xff1a;多表连接-窗口函数十&#xff1a;技能专项-having子句十一&#xff1a;技能…

vue 使用 Echarts做地图及飞线效果

前言&#xff1a; 效果图 一. 项目中安装以及引入Echarts 1.1 npm 命令安装echarts库 npm install echarts --save 1.2 yarn命令安装echarts库 yarn add echarts 1.3 引用 a. 在使用页面上引入 在Vue组件的script标签中引入echarts库 使用 echarts import * as echarts f…

flowable之三 启动一个流程并跟踪

1. 背景介绍 当我们部署一个流程并启动后&#xff0c;Flowable会按照既定流程定义及进行节点处理以及自动流转&#xff0c;从一个节点执行到下一个节点&#xff0c;直至结束。在此过程中&#xff0c;系统如何处理BPMN XML文件&#xff1f;节点如何进行流转&#xff1f;本文对f…

衡兰芷若成绝响,人间不见周海媚(4k修复基于PaddleGan)

一代人有一代人的经典回忆&#xff0c;1994年由周海媚、马景涛、叶童主演的《神雕侠侣》曾经风靡一时&#xff0c;周海媚所诠释的周芷若凝聚了汉水之钟灵&#xff0c;峨嵋之毓秀&#xff0c;遇雪尤清&#xff0c;经霜更艳&#xff0c;俘获万千观众&#xff0c;成为了一代人的共…