首页 >excel操作 > 内容

小白学编程之使用模板导出Excel

2023年8月21日 23:08

(反正没人看到,那我就偷偷学一下)

导出数据库到模板的Excel

这个篇笔记主要是总结一下。

首先是敲了一个简单的导出数据,代码如下:

这是Controller层(注:reqBookService.exportExcel()里面就是只是select出所有数据)

@RequestMapping("/export")    public void export(HttpServletResponse response,Model model) throws Exception {        List<ReqBook> books = reqBookService.exportExcel();        Workbook workbook = new XSSFWorkbook();//XSSFWorkbook可以创建.xlsx格式的Excel,区别于上一篇的.xls格式        Sheet sheet = workbook.createSheet("sheeet0");        String[] titles = {"ISBN","名称","作者","出版社","数量"};        Row row = sheet.createRow(0);        for (int i = 0;i< titles.length;i++) {            Cell cell = row.createCell(i);            cell.setCellValue(titles[i]);        }        for (int i = 0;i < books.size();i++){            row = sheet.createRow(i+1);            ReqBook reqBook = books.get(i);            Cell ISBNCell = row.createCell(0);            ISBNCell.setCellValue(reqBook.getBookISBN());            Cell nameCell = row.createCell(1);            nameCell.setCellValue(reqBook.getName());            Cell authorCell = row.createCell(2);            authorCell.setCellValue(reqBook.getAuthor());            Cell publishingCell = row.createCell(3);            publishingCell.setCellValue(reqBook.getPublishing());            Cell quantityCell = row.createCell(4);            quantityCell.setCellValue(reqBook.getQuantity());        }        String filename = URLEncoder.encode("图书表.xlsx","UTF-8");        response.setContentType("application/octet-stream");//设置输出类型        response.setHeader("content-disposition","attachment;filename=" + filename);//文件下载需要的        response.setHeader("filename",filename);        workbook.write(response.getOutputStream());    }

这段是最初的代码,缺点很显然,太死,不够灵活,所以我封装了一下作为一个util类(注:还有一些欠缺:不能设置结束行,开始列,结束列)
自定义注解@ExcelAtrr

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 自定义注解 * 用于导出Excel */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface ExcelAtrr {    int sort();}

sort等于几就是导出Excel的第几列

import com.example.anno.ExcelAtrr;public class ReqBook {    /**     *id     */    private Integer id;    /**     * ISBN     */    @ExcelAtrr(sort = 3)    private String bookISBN;    /**     * 书名     */    @ExcelAtrr(sort = 0)    private String name;    /**     * 作者     */    @ExcelAtrr(sort = 1)    private String author;    /**     * 出版社     */    @ExcelAtrr(sort = 2)    private String publishing;    /**     * 数量     */    @ExcelAtrr(sort = 4)    private Integer quantity;

封装的使用模板导出工具

import com.example.anno.ExcelAtrr;import com.example.entity.ReqBook;import org.apache.poi.ss.usermodel.*;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import org.springframework.lang.NonNull;import javax.servlet.http.HttpServletResponse;import java.io.OutputStream;import java.lang.reflect.Field;import java.net.URLEncoder;import java.util.List;import java.util.Map;import java.util.Objects;/** * 导出Excel工具 * 需要objs、   path、    rowIndex、 response四个参数 *   数据类型  模板路径   开始行     response * @param <T> */public class ExportUtil<T> {    public void exportExcelStyle(@NonNull Map<String, Object> params)throws Exception{        List<T> objs = (List<T>) params.get("objs");//设置泛型        String path = (String) params.get("path");//路径        Integer rowIndex = (Integer) params.get("rowIndex");//开始行//        Integer cellIndex = (Integer) params.get("cellIndex");//开始列        HttpServletResponse response = (HttpServletResponse) params.get("response");        String filename = (String) params.get("filename");        Workbook workbook = new XSSFWorkbook(Objects.requireNonNull(ExportUtil.class.getClassLoader().getResourceAsStream(path)));        Sheet sheet = workbook.getSheetAt(0);        Row row1 = sheet.getRow(rowIndex);        CellStyle[] cellStyles = new CellStyle[row1.getLastCellNum()];        for (int i = 0;i< cellStyles.length;i++) {            cellStyles[i]=row1.getCell(i).getCellStyle();        }        for (int i = 0;i < objs.size();i++){            Row row = sheet.createRow(i + rowIndex);            T t = objs.get(i);            Class<?> clazz = t.getClass();            Field[] fields = clazz.getDeclaredFields();//只要标了注解的            for (int j = 0; j<cellStyles.length; j++){//根据上面拿到的单元格属性添加                Cell cell = row.createCell(j);                cell.setCellStyle(cellStyles[j]);                //每找出一个有注解的字段,就填入                for (Field field: fields) {                    ExcelAtrr annotation = field.getAnnotation(ExcelAtrr.class);                    if (annotation!=null){                        int sort = annotation.sort();                        if (sort==j) {                            field.setAccessible(true);                            cell.setCellValue(field.get(t).toString());                        }                    }                }            }        }        String fileName = URLEncoder.encode(filename+".xlsx","UTF-8");//下载为“.xlsx”        response.setContentType("application/octet-stream");//设置输出类型        response.setHeader("content-disposition","attachment;filename=" + fileName);//文件下载需要的        response.setHeader("filename",fileName);        workbook.write(response.getOutputStream());    }}

这样就可以用泛型写任何实体的Excel导出
eg:

/**     * 使用模板导出Excel     * @param response     * @param model     * @throws Exception     */    @RequestMapping("/exportExcelStyle")    public void exportExcelStyle(HttpServletResponse response,Model model) throws Exception {        List<ReqBook> reqBooks = reqBookService.exportExcel();        ExportUtil<ReqBook> exportUtil = new ExportUtil<>();        Map<String,Object> params = new HashMap<>();        params.put("objs",reqBooks);        params.put("path", "excel/test.xlsx");//模板的路径,我是放在resources下面 //导出的表要有表头否则可能会报错,我的表头是两行所以从第二行开始        params.put("rowIndex",2);//开始行,从0开始数//        params.put("cellIndex",0);//开始列,默认从0开始        params.put("response",response);        params.put("filename","导出的Excel");        exportUtil.exportExcelStyle(params);    }

虽然缺点还很多但是目前导出一个如下的表还是够用了
这是模板
模板表
这是导出后的样子
导出的表
做这些真的是废了我好长时间,很多莫名其妙的空指针异常,比如:getResourceAsStream()报异常拿不到path,有可能不是路径问题而是字段或者模板表和开始行有问题,我一直以为是我路径不对,是真的坑。
最后,我也是小白如有更好的建议或意见请多多评论指正,不胜感激。


参考文章:https://blog.csdn.net/qq_41802460/article/details/105644672

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时候联系我们修改或删除,在此表示感谢。

特别提醒:

1、请用户自行保存原始数据,为确保安全网站使用完即被永久销毁,如何人将无法再次获取。

2、如果上次文件较大或者涉及到复杂运算的数据,可能需要一定的时间,请耐心等待一会。

3、请按照用户协议文明上网,如果发现用户存在恶意行为,包括但不限于发布不合适言论妄图

     获取用户隐私信息等行为,网站将根据掌握的情况对用户进行限制部分行为、永久封号等处罚。

4、如果文件下载失败可能是弹出窗口被浏览器拦截,点击允许弹出即可,一般在网址栏位置设置

5、欢迎将网站推荐给其他人,网站持续更新更多功能敬请期待,收藏网站高效办公不迷路。

      



登录后回复

共有0条评论