記開發中遇到的兩個小功能--excel合併單元格,根據開始時間結束時間篩選資料
阿新 • • 發佈:2021-01-13
技術標籤:spring boot
合併單元格
生成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 合併單元格