POI 合并单元格

原始结果:


 

 

期望结果:


 

关键代码通用类如下:

 

SchoolController 部分代码:

    @RequestMapping(value="/exportExcel")
    public String exportExcel(HttpServletResponse response) {
        response.setContentType("application/binary;charset=ISO8859_1");
        try {
            ServletOutputStream outputStream = response.getOutputStream();
            String fileName = new String(("导出excel例子").getBytes(), "ISO8859_1");
            response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");// 组装附件名称和格式
            String[] titles = { "省份", "市", "人名" , "学校名"};
            schoolService.exportExcel(titles, outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }	

 

 

 

SchoolServiceImpl部分代码:

    @Override
    public void exportExcel(String[] titles, ServletOutputStream outputStream) {
        
        School school = new School();
//      该类就不贴出代码了,建议自己按照图示,拼装学校集合
        List<School> schools = schoolDao.getSchoolList(school);
        
        // 创建一个workbook 对应一个excel应用文件
        XSSFWorkbook workBook = new XSSFWorkbook();
        // 在workbook中添加一个sheet,对应Excel文件中的sheet
        XSSFSheet sheet = workBook.createSheet("导出excel例子");
        // 自适应列宽度
        sheet.autoSizeColumn(1, true);
        ExportUtil exportUtil = new ExportUtil(workBook, sheet);
        XSSFCellStyle headStyle = exportUtil.getHeadStyle();
        XSSFCellStyle bodyStyle = exportUtil.getBodyStyle();
        
        // 构建表头
        XSSFRow headRow = sheet.createRow(0);
        XSSFCell cell = null;
        for (int i = 0; i < titles.length; i++) {
            cell = headRow.createCell(i);
            cell.setCellStyle(headStyle);
            cell.setCellValue(titles[i]);
        }
        // 构建表体数据
        if (schools != null && schools.size() > 0) {
            for (int j = 0; j < schools.size(); j++) {
                XSSFRow bodyRow = sheet.createRow(j + 1);
                School schoolInner = schools.get(j);

                cell = bodyRow.createCell(0);
                cell.setCellStyle(bodyStyle);
                cell.setCellValue(schoolInner.getProvinces());

                cell = bodyRow.createCell(1);
                cell.setCellStyle(bodyStyle);
                cell.setCellValue(schoolInner.getCity());
                
                cell = bodyRow.createCell(2);
                cell.setCellStyle(bodyStyle);
                cell.setCellValue(schoolInner.getLinker());
                
                cell = bodyRow.createCell(3);
                cell.setCellStyle(bodyStyle);
                cell.setCellValue(schoolInner.getSchoolName());
                
            }
//                /* 
//                 * 设定合并单元格区域范围 
//                 *  firstRow  0-based 
//                 *  lastRow   0-based 
//                 *  firstCol  0-based 
//                 *  lastCol   0-based 
//                 */ 
//            sheet.addMergedRegion(new CellRangeAddress(2, 7, 0, 0));
//            sheet.addMergedRegion(new CellRangeAddress(2, 3, 1, 1));
//            sheet.addMergedRegion(new CellRangeAddress(4, 7, 1, 1));

            
            int lastRowNum = sheet.getLastRowNum();
            exportUtil.mergerData(sheet, 0, 1 , lastRowNum);
            Map<String,String> map = exportUtil.mergerData(sheet, 1, 1 , lastRowNum);
//            System.out.println("map: "+JSON.toJSONString(map));
            for(String value : map.values()){
                String [] strArr = value.split(",");
                int firstRow = Integer.parseInt(strArr[0])-1;
                int lastRow = Integer.parseInt(strArr[1])-1;
                exportUtil.mergerData(sheet, 2, firstRow, lastRow);
            }
            
            
            
        }
        try {
            workBook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

 

 

ExportUtil:代码

package com.bugyun.util;

import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExportUtil {
    private XSSFWorkbook wb = null;

    private XSSFSheet sheet = null;

    /**
     * @param wb
     * @param sheet
     */
    public ExportUtil(XSSFWorkbook wb, XSSFSheet sheet) {
        this.wb = wb;
        this.sheet = sheet;
    }

    /**
     * 合并单元格后给合并后的单元格加边框
     * 
     * @param region
     * @param cs
     */
    public void setRegionStyle(CellRangeAddress region, XSSFCellStyle cs) {

        int toprowNum = region.getFirstRow();
        for (int i = toprowNum; i <= region.getLastRow(); i++) {
            XSSFRow row = sheet.getRow(i);
            for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
                XSSFCell cell = row.getCell(j);// XSSFCellUtil.getCell(row,
                                               // (short) j);
                cell.setCellStyle(cs);
            }
        }
    }

    /**
     * 设置表头的单元格样式
     * 
     * @return
     */
    public XSSFCellStyle getHeadStyle() {
        // 创建单元格样式
        XSSFCellStyle cellStyle = wb.createCellStyle();
        // 设置单元格的背景颜色为淡蓝色
        cellStyle.setFillForegroundColor(HSSFColor.PALE_BLUE.index);
        cellStyle.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
        // 设置单元格居中对齐
        cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        // 设置单元格垂直居中对齐
        cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        // 创建单元格内容显示不下时自动换行
        cellStyle.setWrapText(true);
        // 设置单元格字体样式
        XSSFFont font = wb.createFont();
        // 设置字体加粗
        font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
        font.setFontName("宋体");
        font.setFontHeight((short) 200);
        cellStyle.setFont(font);
        // 设置单元格边框为细线条
        cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
        return cellStyle;
    }

    /**
     * 设置表体的单元格样式
     * 
     * @return
     */
    public XSSFCellStyle getBodyStyle() {
        // 创建单元格样式
        XSSFCellStyle cellStyle = wb.createCellStyle();
        // 设置单元格居中对齐
        cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        // 设置单元格垂直居中对齐
        cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        // 创建单元格内容显示不下时自动换行
        cellStyle.setWrapText(true);
        // 设置单元格字体样式
        XSSFFont font = wb.createFont();
        // 设置字体加粗
//        font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
        font.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);
        
        font.setFontName("宋体");
        font.setFontHeight((short) 200);
        cellStyle.setFont(font);
        // 设置单元格边框为细线条
        cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
        return cellStyle;
    }
    
    /**
     * @param sheet
     * @param colIndex       合并的第几列  (下标从0开始)
     * @param startRowIndex  从第几行开始合并(算上标题,从0开始算)
     * @param endRowIndex    从第几行结束合并
     */
    public Map<String,String> mergerData(XSSFSheet sheet,int colIndex, int startRowIndex , int endRowIndex) {
        Map<String,String> map = new HashMap<>();
        
        breakFor:
        for (int i = startRowIndex; i <= endRowIndex; i++) {
            Cell cell = sheet.getRow(i).getCell(colIndex);

            for (int j = i + 1; j <= endRowIndex; j++) {
                Cell celltemp = sheet.getRow(j).getCell(colIndex);

                // 如果下一行与被比较行相等,则继续该循环,直到不等才跳出
                if (!celltemp.getStringCellValue().equals(cell.getStringCellValue())) {
                    int temp = j-1;
                    if (temp > i) {
                        // 合并单元格
                        map.put(cell.getStringCellValue(), i+1+","+j);
                        sheet.addMergedRegion(new CellRangeAddress(i, temp, colIndex, colIndex));
                        
                    }
                    i = temp;
                    break;
                }
                if (j == endRowIndex) {
                    map.put(cell.getStringCellValue(), i+1+","+j);
                    sheet.addMergedRegion(new CellRangeAddress(i, endRowIndex, colIndex, colIndex));
                    break breakFor;
                }
            }
        }
        return map ;
    }
}

 

pom.xml 引入包:

 

        <!-- poi 导出Excel包 -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>3.14</version>
		</dependency>

 

School类字段 ,参考代码就不一一贴出来了;

 

参考文章:

http://bbs.csdn.net/topics/390420021

http://blog.csdn.net/hehexiaoyou/article/details/37873131

 

猜你喜欢

转载自bugyun.iteye.com/blog/2375254