记录word导出工具类

话不多说,直接上代码(编码环境:jdk1.8、springboot框架)
用到的依赖:

		<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.17</version>
        </dependency>

1、编写注解类 用于标识需要展示到excel中的字段

package com.sztf.shidaikeyi.annotation;

import java.lang.annotation.*;

/**
 * 自定义注解类 用来标识excel要导出的字段
 */
@Documented
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelTitle {
    /**
     * 表头信息
     */
    String head() default "";

}

2、创建实体类并使用注解(我这里用到了lombok 所以没有写get、set)

/**
 * 维修工单实体类
 *
 * @Author: ljp
 * @CreateDate: 2021/1/26 17:17
 */
@Data
@TableName("repair_order")
public class RepairOrder extends BaseEntity {
    private static final long serialVersionUID = 6251454355648214332L;
    /**
     * 主键
     */
    @TableId("id")
    private Long id;
    /**
     * 关联项目id
     */
    private Long projectId;
    //以下字段不存在数据库
    /**
     * 项目名称
     */
    @ExcelTitle(head = "项目名称")
    @TableField(exist = false)
    private String projectName;
    /**
     * 关联设备名称
     */
    @ExcelTitle(head = "关联设备名称")
    @TableField(exist = false)
    private String equipmentName;
    //以上字段不存在数据库
    /**
     * 工段名称
     */
    @ExcelTitle(head = "工段名称")
    private String workSegment;
    /**
     * 关联设备id
     */
    private Long equipmentId;
    /**
     * 原因
     */
    @ExcelTitle(head = "原因")
    private String reason;
    /**
     * 解决办法
     */
    @ExcelTitle(head = "解决办法")
    private String solution;
    /**
     * 执行人
     */
    @ExcelTitle(head = "执行人")
    private String executor;
    /**
     * 填写人
     */
    @ExcelTitle(head = "填写人")
    private String writer;
    /**
     * 填写时间
     */
    @ExcelTitle(head = "填写时间")
    private String writeTime;
    /**
     * 截止时间
     */
    @ExcelTitle(head = "截止时间")
    private String deadline;
    /**
     * 签名
     */
    @ExcelTitle(head = "签名")
    private String signature;
    /**
     * 备注
     */
    @ExcelTitle(head = "备注")
    private String remark;

}

3、工具类的编写:

package com.sztf.shidaikeyi.util;

import com.sztf.shidaikeyi.annotation.ExcelTitle;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * 导出excel工具类
 * 暂时没有完善 实体类中的字段要按照到处顺序排列 暂时没有想到好的办法
 *
 * @Author: ljp
 * @CreateDate: 2021/3/17 15:21
 */
public class ExcelUtil<T> {

    /**
     * sheet页名称
     */
    public static final String SHEET_NAME = "sheet";

    /**
     * 导出excel
     *
     * @param sheetName sheet页名称
     * @param dataList  数据集合
     * @param response  返回对象
     * @param fileName  文件名称
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws IOException
     */
    public void exportExcel(String sheetName, List<T> dataList, HttpServletResponse response, String fileName)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException {
        //没有数据 直接结束
        if (dataList == null || dataList.size() == 0) return;
        //生成一个表格
        HSSFWorkbook workbook = new HSSFWorkbook();
        //创建sheet页
        HSSFSheet sheet = workbook.createSheet(sheetName);
        //设置表格默认列宽度为20个字节
        sheet.setDefaultColumnWidth((short) 20);
        T data = dataList.get(0);
        //通过反射 获取所有字段信息
        Field[] fields = data.getClass().getDeclaredFields();
        //记录所有表头
        List<String> titleList = new ArrayList<>();
        //需要展示的字段合集
        List<Field> showFields = new ArrayList<>();
        for (Field field : fields) {
            //如果字段上没有注解 代表不需要导出
            if (field.getAnnotations().length == 0) continue;
            for (Annotation annotation : field.getAnnotations()) {
                if (annotation instanceof ExcelTitle) {
                    ExcelTitle excelTitle = (ExcelTitle) annotation;
                    titleList.add(excelTitle.head());
                    showFields.add(field);
                }
            }
        }
        //如果在实体类中没有找到excelTile注解 则直接返回
        if (titleList.size() == 0) return;
        //创建第一行
        HSSFRow row = sheet.createRow(0);
        //填充表头
        for (int i = 0; i < titleList.size(); i++) {
            row.createCell(i).setCellValue(titleList.get(i));
        }
        Iterator<T> iterator = dataList.iterator();
        //当前行数
        int rowIndex = 0;
        while (iterator.hasNext()) {
            row = sheet.createRow(++rowIndex);
            T t = iterator.next();
            for (int i = 0; i < showFields.size(); i++) {
                HSSFCell cell = row.createCell(i);
                Field field = showFields.get(i);
                String fieldName = field.getName();
                String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                Class<?> clazz = t.getClass();
                Method getMethod = clazz.getMethod(getMethodName);
                Object value = getMethod.invoke(t);
                String cellValue;
                if (value == null) {
                    cellValue = "";
                } else {
                    if (value instanceof Date) {
                        cellValue = DateUtil.dateToStr((Date) value, DateUtil.YYYY_MM_DD_HH_MM_SS);
                    } else {
                        //可能是integer、double、float、long、string
                        cellValue = String.valueOf(value);
                    }
                }
                cell.setCellValue(cellValue);
            }
        }
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        OutputStream os = response.getOutputStream();
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ";" + "filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
        workbook.write(os);
        os.flush();
        os.close();
    }
}

4、调用测试
编写接口,这里我就贴上我实际的代码,后台如何查询是不体现的

@GetMapping("/downloadExcel")
    public void downloadExcel(String startTime, String endTime, Long projectId, Integer pageNum, HttpServletRequest request, HttpServletResponse response) throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        SysUser curUser = (SysUser) redisTemplate.opsForValue().get(SimplifyUtil.getToken(request));
        IPage<RepairOrder> iPage = repairOrderService.myPage(new Page<>(pageNum == null ? 0 : pageNum, Constant.LIMIT),
                SimplifyUtil.buildCommonVo(startTime, endTime, projectId, curUser, userProjectService));
         //上面是自己的业务逻辑 主要是在这里进行调用
        new ExcelUtil<RepairOrder>().exportExcel(ExcelUtil.SHEET_NAME, iPage.getRecords(), response, EXCEL_NAME);
    }

现在有个点想实现,但是没找到思路:
现在有个缺陷,就是导出的顺序是按实体类中字段的顺序导出的,感觉不太方便。如果可以在注解中再加一个排序字段,可以根据注解类中的排序字段进行导出就完美了,欢迎大神指导!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值