POI导出数据到Excel

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rhx_1989/article/details/88424905

1.poi封装类

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * excel下载公共类
 */
public class OutExcelUtil {
    /**
     * @param sheetName 工作表名称
     * @param titles 数据表 标题
     * @param values 数据
     * @param wb
     * @param style 单元格样式
     * @return
     */
    public static HSSFWorkbook getHSSFWorkbook(String sheetName, List<String> titles, Object values[][],
                                               HSSFWorkbook wb, HSSFCellStyle style,int width){
        //1 创建webbook对象,对应一个excel文件对象
        if(wb == null) wb = new HSSFWorkbook();
        //2 在wb中添加一个sheet,对应excel中的sheet
        HSSFSheet sheet = wb.createSheet(sheetName);
        //3 在sheet中添加标题行,第一行从0开始
        HSSFRow row = sheet.createRow(0);
        //创建excel的单元格
        HSSFCell cell = null;
        //循环title,创建标题
        for(int i=0; i<titles.size(); i++){
            sheet.setColumnWidth(i, setColumnWidth(width));
            cell = row.createCell(i);
            cell.setCellValue(titles.get(i));
            cell.setCellStyle(style);
        }

        //循环创建内容
        HSSFCellStyle nextStyle = setHSSCellStyle(wb);
        for(int i=0; i<values.length; i++){
            row = sheet.createRow(i+1);//+1表示从第二行开始
            for(int j=0; j<values[i].length; j++){
                Object obj = values[i][j];
                //设置单元格样式
                HSSFCell cellNext = row.createCell(j);
                cellNext.setCellStyle(nextStyle);
                setCellValue(obj,cellNext,sheet,i,j);
            }
        }
        return wb;
    }

    public static synchronized void getMergedHSSFWorkbook(HSSFCellStyle nextStyle,HSSFSheet sheet,Object values[][],int dataRow){
        HSSFRow row = null;
        //循环创建内容
        for(int i=0; i<values.length; i++){
            row = sheet.createRow(i+dataRow);//数据开始行
            for(int j=0; j<values[i].length; j++){
                Object obj = values[i][j];
                //设置单元格样式
                HSSFCell cellNext = row.createCell(j);
                cellNext.setCellStyle(nextStyle);
                setCellValue(obj,cellNext,sheet,i,j);
            }
        }
    }

    public static XSSFWorkbook getXSSFWorkbook(String sheetName, List<String> titles, Object values[][],
                                               XSSFWorkbook wb, HSSFCellStyle style, int width){
        //1 创建webbook对象,对应一个excel文件对象
        if(wb == null) wb = new XSSFWorkbook();
        //2 在wb中添加一个sheet,对应excel中的sheet
        XSSFSheet sheet = wb.createSheet(sheetName);
        //3 在sheet中添加标题行,第一行从0开始
        XSSFRow row = sheet.createRow(0);
        //创建excel的单元格
        XSSFCell cell = null;
        //循环title,创建标题
        for(int i=0; i<titles.size(); i++){
            sheet.setColumnWidth(i, setColumnWidth(width));
            cell = row.createCell(i);
            cell.setCellValue(titles.get(i));
            cell.setCellStyle(style);
        }

        //循环创建内容
        XSSFCellStyle nextStyle = setXSSCellStyle(wb);
        for(int i=0; i<values.length; i++){
            row = sheet.createRow(i+1);//+1表示从第二行开始
            for(int j=0; j<values[i].length; j++){
                Object obj = values[i][j];
                //设置单元格样式
                XSSFCell cellNext = row.createCell(j);
                cellNext.setCellStyle(nextStyle);
                if(obj != null){
                    if(obj instanceof String){
                        cellNext.setCellValue(obj.toString());
                    } else if (obj instanceof Date) {
                        cellNext.setCellValue((Date) obj);
                    } else if (obj instanceof Integer) {
                        cellNext.setCellValue(((Integer) obj).intValue());
                    } else if (obj instanceof Double) {
                        cellNext.setCellValue(((Double) obj).doubleValue());
                    } else if (obj instanceof Float) {
                        cellNext.setCellValue(((Float) obj).floatValue());
                    } else if (obj instanceof BigDecimal) {
                        cellNext.setCellValue(((BigDecimal) obj).floatValue());
                    } else if (obj instanceof Long) {
                        cellNext.setCellValue(((Long) obj).longValue());
                    } else if (obj instanceof Boolean) {
                        cellNext.setCellValue(((Boolean) obj).booleanValue());
                    } else {
                        cellNext.setCellValue(obj.toString());
                    }
                }else {
                    cellNext.setCellValue("");
                }
            }
        }
        return wb;
    }

    public static void setCellValue(Object obj,HSSFCell cellNext,HSSFSheet sheet,
                                    int i,int j){
        if(obj != null){
            if(obj instanceof String){
                cellNext.setCellValue(new HSSFRichTextString(obj.toString()));
            } else if (obj instanceof Date) {
                cellNext.setCellValue((Date) obj);
            } else if (obj instanceof Integer) {
                cellNext.setCellValue(((Integer) obj).intValue());
            } else if (obj instanceof Double) {
                cellNext.setCellValue(((Double) obj).doubleValue());
            } else if (obj instanceof Float) {
                cellNext.setCellValue(((Float) obj).floatValue());
            } else if (obj instanceof BigDecimal) {
                cellNext.setCellValue(((BigDecimal) obj).floatValue());
            } else if (obj instanceof Long) {
                cellNext.setCellValue(((Long) obj).longValue());
            } else if (obj instanceof Boolean) {
                cellNext.setCellValue(((Boolean) obj).booleanValue());
            } else if(obj.getClass().isArray()){
                // 设置第一列的1-10行为下拉列表
                CellRangeAddressList regions = new CellRangeAddressList(i+1, i+1, j, j);
                // 创建下拉列表数据
                String[] arr = (String[]) obj;
                DVConstraint constraint = DVConstraint.createExplicitListConstraint(arr);
                // 绑定
                HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
                //dataValidation.setSuppressDropDownArrow(true);
                sheet.addValidationData(dataValidation);
                cellNext.setCellValue(arr[0]);
            } else {
                cellNext.setCellValue(obj.toString());
            }
        }else {
            cellNext.setCellValue("");
        }
    }

    public static void setDownResponseHeader(HttpServletResponse response,String fileName){
        try {
            try {
                fileName = new String (fileName.getBytes(),"iso-8859-1");
            }catch (UnsupportedEncodingException e){
                e.printStackTrace();
            }
            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename="+fileName);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static HttpHeaders setDownResponseHeader(String fileName){
        HttpHeaders headers = new HttpHeaders();
        try {
            headers.add("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("gbk"), "iso8859-1")+".xls");
            headers.setContentType(MediaType.valueOf("application/vnd.ms-excel;charset=UTF-8"));
        }catch (Exception e){
            e.printStackTrace();
        }
        return headers;
    }

    /*设置导出数据excel文件单元格的样式*/
    public static HSSFCellStyle setHSSCellStyle(HSSFWorkbook wb){
        HSSFCellStyle style = wb.createCellStyle();
        HSSFFont font = wb.createFont();
        style.setAlignment(HorizontalAlignment.CENTER);//字体居中
        style.setWrapText(true);//设置不自动换行
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);

        font.setBold(true);//粗体显示
        font.setFontHeightInPoints((short) 10);
        font.setFontName("宋体");
        style.setFont(font);
        return style;
    }

    public static XSSFCellStyle setXSSCellStyle(XSSFWorkbook wb){
        XSSFCellStyle style = wb.createCellStyle();
        XSSFFont font = wb.createFont();
        style.setAlignment(HorizontalAlignment.CENTER);//字体居中
        style.setWrapText(true);//设置不自动换行
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);

        font.setBold(true);//粗体显示
        font.setFontHeightInPoints((short) 10);
        font.setFontName("宋体");
        style.setFont(font);
        return style;
    }

    public static HSSFCellStyle setTitleHSSCellStyle(HSSFWorkbook wb){
        HSSFCellStyle style = wb.createCellStyle();
        HSSFFont font = wb.createFont();
        style.setAlignment(HorizontalAlignment.CENTER);//字体居中
        style.setWrapText(true);//设置不自动换行
        style.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        setHSSCellBorder(style);
        font.setFontHeightInPoints((short) 14);
        font.setBold(true);//粗体显示
        font.setFontName("黑体");
        style.setFont(font);

        return style;
    }

    public static HSSFCellStyle setHSSCellStyleRegion(HSSFWorkbook wb){
        HSSFCellStyle style = wb.createCellStyle();
        HSSFFont font = wb.createFont();
        style.setAlignment(HorizontalAlignment.CENTER);//字体居中
        style.setWrapText(true);//设置不自动换行
        style.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        font.setFontHeightInPoints((short) 12);
        font.setFontName("宋体");
        style.setFont(font);
        return style;
    }

    public static void setHSSCellBorder(HSSFCellStyle style){
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
    }

    public static CellRangeAddress setAddMergedRegion(HSSFSheet sheet, HSSFCell cell, HSSFCellStyle style,
                                                      String cellValue, int firstRow, int lastRow, int firstCol, int lastCol){
        // 合并单元格
        CellRangeAddress cra = new CellRangeAddress(firstRow,lastRow,firstCol,lastCol); // 起始行, 终止行, 起始列, 终止列
        sheet.addMergedRegion(cra);
        cell.setCellValue(cellValue);
        cell.setCellStyle(style);
        setRegionBorder(cra,sheet);
        return cra;
    }

    public static void setRegionBorder(CellRangeAddress range,HSSFSheet sheet){
        // 使用RegionUtil类为合并后的单元格添加边框
        RegionUtil.setBorderBottom(1, range, sheet); // 下边框
        RegionUtil.setBorderLeft(1, range, sheet); // 左边框
        RegionUtil.setBorderRight(1, range, sheet); // 有边框
        RegionUtil.setBorderTop(1, range, sheet); // 上边框
    }

    /*设置单元格宽度*/
    public static int setColumnWidth(int width){
        return 256*width+184;
    }
    /*设置行高*/
    public static short setRowHeight(int height){
        int  h = height * 20;
        return (short) h;
    }

    public static byte[] toByteArray(HSSFWorkbook wb){
        byte[] content = null;
        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            wb.write(os);
            content = os.toByteArray();
            os.flush();
            os.close();
            wb.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return content;
    }
}

2.集合处理类

import java.util.ArrayList;
import java.util.List;

public class ListUtil<T> {

    /**
     * 将list集合分割成多个子集合
     * @param list 要分割的集合
     * @param subRow 子集合包含元素个数
     */
    public static <T> List<List<T>> getSubListByRow(List<T> list,int subRow){
        int count = list.size();
        int subNum = count % subRow == 0 ? count / subRow : count / subRow + 1;
        List<List<T>> resList = new ArrayList<>(subNum);
        for(int i=0;i<subNum;i++){
            int s = i * subRow;
            int e = s + subRow;
            if(e > count) e = count;
            List<T> sonList = list.subList(s,e);
            resList.add(sonList);
        }
        return resList;
    }

    /**
     * 将list集合分割成subCount个子集合
     * @param list 要分割的集合
     * @param subCount 分割成subCount个子集合 10 3
     */
    public static <T> List<List<T>> getSubListByCount(List<T> list,int subCount){
        int size = list.size();
        int subRow = size / subCount;
        if(subRow >= 2){
            if(size%subCount != 0){
                subRow = subRow+1;
            }
        }else{
            if (size > subCount) {
                subRow = subRow+1;;
            }else {
                subRow = size;
            }
        }
        return getSubListByRow(list,subRow);
    }
}

3.定义接口

public interface DemoService {
    /*导出excel*/
    byte[] exportExcel(String ids, int cate);
}

4.接口实现类

import com.rhx.framework.produce.common.util.ListUtil;
import com.rhx.framework.produce.core.db.mapper.primary.center.SysToolsMapper;
import com.rhx.framework.produce.core.service.demo.DemoService;
import com.rhx.framework.produce.upload.excel.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.*;


@Service
@Transactional
public class DemoServiceImpl implements DemoService {
    @Autowired
    private SysToolsMapper toolsMapper;

    @Override
    public byte[] exportExcel(String codes,int cate) {
        //创建HSSFWorkbook对象
        HSSFWorkbook wb = new HSSFWorkbook();
        if(cate==1){
            exportCadreInfo(codes,wb);//干部基本信息报表
        }else if(cate==2){
            //exportCadrePosition(codes,wb);//职位信息报表
        }
        return OutExcelUtil.toByteArray(wb);
    }
    public void exportCadreInfo(String idStr, HSSFWorkbook wb) {
        //根据条件从数据库查询数据集合
        String[] idArr = idStr.split(",");
        List<Map> list = this.toolsMapper.selectAllTools();
        //设置excel文件中sheet名
        String sheetName = "基本信息报表";
        //设置标题名
        List<String[]> titles = new ArrayList<String[]>(){
            {
                //分别添加名称,单元格长度
                add(new String[]{"名称","12"});
                add(new String[]{"链接","50"});
                add(new String[]{"图标","15"});
            }
        };

        //创建sheet对象
        HSSFSheet sheet = wb.createSheet(sheetName);
        //创建excel的单元格
        HSSFCell cell = null;

        HSSFCellStyle titleStyle = OutExcelUtil.setTitleHSSCellStyle(wb);//标题单元格演示
        HSSFCellStyle style = OutExcelUtil.setHSSCellStyle(wb);//普通样式
        //HSSFCellStyle styleRegion = OutExcelUtil.setHSSCellStyleRegion(wb);//合并单元格样式

        HSSFRow title = sheet.createRow(0);
        cell = title.createCell(0);
        title.setHeight((short)(15*30));
        OutExcelUtil.setAddMergedRegion(sheet,cell,titleStyle,sheetName,0,0,0,titles.size()-1);

        //循环title,创建标题
        HSSFRow row = sheet.createRow(1);
        for(int i=0; i<titles.size(); i++){
            sheet.setColumnWidth(i, OutExcelUtil.setColumnWidth(Integer.valueOf(titles.get(i)[1])));
            cell = row.createCell(i);
            cell.setCellValue(titles.get(i)[0]);
            cell.setCellStyle(style);
        }


        //创建数据对象,用来保存list数据
        List<List<Map>> subList = ListUtil.getSubListByCount(list,2);
        for(int s=0;s<subList.size();s++){
            List<Map> sub = subList.get(s);
            Object[][] values = new Object[sub.size()][titles.size()];
            for(int i=0; i<sub.size(); i++){
                values[i][0] = sub.get(i).get("toolName");
                values[i][1] = sub.get(i).get("toolLink");
                values[i][2] = sub.get(i).get("toolIcon");
            }
            int startRow = 2;
            if(s > 0){
                startRow = startRow + subList.get(s-1).size();
            }
            int dataRow = startRow;
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("start");
                    OutExcelUtil.getMergedHSSFWorkbook(style,sheet,values,dataRow);
                    System.out.println("end");
                }
            },"thread-"+s);
            try {
                thread.start();
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

5.springboot 调用导出方法

@Controller
@RequestMapping("/demo")
public class DemoController {
    
    @Autowired
    private DemoService demoService;    

    /*根据查询条件导出数据到excel*/
    @RequestMapping("/exportExcel")
    public ResponseEntity<byte[]> exportExcel(HttpServletRequest request, String ids){
        //设置excel文件名
        String fileName="信息报表";
        //设置HttpHeaders,设置fileName编码,排除导出文档名称乱码问题
        HttpHeaders headers = OutExcelUtil.setDownResponseHeader(fileName);
        byte[] value = null;
        try {
            //获取要导出的数据
            value = this.demoService.exportExcel(ids,1);
        }catch (Exception e){
            e.printStackTrace();
        }
        return new ResponseEntity<byte[]>(value,headers, HttpStatus.OK);
    }
} 
    

猜你喜欢

转载自blog.csdn.net/rhx_1989/article/details/88424905