java用 poi封装一个excel导出模板工具类

记录封装一个excel导出工具类

因为业务需求需要支持导入导出功能,之前需要导出功能的模块比较少,可以直接调poi包的API接口,现在不行了,好几十个。。。一个一个写估计要通宵,因此写一个统一的导出模板。话不多说上代码!!
业务代码不方便贴出来,用demo演示。

jar包:

		<!-- poi -->
        <!--xls 03-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <!--xlsx 07-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

第一步,先整个注解,把需要导出的字段给注释上,不然把id,password什么的给导出来了岂不尴尬。

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

/**
 * @Author xjn
 * date 2021/3/11
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAnno {

    int sort();
}

第二步、给需要导出的实体类字段安排上

import com.study.config.ExcelAnno;
import lombok.Data;

/**
 * @Author xjn
 * date 2021/3/11
 */
@Data
public class User {

    private String id;

    @ExcelAnno(sort = 0)
    private String name;

    @ExcelAnno(sort = 1)
    private Integer age;

    @ExcelAnno(sort = 2)
    private String createTime;
}

第三步、封装poi模板

import com.study.config.ExcelAnno;
import lombok.NonNull;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author xjn
 * date 2021/3/11
 */
public class ExcelUtil<T> {

	/**
     * params包含:
     *  <实体类列表 objs
     *  开始行索引 rowIndex
     *  HttpServletResponse response
     *  模板路径 path
     *  文件名称 fileName>
     * 
     * @param params
     */
    public void exportExcel(@NonNull Map<String, Object> params) {
        XSSFWorkbook workbook = null;
        try {
            // 拿到需要导出的实体类(用泛型接收)
            List<T> objs = (List<T>) params.get("objs");
            // 从第几行开始写入
            Integer rowIndex = (Integer) params.get("rowIndex");
            HttpServletResponse response = (HttpServletResponse) params.get("response");
            // 通过类加载器获取excel模板信息 这个path指向resources下的目录 : ./excel/demo.xlsx
            InputStream inputStream = Objects.requireNonNull(ExcelUtil.class
                    .getClassLoader().getResourceAsStream((String) params.get("path")));
            workbook = new XSSFWorkbook(inputStream);
            // 获取excel的表单
            XSSFSheet sheetAt = workbook.getSheetAt(0);
            XSSFRow row1 = sheetAt.getRow(0);
            for (int i = 0; i < objs.size(); i++) {
                // 创建行
                XSSFRow row = sheetAt.createRow(i + rowIndex);
                // 获取实体信息
                T t = objs.get(i);
                Class<?> clazz = t.getClass();
                // 获取字段信息
                Field[] fields = clazz.getDeclaredFields();
                short lastCellNum = row1.getLastCellNum();
                for (int j = 0; j < lastCellNum; j++) {
                    XSSFCell cell = row.createCell(j);
                    for (Field field : fields) {
                        // 遍历字段信息 获取字段上的注解信息
                        ExcelAnno annotation = field.getAnnotation(ExcelAnno.class);
                        // 如果注解的sort和excel的列匹配 把值设置进去
                        if (annotation != null && annotation.sort() == j) {
                            // 暴力访问(因为字段是private),所以需要设置允许访问,或者字段设置成public也可
                            field.setAccessible(true);
                            // 这里需要判断一下,不然如果字段是空值的话会空指针。。。
                            cell.setCellValue(field.get(t) == null ? "" : field.get(t).toString());
                            break;
                        }
                    }
                }
            }
            String fileName = URLEncoder.encode((String) params.get("fileName"), "UTF-8");
            response.setContentType("application/octet-stream");
            response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
            workbook.write(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (workbook != null) {
                    workbook.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
}

封装好了,测一手

import com.study.util.ExcelUtil;
import com.study.dao.UserDao;
import com.study.entity.po.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author xjn
 * date 2021/3/11
 */
@RestController
@RequestMapping("/excel")
public class ExcelDemo {

    @Autowired
    UserDao userDao;

    @RequestMapping(value = "downLoad",method = RequestMethod.GET)
    public void loadfile(HttpServletResponse response) {

        List<User> all = userDao.findAll();

        ExcelUtil excelUtil = new ExcelUtil();
        Map<String,Object> map = new HashMap<>();
        map.put("objs",all);
        map.put("response",response);
        map.put("path", "./excel/template.xlsx");
        map.put("rowIndex",2);
        map.put("fileName","人员表");
        excelUtil.exportExcel(map);
    }

}

模板excel:
在这里插入图片描述
导出后的excel:
在这里插入图片描述好使,下班!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值