POI excel tool operations (five) package based annotation tools derived excel

       POI is used to export excel work which is often used, but if you have to write each export, will become more troublesome, the code basically repeats. So recently I took time to learn a little, according to his own notes, based on reflective technology, writing tools of a POI export excel. To achieve the basic primary and secondary header deriving both.

       The writing of this example is a simple SpringBoot works on SpringBoot do not understand, self-learning under.

1. Create a project SpringBoot

1.1 import dependencies

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>POI_SpringBoot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 定义公共资源版本 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <!-- 上边引入 parent,因此 下边无需指定版本 -->
        <!-- 包含 mvc,aop 等jar资源 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--spring操作数据库jpa  用于将数据存入数据库的类和方法的集-->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>-->

        <!-- 热部署 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>true</scope>
        </dependency>

        <!--spring模板引擎-->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>-->

        <!--数据库相关-->
        <!--<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>-->

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.collections</groupId>
            <artifactId>google-collections</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>



    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!-- 没有该配置,devtools 不生效 -->
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

1.2 startup class

package com.poi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PoiApplication {
    public static void main(String[] args) {
        SpringApplication.run(PoiApplication.class,args);
    }
}

1.3 Profile application.yml

I configured here will only configure the port number, the other did set up, there is a need can be set ourselves.

server:
  port: 9000

 

2, custom annotations

       Carrying excel export, we need to set some excel cell styles, such as: row height, column width, font and font color, etc. properties. To be able to flexible settings, so we need to define a note to set the properties of each column through annotations.

package com.poi.annotation;

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 ExcelColumn {
    /**
     * @Title: title
     * @Description: 表头列名 必填
     */
    public String title();

    /**
     * 列的序号,意思就是把添加这个注解的属性要放到excel的第几列,从1开始
     * 需要注意的是:这个值必须连续,比如:各个属性的sort必须是:1,3,2,4,6,5(可以乱序)
        但是不能出现:1,3,4,6,5(少了2)
     */
    public int sort();

    /**
     * @Title: width
     * @Description: 列宽 默认15
     */
    public short width() default 15;

    public enum Alignment {
        LEFT(0x1), CENTER(0x2), RIGHT(0x3);
        private int value;

        private Alignment(int value) {
            this.value = value;
        }
        public int getValue() {
            return value;
        }
    };

    /**
     * @Title: alignment
     * @Description: 文字样式 默认居中(Alignment.CENTER)
     */
    public Alignment alignment() default Alignment.CENTER;

    /**
     * @Title: boder
     * @Description: 单元格是否需要边框 环绕包围 默认true
     */
    public boolean boder() default true;

    public enum StyleColor {
        WHITE(0x9), BLACK(0x8), BLUE(0xc), RED(0xa), YELLOW(0xd);
        private int value;

        private StyleColor(int value) {
            this.value = value;
        }
        public int getValue() {
            return value;
        }
    };

    /**
     * @Title: styleColor
     * @Description: 单元格背景色 默认白色
     */
    public StyleColor styleColor() default StyleColor.WHITE;

    public enum FontColor {
        BLACK(0x8), BLUE(0xc), RED(0xa), YELLOW(0xd);
        private int value;

        private FontColor(int value) {
            this.value = value;
        }
        public int getValue() {
            return value;
        }
    };

    /**
     * @Title: fontColor
     * @Description: 文字颜色 默认黑色(FontColor.BLACK) 暂支持 BLACK BLUE RED YELLO
     */
    public FontColor fontColor() default FontColor.BLACK;

    /**
     * @Title: fontSize
     * @Description: 字号大小 默认12
     */
    public short fontSize() default 12;

    /**
     * @Title: fontName
     * @Description: 字体 默认微软雅黑
     */
    public String fontName() default "微软雅黑";
}

3, export excel utility classes

Tools, the use of technology to capture the reflection properties of the class as well as annotations, you need to have some understanding of reflection.

Tools Direct download excel file, and the problem of Chinese garbled download does not appear, because it has done a appropriate treatment.

package com.poi.util;

import com.poi.annotation.ExcelColumn;
import org.apache.poi.hssf.usermodel.HSSFBorderFormatting;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Iterator;
import java.util.List;

/**
 * excel导出工具类
 */
@SuppressWarnings("all")
public class ExcelExpUtil<T> {

    private Logger log = LoggerFactory.getLogger(ExcelExpUtil.class);//日志记录

    private Class clazz;//导出目标类的Class对象
    private int colNum;//总列数
    private int startRowIndex;//导出内容开始的行号,不包括表头
    private Field[] fields;//所有是属性数组
    private String titleName;//标题内容
    private String[] headerArr;//要合并的表头数组


    private String[] headers;// 列名集合
    private Short[] columnWidth ;// 列宽集合
    private Integer[] alignList ;// 内文样式位置集合,左对齐,居中或右对齐
    private Boolean[] boderList ;// 是否需要边框  集合
    private Integer[] fontColorList;// 字体颜色集合
    private String[] fontNameList ;// 字体集合
    private Short[] fontSizeList;// 字号集合
    private Integer[] styleColorList ;// 单元格背景色  集合
    private Field[] excelFileds ;//存放有注解的字段  也就是需要导出的字段  无注解字段排除

    /**
     * 没有合并表头的构造方法
     * @param clazz         导出类的CLass对象,通过它来反射获取对应的属性和注解
     * @param titleName     标题名称
     * @param colNum        总列数,在导出之前我们应该已经知道总共的列数了
     * @param startRowIndex 导出内容开始的行号,不包括表头
     */
    public ExcelExpUtil(Class clazz,String titleName, int colNum, int startRowIndex){
        this.clazz=clazz;
        this.titleName = titleName;
        this.colNum = colNum;
        this.startRowIndex = startRowIndex-1;//从0开始的,所以减1
        this.fields = clazz.getDeclaredFields();//通过发射获取类的所有属性,包括私有属性
        this.headers = new String[colNum];
        this.columnWidth = new Short[colNum];
        this.alignList = new Integer[colNum];
        this.boderList = new Boolean[colNum];
        this.fontColorList = new Integer[colNum];
        this.fontNameList = new String[colNum];
        this.fontSizeList = new Short[colNum];
        this.styleColorList = new Integer[colNum];
        this.excelFileds = new Field[colNum];
    }

    /**
     * 有一行合并表头的构造方法
     * @param clazz         导出类的CLass对象
     * @param titleName     标题名称
     * @param colNum        总列数
     * @param startRowIndex 导出内容开始的行号,不包括表头
     * @param headerArr     要合并的表头数组
     */
    public ExcelExpUtil(Class clazz,String titleName, int colNum, int startRowIndex,String[] headerArr){
        this(clazz,titleName,colNum,startRowIndex);//调用另一个构造方法
        this.headerArr = headerArr;
    }

    /**
     * 导出excel的方法
     * @param dataList   导出的业务数据
     * @param response   浏览器下载的流
     * @param fileName   导出的文件名
     * @param ext        导出的文件的扩展名,.xls  .xlsx
     */
    public void excelExp(List<T> dataList,HttpServletRequest request, HttpServletResponse response, String fileName, String ext){
        //根据后缀名得到工作簿对象
        Workbook workbook = getWorkBook(ext);
        if(workbook != null){
            creatSheet(workbook, dataList);//创建sheet页
            //下载文件
            this.downloadFile(workbook,request,response,fileName,ext);
        }else{
            log.error("创建工作簿失败");
        }
    }

    //创建sheet
    private void creatSheet(Workbook workbook, List<T> dataList) {
        if(dataList==null || dataList.size()<=0){
            return;
        }
        Sheet sheet = workbook.createSheet();//sheet对象
        Row row =null;//行对象
        Cell cell = null;//列对象
        ExcelColumn excelColumn = null;
        int j=0;//相当于是列号,从0开始的
        for(short i = 0; i < fields.length; i++){//遍历属性的集合,得到有注解的属性的集合
            Field field = fields[i];//得到属性
            //判断属性上面是否有注解:ExcelColumn
            if(field.isAnnotationPresent(ExcelColumn.class)){
                excelColumn = (ExcelColumn)field.getAnnotation(ExcelColumn.class);//通过属性获取指定的注解信息
                j = excelColumn.sort()-1;//属性上注解的列号是从1开始的,其实poi中的列号是从0开始的,所以这里减1

                excelFileds[j] = field;//放入到要导出字段的集合中
                headers[j] = excelColumn.title();//把列名放入到列名集合中
                columnWidth[j]=excelColumn.width();//把宽度放入到宽度集合中
                alignList[j]=excelColumn.alignment().getValue();
                boderList[j]=excelColumn.boder();
                fontColorList[j]=excelColumn.fontColor().getValue();
                fontNameList[j]=excelColumn.fontName();
                fontSizeList[j]=excelColumn.fontSize();
                styleColorList[j]=excelColumn.styleColor().getValue();
            }
        }

        // 循环设置列宽
        int length = columnWidth.length;
        for (int i = 0; i < length; i++) {
            sheet.setColumnWidth(i, columnWidth[i] * 256);
        }

        // 产生表格标题行,标题行是第一行
        this.createTitle(workbook,sheet,row);

        // 合并表头行设置
        if(this.headerArr!=null){
            this.createHeBinHeader(workbook,sheet,row,cell);
        }

        //生成表头行,用的header中的数据
        this.createHeader(workbook,sheet,row,cell);

        // 遍历集合数据,产生数据行
        this.setDataToSheet(workbook,sheet,row,cell,dataList);
    }

    //根据表头数组信息合并行
    private void createHeBinHeader(Workbook workbook, Sheet sheet, Row row, Cell cell) {
        row = sheet.createRow(1);//第二行是合并表头的行,行号为1
        row.setHeightInPoints(25);//设置行高
        CellStyle boderStyle = workbook.createCellStyle();//创建一个样式
        Font font = workbook.createFont();// 生成一个字体 默认字体微软雅黑
        font.setFontHeightInPoints((short)20);// 设置字体大小
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);//字体加粗
        boderStyle.setFont(font);// 把字体应用到当前的样式

        //设置边框
        //boderStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        /*boderStyle.setBorderBottom(CellStyle.BORDER_THIN);
        boderStyle.setBorderLeft(CellStyle.BORDER_THIN);
        boderStyle.setBorderRight(CellStyle.BORDER_THIN);
        boderStyle.setBorderTop(CellStyle.BORDER_THIN);*/
        //垂直居中
        boderStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        boderStyle.setAlignment(CellStyle.ALIGN_CENTER); // 创建一个居中格式

        String[] zuoBiaoArr = null;
        int colIndex = 0;//列起始行号
        for(int i = 0; i<headerArr.length;i++){
            String[] valueArr = headerArr[i].split("#");
            String cellValue = valueArr[0];//单元格内容
            String zuoBiaoStr = valueArr[1];
            zuoBiaoArr = zuoBiaoStr.split(",");

            colIndex=this.colNum-(this.colNum-Integer.parseInt(zuoBiaoArr[3]))-1;
            cell = row.createCell(colIndex);//得到列
            cell.setCellStyle(boderStyle);//设置样式
            cell.setCellValue(cellValue);//设置内容
            sheet.addMergedRegion(new CellRangeAddress(Integer.parseInt(zuoBiaoArr[0]),
                    Integer.parseInt(zuoBiaoArr[1]), Integer.parseInt(zuoBiaoArr[2]), Integer.parseInt(zuoBiaoArr[3])));//设置合并
            //colIndex += Integer.parseInt(zuoBiaoArr[3])+1;//第二列的开始列号
        }
    }

    /**
     * 循环遍历,把数据设置到表格中的方法
     * @param workbook      工作簿
     * @param row           行对象
     * @param cell          单元格对象
     * @param sheet         sheet对象
     * @param dataList      数据集合
     * @param alignList     对齐方式集合
     * @param boderList     是否边框的集合
     * @param fontColorList 字体颜色的集合
     * @param fontNameList  字体名称的集合
     * @param fontSizeList  字体大小的集合
     * @param styleColorList 背景颜色的集合
     * @param excelFileds   需要导出的列 集合
     */
    private void setDataToSheet(Workbook workbook, Sheet sheet, Row row,Cell cell, List<T> dataList) {
        Iterator<T> it = dataList.iterator();
        while (it.hasNext()) {
            row = sheet.createRow(startRowIndex++);//从第几行开始
            T t = (T) it.next();
            // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
            for (int i = 0; i < excelFileds.length; i++) {
                cell = row.createCell(i);
                Field field = excelFileds[i];//获取属性
                field.setAccessible(true);//忽略检查,不加这个写入不了数据
                //调用方法进行样式设置
                this.setCellStyle(workbook, cell, alignList[i], boderList[i],styleColorList[i],
                                    fontColorList[i],  fontNameList[i],fontSizeList[i],false);
                String fieldName = field.getName();//得到属性名称
                //得到属性的get方法名称
                String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                try {
                    cell.setCellValue(field.get(t).toString());

                    //另外一种手动拼get方法的方式获取值
                    //得到对应的方法
                    /*Method getMethod = this.clazz.getMethod(getMethodName, new Class[] {});
                    //执行方法,得到返回值
                    Object value = getMethod.invoke(t, new Object[] {});
                    String textValue = value.toString();
                    if (textValue != null) {
                        RichTextString richString = new HSSFRichTextString(textValue);
                        cell.setCellValue(richString);
                    }*/
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //生成表头行
    private void createHeader(Workbook workbook, Sheet sheet,Row row,Cell cell) {
        row = sheet.createRow(this.startRowIndex-1);//内容开始行的上一行是表头行
        for (int i = 0; i < headers.length; i++) {
            cell = row.createCell(i);
            //调用方法设置样式
            this.setCellStyle(workbook, cell, alignList[i], boderList[i],styleColorList[i], fontColorList[i],  fontNameList[i],fontSizeList[i],true);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);//获取该列的值
            cell.setCellValue(text);//把值设置到单元格中
        }
    }

    /**
     * 创建标题行的方法
     * @param workbook
     * @param sheet
     * @param row
     */
    private void createTitle(Workbook workbook,Sheet sheet,Row row){
        row = sheet.createRow(0);//标题行
        row.setHeightInPoints(50);//设置行高
        Cell titleCell = row.createCell(0);//得到标题列

        CellStyle cellStyle = workbook.createCellStyle();
        // 生成一个字体 默认字体微软雅黑
        Font font = workbook.createFont();
        // 设置字体大小
        font.setFontHeightInPoints((short)30);
        // 字体加粗
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
        // 把字体应用到当前的样式
        cellStyle.setFont(font);

        //垂直居中
        cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        cellStyle.setAlignment(CellStyle.ALIGN_CENTER); // 创建一个居中格式
        titleCell.setCellStyle(cellStyle);//设置样式

        titleCell.setCellValue(this.titleName);//设置内容
        sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(),
                row.getRowNum(), row.getRowNum(), this.colNum-1));//设置合并
    }

    /**
     * @Title: 设置单元格样式的方法
     * @param workbook   工作簿
     * @param cell       要配置的单元格
     * @param alignment  单元格内文样式
     * @param needBoder  是否需要环绕边框
     * @param sytleColor 单元格背景色
     * @param fontColor  文字颜色
     * @param fontName   字体
     * @param fontSize   字号
     * @param isBold     表头是否加粗
     * @Description: 设置单元格以及字体的整体样式
     */
    private void setCellStyle(Workbook workbook, Cell cell, int alignment, Boolean needBoder, int sytleColor,int fontColor,
                              String fontName,short fontSize,boolean isBold) {
        // 生成一个通用样式 默认背景为白色
        CellStyle style = workbook.createCellStyle();
        style.setFillForegroundColor((short)sytleColor);

        // 单元格内容样式
        style.setAlignment((short) alignment);

        // 单元格是否需要边框
        if (needBoder) {
            style.setFillPattern(CellStyle.SOLID_FOREGROUND);
            style.setBorderBottom(CellStyle.BORDER_THIN);
            style.setBorderLeft(CellStyle.BORDER_THIN);
            style.setBorderRight(CellStyle.BORDER_THIN);
            style.setBorderTop(CellStyle.BORDER_THIN);
        }

        // 生成一个字体 默认字体微软雅黑
        Font font = workbook.createFont();
        font.setFontName(fontName);
        font.setColor((short) fontColor);

        // 设置字体大小
        font.setFontHeightInPoints(fontSize);

        // 字体是否加粗
        if (isBold) {
            font.setBoldweight(Font.BOLDWEIGHT_BOLD);
        }

        // 把字体应用到当前的样式
        style.setFont(font);
        cell.setCellStyle(style);
    }

    //根据后缀名得到工作簿对象
    private Workbook getWorkBook(String ext){

        if(".xls".equals(ext)){
            return new HSSFWorkbook();
        }
        if(".xlsx".equals(ext)){
            return new SXSSFWorkbook();
        }
        log.error("扩展名只能为【.xls】或【.xlsx】");
        return null;
    }

    /**
     * 文件下载的方法
     * @param workbook  工作簿
     * @param request   请求
     * @param response  响应
     * @param filename  文件名称
     * @param ext       文件扩展名
     */
    private void downloadFile(Workbook workbook,HttpServletRequest request, HttpServletResponse response,String filename,String ext){
        filename = filename+ext;//文件名+扩展名
        //调用其他下载方法
        downloadFile(workbook,request,response,filename);
    }

    private void downloadFile(Workbook workbook,HttpServletRequest request, HttpServletResponse response,String filename){
        try {
            //从请求头中获取User-Agent判断当前使用的是否是火狐浏览器
            String agent = request.getHeader("User-Agent");
            //根据不同浏览器进行不同的编码
            String realFilename = "";
            if (agent.contains("MSIE")) {
                // IE浏览器
                realFilename = URLEncoder.encode(filename, "utf-8");
                realFilename = realFilename.replace("+", " ");
            } else if (agent.contains("Firefox")) {
                // 火狐浏览器,此处使用java8
                realFilename = "=?utf-8?B?" + Base64.getEncoder().encodeToString(filename.getBytes("utf-8")) + "?=";
            } else {
                // 其它浏览器
                realFilename = URLEncoder.encode(filename, "utf-8");
            }
            //设置要被下载的文件名
            response.setHeader("Content-Disposition","attachment;filename="+realFilename);
            response.setContentType("application/octet-stream");
            response.setHeader("filename", filename);
            workbook.write(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4, test Export

4.1 add annotations in the Java classes

package com.poi.pojo;

import com.poi.annotation.ExcelColumn;

import java.util.Date;

public class User {
    //如果这个属性需要导出,那么就在上面添加注解信息
    @ExcelColumn(title = "姓名",width = 20,alignment = ExcelColumn.Alignment.CENTER,sort=2)
    private String name;
    @ExcelColumn(title = "用户ID",width = 10,alignment = ExcelColumn.Alignment.LEFT,styleColor = ExcelColumn.StyleColor.RED,sort=1)
    private String id;

    @ExcelColumn(title = "年龄",width = 10,alignment = ExcelColumn.Alignment.CENTER,sort=4)
    private int age;
    //@ExcelColumn(title = "出生日期",width = 20,alignment = ExcelColumn.Alignment.LEFT,sort=4)
    private Date birthday;
    @ExcelColumn(title = "家庭住址",width = 50,alignment = ExcelColumn.Alignment.LEFT,fontColor = ExcelColumn.FontColor.BLUE,sort=5)
    private String address;
    @ExcelColumn(title = "身高",width = 10,alignment = ExcelColumn.Alignment.CENTER,sort=3)
    private double high;

    public User() {
    }

    public User(String id, String name, int age, Date birthday, String address, double high) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.birthday = birthday;
        this.address = address;
        this.high = high;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public double getHigh() {
        return high;
    }

    public void setHigh(double high) {
        this.high = high;
    }
}

4.2 Creating Controller

package com.poi.controller;

import com.poi.pojo.User;
import com.poi.util.ExcelExpUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("/excel")
public class UserExcelController {

    @RequestMapping("/userList")
    public void expUserList(HttpServletRequest request,HttpServletResponse response){
        //查询业务数据,实际工程中应该是从数据库中查询的
        List<User> userList = this.getDataList();

        //调用工具类方法进行导出
        new ExcelExpUtil(User.class,"用户列表",5,3)
                .excelExp(userList,request,response,"用户列表",".xlsx");
    }

    private List<User> getDataList() {

        List<User> userList = new ArrayList<>();
        User user1 = new User("1001","老庞",38,new Date(System.currentTimeMillis()-1000*60*60*24*365),"湖南省长沙市岳麓区岳麓书院1",180.5);
        User user2 = new User("1002","老王",38,new Date(System.currentTimeMillis()-1000*60*60*24),"湖南省长沙市岳麓区岳麓书院2",170.5);
        User user3 = new User("1003","老李",38,new Date(System.currentTimeMillis()-1000*60*60*24*365*2),"湖南省长沙市岳麓区岳麓书院3",160.5);
        User user4 = new User("1004","老周",38,new Date(System.currentTimeMillis()-1000*60*60*24*365*10),"湖南省长沙市岳麓区岳麓书院4",190.5);
        User user5 = new User("1005","老赵",38,new Date(System.currentTimeMillis()-1000*60*60*24*365*20),"湖南省长沙市岳麓区岳麓书院5",150.5);
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);
        userList.add(user5);

        return userList;
    }
}

4.3 Effects

Start project, visit: http://127.0.0.1:9000/excel/userList can download the excel file, open the downloaded effect after the following:

 

5, tested for incorporation of a header

5.1, create a new test java object

package com.poi.pojo;

import com.poi.annotation.ExcelColumn;

public class Dog {
    @ExcelColumn(title = "宠物ID",sort = 2,width = 10)
    private int id;
    @ExcelColumn(title = "宠物名称",sort = 1,width = 20)
    private String name;
    @ExcelColumn(title = "宠物的颜色",sort = 3,width = 20)
    private String color;
    @ExcelColumn(title = "宠物主人ID",sort = 5,width = 10)
    private String userId;
    @ExcelColumn(title = "宠物喜欢吃的食物",sort = 4,width = 30)
    private String eat;
    @ExcelColumn(title = "宠物主人名称",sort = 6,width = 20)
    private String userName;


    public Dog(int id, String name, String color,String eat, String userId, String userName) {
        this.id = id;
        this.name = name;
        this.color = color;
        this.eat = eat;
        this.userId = userId;
        this.userName = userName;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getEat() {
        return eat;
    }

    public void setEat(String eat) {
        this.eat = eat;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

5.2 Creating the Controller

package com.poi.controller;

import com.poi.pojo.Dog;
import com.poi.util.ExcelExpUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping("/excel")
public class DogController {

    @RequestMapping("/dogList")
    public void excelExport(HttpServletRequest request, HttpServletResponse response){

        //构造合并的表头行信息
        String[] headerArr = new String[3];
        headerArr[0] = "宠物信息1#1,1,0,1";
        headerArr[1] = "宠物信息2#1,1,2,3";
        headerArr[2] = "主人信息#1,1,4,5";

        List<Dog> dogList = new ArrayList<>();
        Dog dog1 = new Dog(1,"小坏猫咪","五颜六色的好好看","就是喜欢吃死老鼠","1001","老庞");
        Dog dog2 = new Dog(1,"小乖兔兔","纯白纯白的好漂亮","就是喜欢吃胡萝卜","1001","老庞");
        dogList.add(dog1);
        dogList.add(dog2);
        //这里调用的是可以合并表头的构造方法
        new ExcelExpUtil(Dog.class,"宠物列表",6,4,headerArr)
                .excelExp(dogList,request,response,"宠物列表",".xlsx");
    }
}

5.3 Export results View

Run the project, request: http://127.0.0.1:9000/excel/dogList , the effect is as follows:

 

发布了81 篇原创文章 · 获赞 15 · 访问量 2万+

Guess you like

Origin blog.csdn.net/zengdongwen/article/details/103933066