SpringBoot使用poi实现导出excel

//实体类
//导出的数据的实体
public class User {
    private String id;
    private String name;
    private String year;
    //省略get和set
}
//存放数据实体类
public class ExportEntity<T> implements Serializable {
    Map<String,List<T>> map = new HashMap();

    public Map<String, List<T>> getMap() {
        return map;
    }
    public void setMap(Map<String, List<T>> map) {
        this.map = map;
    }
}
//controller
@Controller
public class UserController {

    @Autowired
    UserService userService;

    @ResponseBody
    @RequestMapping("/export")
    public void export(HttpServletResponse response){
        userService.exportData(response);
    }
}
//service
public interface UserService {
    void exportData(HttpServletResponse response);
}

//实现该方法
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    //导出数据库数据
    @Override
    public void exportData(HttpServletResponse response){
        //存放数据
        Map<String, List<User>> map = new HashMap();
        //根据年份导出数据
        for (int j = 2019; j < 2022 ; j++) {
            String sql = "select * from user where year = '"+j+"'";
            List<User> listData = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
            //key对应年份,value为查出来的数据集合
            map.put(String.valueOf(j),listData);
        }
        ExportEntity<User> export = new ExportEntity();
        export.setMap(map);

        try {
            // excel文件名
            String fileName = "export.xls";
            //字段名称显示在excel第一行
            String[] title = {"主键","名称","年份"};
            //字段备注显示在excel第二行
            String[] mergeCell = {"ID","name","year"};
            //标题要合并几行 没用到
            Integer cellNum = title.length - 1;
            // 创建HSSFWorkbook
            //多个sheet页
            HSSFWorkbook wbMulit = ExportUtil.getHSSFWorkbookMulit(title, export, null,  mergeCell, cellNum);
            //单个sheet页
//            HSSFWorkbook wbSingle = ExportUtil.getHSSFWorkbookSingle(title, export, null,  mergeCell, cellNum);
            // 响应到客户端
            this.setResponseHeader(response, fileName);
            OutputStream os = response.getOutputStream();
            wbMulit.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 发送响应流方法
    public void setResponseHeader(HttpServletResponse response, String fileName) {
        try {
            try {
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            response.setContentType("application/octet-stream;charset=ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
//导出方法
import com.qxj.export.entity.ExportEntity;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ExportUtil {
    /**
     * 导出多个sheet页Excel
     * @param title 标题
     * @param map 内容
     * @param wb HSSFWorkbook对象
     * @return
     */
    public static HSSFWorkbook getHSSFWorkbookMulit(String[] title, ExportEntity<?> map, HSSFWorkbook wb, String[] mergeCell, Integer cellNum ){

        // 第一步,创建一个HSSFWorkbook,对应一个Excel文件
        if(wb == null){
            wb = new HSSFWorkbook();
        }
        String[][] content = new String[0][];
        HSSFSheet sheet = null;
        //获取到参数中的数据
        Map<String, ? extends List<?>> mapData = map.getMap();
        List exportEntities = new ArrayList();
        //将数据存放到集合中 显示多个个sheet页写法 根据年份创建sheet页
        for (int k = 2019; k < 2022; k++) {
            for (int i = k; i < k + 1; i++) {
                if (i < 2022) {
                    for (int j = 0; j < mapData.get(String.valueOf(i)).size(); j++) {
                        exportEntities.add(mapData.get(String.valueOf(i)).get(j));
                    }
                }
            }
            if(exportEntities.size()!=0) {
                //需要导出的数据存入二维数组中
                content = new String[exportEntities.size()][title.length];
                for (int j = 0; j < exportEntities.size(); j++) {
                    //拿到需要导出的对象
                    Object export = exportEntities.get(j);
                    Class exportClass = export.getClass();
                    //通过反射获取属性信息
                    Field[] declaredFields = exportClass.getDeclaredFields();
                    for (int i = 0; i < declaredFields.length; i++) {
                        //获得属性
                        Field field = declaredFields[i];
                        //打开访问
                        field.setAccessible(true);
                        //获取属性名
                        String name = field.getName();
                        String value = null;
                        try {
                            value = (String) field.get(export);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                        content[j][i] = value;
                    }
                }
                // 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet 根据年导出显示多个sheet页
                sheet = wb.createSheet(String.valueOf(k));

                //设置每一列的宽度
                for (int i = 0; i < title.length; i++) {
                    sheet.setColumnWidth(i, 30 * 256);
                }
                //给单元格设置样式以及创建单元格
                style(sheet,wb,mergeCell,title,content);
                exportEntities.clear();//清理数据集合
            }
        }
        return wb;
    }

    /**
     * 导出单个sheet页Excel
     * @param title 标题
     * @param map 内容
     * @param wb HSSFWorkbook对象
     * @return
     */
    public static HSSFWorkbook getHSSFWorkbookSingle(String[] title, ExportEntity<?> map, HSSFWorkbook wb, String[] mergeCell, Integer cellNum ){

        // 第一步,创建一个HSSFWorkbook,对应一个Excel文件
        if(wb == null){
            wb = new HSSFWorkbook();
        }
        String[][] content = new String[0][];
        HSSFSheet sheet = null;
        // 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet 只需要一个sheet页放开
        sheet = wb.createSheet("sheetName");
        //设置每一列的宽度
        for (int i = 0; i < title.length; i++) {
            sheet.setColumnWidth(i, 30 * 256);
        }
        Map<String, ? extends List<?>> mapData = map.getMap();
        List exportEntities = new ArrayList();
        //将数据存放到集合中 显示单个sheet页写法
        for (int k = 2019; k < 2022; k++) {
            for (int i = 0; i < mapData.get(String.valueOf(k)).size(); i++) {
                exportEntities.add(mapData.get(String.valueOf(k)).get(i));
            }
        }
        if(exportEntities.size()!=0) {
            //需要导出的数据存入二维数组中
            content = new String[exportEntities.size()][title.length];
            for (int j = 0; j < exportEntities.size(); j++) {
                Object export = exportEntities.get(j);
                Class exportClass = export.getClass();
                Field[] declaredFields = exportClass.getDeclaredFields();
                for (int i = 0; i < declaredFields.length; i++) {
                    //获得属性
                    Field field = declaredFields[i];
                    //打开访问
                    field.setAccessible(true);
                    //获取属性名
                    String name = field.getName();
                    String value = null;
                    try {
                        value = (String) field.get(export);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    content[j][i] = value;
                }
            }
            //给单元格设置样式以及创建单元格
            style(sheet,wb,mergeCell,title,content);
            exportEntities.clear();//清理数据集合
        }
        return wb;
    }

    //表格样式设置和创建单元格
    private static void style(HSSFSheet sheet, HSSFWorkbook wb, String[] mergeCell, String[] title, String[][] content){
        // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
        HSSFRow row = sheet.createRow(0);
        row.setHeightInPoints(30);//设置高度

        // 第四步,创建单元格,并设置值表头 设置表头居中 //标题的样式
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);//左右居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);//上下居中
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        Font font = wb.createFont();
        font.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());//设置字体颜色
        font.setFontName("黑体");//设置字体
        font.setFontHeightInPoints((short) 16);//设置字体大小
        style.setFont(font);
        //数据的样式
        HSSFCellStyle styleData = wb.createCellStyle();
        styleData.setWrapText(true);//设置自动换行
        styleData.setAlignment(HorizontalAlignment.CENTER);//左右居中
        styleData.setVerticalAlignment(VerticalAlignment.CENTER);//上下居中
        styleData.setBorderBottom(BorderStyle.THIN);
        styleData.setBorderLeft(BorderStyle.THIN);
        styleData.setBorderRight(BorderStyle.THIN);
        styleData.setBorderTop(BorderStyle.THIN);

        //声明列对象
        HSSFCell cell = null;
        for (int i = 0; i < mergeCell.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(mergeCell[i]);
            cell.setCellStyle(style);
        }
        //创建标题那一行
        HSSFRow rowTitle = sheet.createRow(1);
        //创建标题
        for (int i = 0; i < title.length; i++) {
            cell = rowTitle.createCell(i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(style);
        }

        //创建内容
        for (int i = 0; i < content.length; i++) {
            row = sheet.createRow(i + 2);
            for (int j = 0; j < content[i].length; j++) {
                //将内容按顺序赋给对应的列对象
                cell = row.createCell(j);
                cell.setCellValue(content[i][j]);
                cell.setCellStyle(styleData);
            }
        }
    }
}
//配置文件
#mysql
#DB
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/数据库名称
spring.datasource.username=root
spring.datasource.password=root
#JPA
spring.jpa.database=mysql
spring.jpa.show-sql=true
#port
server.port=8088
//依赖
        <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>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/oracle/oracle-jdbc -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.4.0-atlassian-hosted</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
//表结构
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `year` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;
posted @ 2022-03-24 17:55  橙香五花肉  阅读(89)  评论(0编辑  收藏  举报