欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java导出多sheet的Excel表格

程序员文章站 2022-07-13 12:58:21
...

导出表格代码做备份

Poi导出到Excel表格

主要maven的jar包

 <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>2.5.6</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version> 3.10-FINAL</version>
        </dependency>

主要代码

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class PoiExcelExport {

    /**
     * 每一个sheet能存放多少数据
     */
    private final int MAX_ROW;
    /**
     * 存放文件的位置
     */
    private final String TEMP_PATH;
    /**
     * 文件名称
     */
    private final String FILE_NAME;
    /**
     * 文件名称
     */
    private String sheetName;

    /**
     * 每次查询完数据库的list长度都是100,该变量统计每次list的size
     */
    private int amout = 0;
    /**
     * sheet表头
     */
    private Set<String> columnTitle;
    /**
     * 确保每个sheet名称都不一样
     */
    private AtomicInteger count = new AtomicInteger();

    public PoiExcelExport() {
        this(6000, "D:/tmp/excel/", UUID.randomUUID().toString());
    }

    public PoiExcelExport(int max_row) {
        this(max_row, "D:/tmp/excel/", UUID.randomUUID().toString(), "sheet");
    }

    public PoiExcelExport(int max_row, String temp_path, String file_name) {
        this(max_row, temp_path, file_name, "sheet");
    }

    /**
     * @param max_row   每一个sheet能存放多少数据
     * @param temp_path 存放文件的位置
     * @param file_name 文件名
     */
    public PoiExcelExport(int max_row, String temp_path, String file_name, String sheetName) {
        MAX_ROW = max_row;
        TEMP_PATH = temp_path;
        FILE_NAME = file_name;
        this.sheetName = sheetName;
    }

    /**
     * @param wb 新建SXSSFWorkbook导出对象
     */
    public void createFile(SXSSFWorkbook wb) {

        File excelFile = new File(TEMP_PATH);
        if (!excelFile.exists()) {
            excelFile.mkdirs();
        }
        String excelPath = TEMP_PATH + FILE_NAME;
        excelPath = excelPath + ".xlsx";
        excelFile = new File(excelPath);
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(excelFile);
            wb.write(fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (Exception e) {
            throw new RuntimeException("生成excel文件时出现异常");
        }
    }


    /**
     * @param list       数据
     * @param wb         SXSSFWorkbook对象
     * @param isNewSheet 是否是新的sheet,如果是就用新的sheet名
     * @param row        从第几行开始写
     * @throws IOException
     */
    public void textExport(List<Map<String, Object>> list, SXSSFWorkbook wb,
                           boolean isNewSheet, int row) throws IOException {
        // 设置sheet的表头
        if (this.getColumnTitle() == null) {
            this.setColumnTitle(list.get(0).keySet());
        }

        String sheetName = isNewSheet ? this.sheetName + count.incrementAndGet() : this.sheetName + count.get();
        SXSSFSheet sheet;
        if (isNewSheet) {
            //根据sheetName,新建sheet页
            sheet = (SXSSFSheet) wb.createSheet(sheetName);
            //设置表头
            Row headRow = sheet.createRow(0);
            int i = 0;
            for (String title : this.getColumnTitle()) {
                // 写入标题
                Cell cell = headRow.createCell(i++);
                cell.setCellValue(title);
            }
        } else {
            sheet = (SXSSFSheet) wb.getSheet(sheetName);
        }
        //设置默认宽度sheet.setDefaultColumnWidth(20);
        //设置具体内容
        for (Map<String, Object> dataMap : list) {
            // 创建新行
            SXSSFRow dataRow = (SXSSFRow) sheet.createRow(row++);
            Set<String> keys = dataMap.keySet();
            // 设置第 i 个列的数据
            int i = 0;
            for (String key : keys) {
                // 创建列,创建完之后自增 1,下一次循环创建下一列
                Cell cell1 = dataRow.createCell(i);
                Object o = dataMap.get(key);
                // 判读是否为空
                if (StringUtils.isNotBlank(String.valueOf(o))) {
                    // 如果是日期就格式化输出
                    String data = o instanceof Date ? formatDate(o) : String.valueOf(o);
                    // 设置表格宽度 +2 是为了比字符串更长一点,空出一点
                    sheet.setColumnWidth(i, (data.length() + 2) * 256);
                    // 写到表格里
                    cell1.setCellValue(data);
                } else {
                    cell1.setCellValue("");
                }
                i++;
            }

            // 将数据刷新到磁盘
            if (this.getAmout() % 1000 == 0) {
                sheet.flushRows();
            }
        }

        // 设置到此刻位置一共有多少条数据
        this.setAmout(this.getAmout() + list.size());

    }

    /**
     * 格式化日期
     *
     * @param val
     * @return
     */
    private String formatDate(Object val) {
        return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format((Date) val);
    }


    public int getMAX_ROW() {
        return MAX_ROW;
    }

    public String getTEMP_PATH() {
        return TEMP_PATH;
    }

    public String getFILE_NAME() {
        return FILE_NAME;
    }

    public String getSheetName() {
        return sheetName;
    }

    public int getAmout() {
        return amout;
    }

    public AtomicInteger getCount() {
        return count;
    }

    public void setColumnTitle(Set<String> columnTitle) {
        this.columnTitle = columnTitle;
    }

    public Set<String> getColumnTitle() {
        return columnTitle;
    }

    public void setAmout(int amout) {
        this.amout = amout;
    }
}

Test类

import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.IOException;
import java.util.*;

public class Test {


    public static void main(String[] args) throws IOException {
        // 模拟数据库查数据多少次。
        int end = 1;
        // 判断第二次写数据从多少行开始写
        int startNum = 0;
        // 存放数据的list
        List<Map<String, Object>> list = new ArrayList();
        //新建SXSSFWorkbook导出对象并设置每1000条刷新数据到硬盘,大数据导出时防止内存溢出
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        // 新建导出对象,可以自定义名字和位置和sheet名字
        PoiExcelExport export = new PoiExcelExport();
        // PoiExcelExport export = new PoiExcelExport(6000,"D:/tmp/excel/","测试表格","sheet名字");

        // sheet表头名字,可以自定义,可以用map的key。默认是map的key。
        Set<String> strings = new HashSet<>();
        strings.add("序号");
        strings.add("日期");
        strings.add("数字");
        strings.add("数字1");
        export.setColumnTitle(strings);

        // 模拟循环查询数据库
        while (true) {
            // 设置数据
            list.addAll(LIST_DATA);
            // 当查询五次之后开始向文件里写
            if (list.size() % 500 == 0) {
                if (export.getAmout() % export.getMAX_ROW() == 0) {
                    export.textExport(list, wb, Boolean.TRUE, 1);
                    startNum = 0;
                } else {
                    export.textExport(list, wb, Boolean.FALSE, list.size() * (++startNum) + 1);
                }
                list.clear();
            }
            // 模拟查询完数据库
            if (end == 121) {
                export.textExport(list, wb, Boolean.TRUE, 1);
                list.clear();
                break;
            }
            end++;
        }
        export.createFile(wb);
    }


    

    private static List<Map<String, Object>> LIST_DATA;

    static {
        LIST_DATA = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            Map<String, Object> map = new LinkedHashMap();
            map.put("name", i);
            map.put("date", new Date());
            map.put("key", "2832734897238412131322131231");
            map.put("key1", "2832734897238412131322131231");
            LIST_DATA.add(map);
        }
    }

}