原始结果:
期望结果:
关键代码通用类如下:
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