合并单元格
生成excel,我用的是XSSFWorkbook,合并单元格,使用的是addMergedRegion方法,
//参数说明:1:开始行 2:结束行 3:开始列 4:结束列
//比如合并 第二行到第四行的 第六列到第八列 sheet.addMergedRegion(new //CellRangeAddress(1,3,5,7));
sheet.addMergedRegion(new CellRangeAddress(0,0,0,1));
类似于这样
//第1,2,3,4,5,6列,第一行第二行,合并单元格
sheet.addMergedRegion(new CellRangeAddress(0,1,0,0));
sheet.addMergedRegion(new CellRangeAddress(0,1,1,1));
sheet.addMergedRegion(new CellRangeAddress(0,1,2,2));
sheet.addMergedRegion(new CellRangeAddress(0,1,3,3));
sheet.addMergedRegion(new CellRangeAddress(0,1,4,4));
sheet.addMergedRegion(new CellRangeAddress(0,1,5,5));
//第7,8,9,10列,第一行,合并单元格
sheet.addMergedRegion(new CellRangeAddress(0,0,6,9));
//第11,12,13,14列,第一行,合并单元格
sheet.addMergedRegion(new CellRangeAddress(0,0,10,13));
部分样例代码:
/**
* 写入excel
* @return
*/
public ComServiceResVo writeExcel(String fileName, ServletOutputStream outputStream) {
// 创建一个workbook 对应一个excel应用文件
XSSFWorkbook workBook = new XSSFWorkbook();
// 在workbook中添加一个sheet,对应Excel文件中的sheet
XSSFSheet sheet = workBook.createSheet(fileName);
sheet.setDefaultColumnWidth((short) 30);
ExportUtil exportUtil = new ExportUtil(workBook, sheet);
XSSFCellStyle headStyle = exportUtil.getHeadStyle();
XSSFCellStyle bodyStyle = exportUtil.getBodyStyle();
// 构建表头
XSSFRow headRow = sheet.createRow(0);
XSSFCell cell = null;
cell = headRow.createCell(0);
cell.setCellStyle(headStyle);
cell.setCellValue("");
cell = headRow.createCell(1);
cell.setCellStyle(headStyle);
cell.setCellValue("区县");
cell = headRow.createCell(2);
cell.setCellStyle(headStyle);
cell.setCellValue("隔离点名称");
// 构建表体数据
//根据区县排序
ArrayList<IsolatedPointEntity> datas =
excelDatas.stream().sorted
(Comparator.comparing(IsolatedPointEntity::getCounty))
.collect(Collectors.toCollection(ArrayList::new));
int countyCount=0;
int countyIndex=0;
for (int j = 0; j < datas.size(); j++) {
IsolatedPointEntity order=datas.get(j);
XSSFRow bodyRow = sheet.createRow(j + 1);
if(j==0){
cell = bodyRow.createCell(0);
cell.setCellStyle(bodyStyle);
cell.setCellValue("无锡市");
}
int finalJ = j;
/**
* 不同区县,合并单元格
* 第一个区县绘制位置是0,包含三个隔离点,第二个区县绘制位置就是j+3 =3
* 第三个区县包含四个隔离点,绘制位置就是3+4=7
*/
if(j == 0 || j == countyIndex) {
countyCount= (int) (datas.stream().filter((p) -> p.getCounty().equals(datas.get(finalJ).getCounty())).count());
countyIndex= j+countyCount;
cell = bodyRow.createCell(1);
cell.setCellStyle(bodyStyle);
cell.setCellValue(order.getCounty()==null?"":order.getCounty()+"("+countyCount+")");
}
}
//第一列,第一行到最后一行,合并单元格
sheet.addMergedRegion(new CellRangeAddress(1,datas.size(),0,0));
//第二列,根据区县合并单元格
int countyCount1= 0;
//区县在列表中的位置
int countyIndex1=0;
for(int j = 0; j < datas.size(); j++){
int finalJ = j;
if(j==0||j==countyIndex1-1) {
countyCount1= (int) (datas.stream().filter((p) -> p.getCounty().equals(datas.get(finalJ).getCounty())).count());
countyIndex1= j+countyCount1;
sheet.addMergedRegion(new CellRangeAddress(j+1,countyCount1,1,1));
}
}
//最后一行
XSSFRow bodyRow = sheet.createRow(excelDatas.size()+1);
//第一列
cell = bodyRow.createCell(0);
cell.setCellStyle(bodyStyle);
cell.setCellValue("合计");
//第二列
cell = bodyRow.createCell(1);
cell.setCellStyle(bodyStyle);
cell.setCellValue(datas.size());
try {
workBook.write(outputStream);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
logger.error(e.getMessage());
return ComServiceResVo.badRequest("导出失败");
} finally {
try {
outputStream.close();
} catch (IOException e) {
logger.error(e.getMessage());
}
}
return ComServiceResVo.badRequest("导出成功");
}
另外,java 8 stream真香,做一些统计,不再需要写各种for循环了
datas.stream().mapToDouble(IsolatedPointEntity::getPeopleTotalRelieve).sum()
excel的一些配置
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);
cell.setCellStyle(cs);
}
}
}
/**
* 设置表头的单元格样式
*
* @return
*/
public XSSFCellStyle getBigHeadStyle()
{
// 创建单元格样式
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) 400);
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 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.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;
}
}
根据开始时间和结束时间筛选数据
Entity的里边设置两个字段,一个是显示的String,一个是Long型的时间戳,用来比较
/**
* 登记日期
*/
@Column(name = "register_date", length = 12)
private String registerDate;
/**
* 登记日期(Long)
*/
@Column(name = "register_date_long")
private Long registerDateLong;
VO里添加两个对应字段,开始时间,结束时间
@QueryCriteria(name = "registerDateLong",expression = EXPRESSION.GE)
private Long sDateLong;
@QueryCriteria(name = "registerDateLong",expression = EXPRESSION.LT)
private Long eDateLong;
js使用laydate控件选择日期
<script type="text/javascript">
$(function () {
laydate.render({
elem: '#q_sDate', //指定元素
type: 'date',
});
laydate.render({
elem: '#q_eDate', //指定元素
type: 'date',
});
});
</script>
传入后台
d.sDate = $("#q_sDate").val();
d.eDate = $("#q_eDate").val();
后台查询
public Page<IsolatorEntity> findCondForMg(Pageable pageable, IsolatorVO vo){
if(!StringUtils.isEmpty(vo.getsDate())){
vo.setsDateLong(DateUtil.fromStringToInstant("yyyy-MM-dd", vo.getsDate() + "").toEpochMilli());
}
if(!StringUtils.isEmpty(vo.geteDate())) {
vo.seteDateLong(DateUtil.fromStringToInstant("yyyy-MM-dd HH:mm:ss", vo.geteDate() + " 23:59:59").toEpochMilli());
}
Page<IsolatorEntity> pointEntities=repository.findByCriteria(pageable, vo, null);
return pointEntities;
}
参考文章
java poi 合并单元格