java导出Excel文档,使用POI方式

首先引入依赖


    org.apache.poi
    poi
    4.1.0


    org.apache.poi
    poi-ooxml
    4.1.0

下面是工具类,供参考使用

package cn.stylefeng.guns.core.util;

import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * excel导出工具
 *
 * @author hexm
 * @date 2019/9/5 9:29
 */
public class ExcelExportUtil {
    //sheet各个列的表头
    private String[] headList;
    //各个列的元素key值
    private String[] headKey;
    //sheet需要填充的数据信息
    private List> data;
    //工作表名称
    private String sheetName;
    //字体大小
    private short fontSize = 12;
    //字体加粗
    private boolean bold = false;
    //标题与内容的字体
    private String font = HSSFFont.FONT_ARIAL;
    //内容颜色
    private short color = Font.COLOR_NORMAL;
    //内容背景色
    private Short backgroundColor;
    //标题字体大小
    private short titleFontSize = 13;
    //标题粗体
    private boolean titleBold = true;
    //标题颜色
    private short titleColor = Font.COLOR_NORMAL;
    //标题背景色
    private Short titleBackgroundColor;

    private ExcelExportUtil() {
    }

    public static ExcelExportUtil of(String sheetName, String[] headList, String[] headKey, List> data) {
        ExcelExportUtil util = new ExcelExportUtil();
        util.sheetName = sheetName;
        util.headList = headList;
        util.headKey = headKey;
        util.data = data;
        return util;
    }

    /**
     * 分段性写入Xlsx格式Excel文档到流中
     * 适合大量数据导出使用
     * 在内存中保留{@see rowAccessWindowSize}行,超出行将之前写入的数据写到磁盘临时文件中(C:\Users\Administrator\AppData\Local\Temp)
     * @param os
     * @param rowAccessWindowSize rowAccessWindowsize必须大于0或小于-1
     */
    public void writeXlsxTo(OutputStream os,int rowAccessWindowSize) {
        //创建HSSFWorkbook对象(excel的文档对象)
        SXSSFWorkbook wb = new SXSSFWorkbook(rowAccessWindowSize);
        //建立新的sheet对象(excel的表单)
        SXSSFSheet sheet = wb.createSheet(sheetName);
        //创建表头
        createHead(wb, sheet);
        //跟踪所有列以调整大小
        sheet.trackAllColumnsForAutoSizing();
        //创建表体
        createRow(wb, sheet);
        try {
            wb.write(os);
            //删除临时文件
            wb.dispose();
            wb.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 一次性写入Xlsx格式Excel文档到流中。数据将保留到内存中
     *
     * @param os
     */
    public void writeXlsxTo(OutputStream os) {
        //创建HSSFWorkbook对象(excel的文档对象)
        XSSFWorkbook wb = new XSSFWorkbook();
        //建立新的sheet对象(excel的表单)
        XSSFSheet sheet = wb.createSheet(sheetName);
        //创建表头
        createHead(wb, sheet);
        //创建表体
        createRow(wb, sheet);
        try {
            wb.write(os);
            wb.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 一次性写入Xls格式Excel文档到流中
     *
     * @param os
     */
    public void writeXlsTo(OutputStream os) {
        //创建HSSFWorkbook对象(excel的文档对象)
        HSSFWorkbook wb = new HSSFWorkbook();
        //建立新的sheet对象(excel的表单)
        HSSFSheet sheet = wb.createSheet(sheetName);
        //创建表头
        createHead(wb, sheet);
        //创建表体
        createRow(wb, sheet);
        try {
            wb.write(os);
            wb.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建表头
     *
     * @param sheet
     */
    private void createHead(Workbook wb, Sheet sheet) {
        //在sheet里创建第一行,参数为行索引(excel的行),可以是0~65535之间的任何一个
        Row headRow = sheet.createRow(0);

        // 1.生成表头字体对象
        Font headFont = wb.createFont();
        headFont.setFontHeightInPoints(this.titleFontSize);
        headFont.setFontName(this.font);
        headFont.setBold(this.titleBold);
        headFont.setColor(this.titleColor);
        // 2.生成样式对象
        CellStyle headStyle = wb.createCellStyle();
        headStyle.setFont(headFont); // 调用字体样式对象
        headStyle.setWrapText(true); // 是否自动换行
        if (titleBackgroundColor != null){
            headStyle.setFillForegroundColor(titleBackgroundColor);
            headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        }
        headStyle.setAlignment(HorizontalAlignment.CENTER);//设置居中样式
        headStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        for (int i = 0; i < headList.length; i++) {
            //创建单元格(excel的单元格,参数为列索引,可以是0~255之间的任何一个
            Cell cell = headRow.createCell(i);

            // 3.单元格应用样式
            cell.setCellStyle(headStyle);

            //设置单元格内容
            cell.setCellValue(headList[i]);
        }
    }

    /**
     * 创建表体
     *
     * @param wb
     * @param sheet
     */
    private void createRow(Workbook wb, Sheet sheet) {
        // 1.生成表数据字体对象
        Font font = wb.createFont();
        font.setFontHeightInPoints(this.fontSize);
        font.setFontName(this.font);
        font.setBold(bold);
        font.setColor(this.color);
        // 2.生成样式对象
        CellStyle rowStyle = wb.createCellStyle();
        rowStyle.setFont(font); // 调用字体样式对象
        rowStyle.setWrapText(true); // 是否自动换行
        if (backgroundColor != null){
            rowStyle.setFillForegroundColor(backgroundColor);
            rowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        }
        rowStyle.setAlignment(HorizontalAlignment.CENTER);//设置居中样式
        rowStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        //填充数据
        for (int i = 0; i < data.size(); i++) {
            //在sheet里创建第二行,参数为行索引(excel的行),可以是0~65535之间的任何一个
            Row row = sheet.createRow(i + 1);
            Map rowData = data.get(i);
            for (int z = 0; z < headKey.length; z++) {
                //创建单元格(excel的单元格,参数为列索引,可以是0~255之间的任何一个
                Cell cell = row.createCell(z);

                // 3.单元格应用样式
                cell.setCellStyle(rowStyle);

                String value;

                Object valueObject = rowData.get(headKey[z]);

                if (valueObject == null) {
                    value = "";
                } else if (valueObject instanceof String) {
                    //取出的数据是字符串直接赋值
                    value = (String) valueObject;
                } else if (valueObject instanceof Integer) {
                    //取出的数据是Integer
                    value = String.valueOf(((Integer) (valueObject)).floatValue());
                } else if (valueObject instanceof BigDecimal) {
                    //取出的数据是BigDecimal
                    value = String.valueOf(((BigDecimal) (valueObject)).floatValue());
                } else {
                    value = valueObject.toString();
                }

                //设置单元格内容
                cell.setCellValue(value);
            }
        }
        for (int i = 0; i < headKey.length; i++) {
            //宽度自适应
            sheet.autoSizeColumn(i);
        }
    }

    public ExcelExportUtil setFontSize(short fontSize) {
        this.fontSize = fontSize;
        return this;
    }

    public ExcelExportUtil setBold(boolean bold) {
        this.bold = bold;
        return this;
    }

    public ExcelExportUtil setFont(String font) {
        this.font = font;
        return this;
    }

    public ExcelExportUtil setTitleFontSize(short titleFontSize) {
        this.titleFontSize = titleFontSize;
        return this;
    }

    public ExcelExportUtil setColor(short color) {
        this.color = color;
        return this;
    }

    public ExcelExportUtil setTitleBold(boolean titleBold) {
        this.titleBold = titleBold;
        return this;
    }

    public ExcelExportUtil setTitleColor(short titleColor) {
        this.titleColor = titleColor;
        return this;
    }

    public ExcelExportUtil setBackgroundColor(short backgroundColor) {
        this.backgroundColor = backgroundColor;
        return this;
    }

    public ExcelExportUtil setTitleBackgroundColor(short titleBackgroundColor) {
        this.titleBackgroundColor = titleBackgroundColor;
        return this;
    }
}

调用代码示例:

/**
 * 导出excel
 *
 * @param ids
 * @return
 * @throws IOException
 */
@RequestMapping("/exportExcel")
public void exportExcel(String ids, HttpServletResponse response) throws IOException {
    if (StringUtils.isNotEmpty(ids)) {
        List idList = Arrays.stream(ids.split(",")).map(Integer::parseInt).collect(Collectors.toList());
        String[] head = {"title1", "title2"};
        String[] keys = {"key1", "key2"};
        List> data = service.findList(idList);
        OutputStream os = response.getOutputStream();
        //不缓存
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Expires", "0");
        //内容标识
        response.setContentType("application/vnd.ms-excel");
        String name = String.format("%s(总计-%s).xlsx", DateUtil.getDateFormat(DateUtil.SQL_FORMAT), data.size());
        //下载/另存为时,展示
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
        //需要先设置响应头,然后再写入数据流,不然格式上会有问题
        ExcelExportUtil.of("清单", head, keys, data)
                .setTitleBackgroundColor(HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex())//设置标题背景灰度25%
                .writeXlsxTo(os,1000);//将数据写入到流中,始终保持内存最大1000条数据,防止内存溢出
        os.flush();
        os.close();
    }
}

代码仅供参考,如果业务需支持复杂度更高的,需要自定义修改工具

贴上效果图,不然老是觉得自己没有说服力!

java导出Excel文档,使用POI方式_第1张图片

你可能感兴趣的:(java工具类,java导出excel,poi导出excel)