Java后台导出Excel工具类

本文介绍了一种使用Java后台导出Excel的方法,包括引入Apache POI库,实现Service层业务逻辑,以及创建ExportExcelUtil工具类的过程。文章详细展示了如何通过代码生成Excel文件,设置列头、数据和样式。

Java后台导出Excel工具类,废话不多说,直接上代码。

一、引入Jar包
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.6</version>
</dependency>
二、service层
package com.kelly.stage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kelly.stage.entity.User;
import com.kelly.stage.mapper.UserMapper;
import com.kelly.stage.service.IExportService;
import com.kelly.stage.util.ExportExcelUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * ExportServiceImpl
 *
 * @author Kelly
 * @version v1.0
 * @date 2020/6/26 21:39
 */
@Service
public class ExportServiceImpl implements IExportService {

    @Resource
    private UserMapper userMapper;

    @Override
    public void exportExcel(HttpServletResponse response) {
        {
            //设置表格标题行
            String[] headers = new String[] {"用户名","密码"};

            String title = "用户信息表.xls";
            String[] sheetNames = {"用户信息"};
            List<List<Object[]>> list = new ArrayList<>();

            QueryWrapper<User> query = new QueryWrapper<>();
            List<User> userList = userMapper.selectList(query);
            List<Object[]> dataList = buildOrderExportData(headers.length,userList);
            list.add(dataList);

            if (list != null) {
                //使用流将数据导出
                OutputStream out;
                try {
                    //防止中文乱码
                    response.setContentType("octets/stream");
                    response.setContentType("APPLICATION/OCTET-STREAM");
                    response.setHeader("Content-Disposition", 
                     "attachment;filename=" + URLEncoder.encode(title, "UTF-8"));
                    out = response.getOutputStream();
                    ExportExcelUtil ex = new ExportExcelUtil(title, headers,sheetNames,list);
                    ex.export(out);
                    out.flush();
                    out.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private List<Object[]> buildOrderExportData(int length, List<User> userList) {
        List<Object[]> dataList = new ArrayList<Object[]>();
        for (int i = 0; i < userList.size(); i++) {
            Object[] objs = new Object[length];
            objs[0] = userList.get(i).getName();
            objs[1] = userList.get(i).getPassword();
            dataList.add(objs);
        }
        return dataList;
    }
}
三、ExportExcelUtil类
package com.kelly.stage.util;


import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

/**
 * excel util
 * @author Kelly
 * @version 1.0
 * @date 2020/4/16 14:41
 */
public class ExportExcelUtil {

    private String title;
    /**
     * 导出表的列名
     */
    private String[] rowName ;

    /**
     * sheet页title
     */
    private String[] sheetNames;

    /**
     * Object类型数据代表每一个Cell
     */
    private List<List<Object[]>> dataList;

    /**
     * 构造方法,传入要导出的数据
     */
    public ExportExcelUtil(String title, String[] rowName, String[] sheetNames, List<List<Object[]>> dataList){
        this.dataList = dataList;
        this.rowName = rowName;
        this.sheetNames = sheetNames;
        this.title = title;
    }

    /**
     * 导出数据
     * @param out
     * @throws Exception
     */
    public boolean export(OutputStream out) throws Exception{

        // 创建工作簿对象
        HSSFWorkbook workbook = new HSSFWorkbook();
        try{
            if (sheetNames != null && sheetNames.length > 0) {
                for (int b = 0; b < sheetNames.length; b++) {
                    // 创建工作表
                    HSSFSheet sheet = workbook.createSheet(sheetNames[b]);
                    //sheet样式定义【getColumnTopStyle()/getStyle()均为自定义方法 - 在下面  - 可扩展】
                    //获取列头样式对象
                    HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);
                    //单元格样式对象
                    HSSFCellStyle style = this.getStyle(workbook);

                    //定义所需列数
                    int columnNum = rowName.length;
                    // 在索引2的位置创建行(最顶端的行开始的第二行)
                    HSSFRow rowRowName = sheet.createRow(0);

                    // 将列头设置到sheet的单元格中
                    for(int n=0;n<columnNum;n++){
                        //创建列头对应个数的单元格
                        HSSFCell cellRowName = rowRowName.createCell(n);
                        //设置列头单元格的数据类型
                        cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING);
                        HSSFRichTextString text = new HSSFRichTextString(rowName[n]);
                        //设置列头单元格的值
                        cellRowName.setCellValue(text);
                        //设置列头单元格样式
                        cellRowName.setCellStyle(columnTopStyle);
                    }

                    //将查询出的数据设置到sheet对应的单元格中
                    List<Object[]> objList = dataList.get(b);
                    for(int i = 0;i < objList.size(); i++){
                        //遍历每个对象
                        Object[] obj = objList.get(i);
                        //创建所需的行数(从第二行开始写数据)
                        HSSFRow row = sheet.createRow(i+1);

                        for(int j=0; j<obj.length; j++){
                            //设置单元格的数据类型
                            HSSFCell cell = row.createCell(j,HSSFCell.CELL_TYPE_STRING);
                            //data是否为数值型
                            Boolean isNum = false;
                            //data是否为整数
                            Boolean isInteger=false;
                            if (obj[j] != null && !"".equals(obj[j])) {
                                //判断data是否为数值型
                                isNum = (obj[j].toString().matches("^(-?\\d+)(\\.\\d+)?$") && obj[j].toString().length() < 7);
                                //判断data是否为整数(小数部分是否为0)
                                isInteger = obj[j].toString().matches("^[-\\+]?[\\d]*$");
                            }
                            if (isNum) {
                                // 此处设置数据格式
                                if (isInteger) {
                                    //数据格式只显示整数
                                    style.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,#0"));
                                    if(!"".equals(obj[j]) && obj[j] != null){
                                        //设置单元格的值
                                        cell.setCellValue(Integer.valueOf(obj[j].toString()).intValue());
                                    } else {
                                        cell.setCellValue("");
                                    }
                                } else {
                                    //保留两位小数点
                                   style.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00"));
                                    // 设置单元格内容为double类型
                                    if(!"".equals(obj[j]) && obj[j] != null){
                                        //设置单元格的值
                                        cell.setCellValue(Double.parseDouble(obj[j].toString()));
                                    } else {
                                        cell.setCellValue("");
                                    }
                                }
                                // 设置单元格格式
                                cell.setCellStyle(style);

                            } else {
                                cell.setCellStyle(style);
                                // 设置单元格内容为字符型
                                if(!"".equals(obj[j]) && obj[j] != null){
                                    //设置单元格的值
                                    cell.setCellValue(obj[j].toString());
                                } else {
                                    cell.setCellValue("");
                                }
                            }

                            // 设置序号
//                            if(j == 0){
//                                cell = row.createCell(j,HSSFCell.CELL_TYPE_NUMERIC);
//                                cell.setCellValue(i+1);
//                            }else{
//                                cell = row.createCell(j,HSSFCell.CELL_TYPE_STRING);
//                                if(!"".equals(obj[j]) && obj[j] != null){
//                                    //设置单元格的值
//                                    cell.setCellValue(obj[j].toString());
//                                } else {
//                                    cell.setCellValue("");
//                                }
//                            }
                            //设置单元格样式
//                            cell.setCellStyle(style);
                        }
                    }
                    //让列宽随着导出的列长自动适应
                    for (int colNum = 0; colNum < columnNum; colNum++) {
                        int columnWidth = sheet.getColumnWidth(colNum) / 256;
                        for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
                            HSSFRow currentRow;
                            //当前行未被使用过
                            if (sheet.getRow(rowNum) == null) {
                                currentRow = sheet.createRow(rowNum);
                            } else {
                                currentRow = sheet.getRow(rowNum);
                            }
                            if (currentRow.getCell(colNum) != null) {
                                HSSFCell currentCell = currentRow.getCell(colNum);
                                if (currentCell != null) {
                                    if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                                        int length = 0;
                                        try {
                                            length = currentCell.getStringCellValue().getBytes().length;
                                        } catch (Exception e) {
                                            length = currentCell.getStringCellValue().getBytes().length;
                                            e.printStackTrace();
                                        }
                                        if (columnWidth < length) {
                                            columnWidth = length;
                                        }
                                    }
                                }
                            }
                        }
                        if(colNum == 0){
                            sheet.setColumnWidth(colNum, (columnWidth-2) * 256);
                        }else{
                            sheet.setColumnWidth(colNum, (columnWidth+4) * 256);
                        }
                    }
                }
            }
            if(workbook !=null){
                try{
                    workbook.write(out);
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
        finally{
            out.close();
        }
        return true;
    }

    /**
     * 列头单元格样式
     * @param workbook
     * @return
     */
    public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {
        // 设置字体
        HSSFFont font = workbook.createFont();
        //设置字体大小
        font.setFontHeightInPoints((short)11);
        //字体加粗
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        //设置字体名字
        font.setFontName("Courier New");
        //设置样式;
        HSSFCellStyle style = workbook.createCellStyle();
        //设置底边框;
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        //设置底边框颜色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        //设置左边框;
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        //设置左边框颜色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        //设置右边框;
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        //设置右边框颜色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        //设置顶边框;
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        //设置顶边框颜色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //在样式用应用设置的字体;
        style.setFont(font);
        //设置自动换行;
        style.setWrapText(false);
        //设置水平对齐的样式为居中对齐;
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        //设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        return style;

    }

    /**
     * 列数据信息单元格样式
     * @param workbook
     * @return
     */
    public HSSFCellStyle getStyle(HSSFWorkbook workbook) {
        // 设置字体
        HSSFFont font = workbook.createFont();
        //设置字体名字
        font.setFontName("Courier New");
        //设置样式;
        HSSFCellStyle style = workbook.createCellStyle();
        //设置底边框;
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        //设置底边框颜色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        //设置左边框;
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        //设置左边框颜色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        //设置右边框;
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        //设置右边框颜色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        //设置顶边框;
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        //设置顶边框颜色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //在样式用应用设置的字体;
        style.setFont(font);
        //设置自动换行;
        style.setWrapText(false);
        //设置水平对齐的样式为居中对齐;
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        //设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        return style;
    }
}

去吧,皮卡丘~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值