在做一個業務的匯出,目前遇到一個需求,如下圖:

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.Data;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.List;
/**
* 單元格合并策略類
*
*/
@Data
public class ExcelFillCellMergeStrategy implements CellWriteHandler {
/**
* 哪幾列的欄位需要合并
*/
private int[] mergeColumnIndex;
/**
* 從第幾行開始合并
*/
private int mergeRowIndex;
public ExcelFillCellMergeStrategy() {
}
public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) {
this.mergeRowIndex = mergeRowIndex;
this.mergeColumnIndex = mergeColumnIndex;
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Head head, Integer integer, Integer integer1, Boolean aBoolean) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
Head head, Integer integer, Boolean aBoolean) {
Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
CellStyle cellStyle = workbook.createCellStyle();
Font cellFont = workbook.createFont();
//加粗
cellFont.setBold(true);
//字體大小
cellFont.setFontHeightInPoints((short) 12);
//居中
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setFont(cellFont);
cell.setCellStyle(cellStyle);
//設定 自動換行
cellStyle.setWrapText(true);
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
//當前行
int curRowIndex = cell.getRowIndex();
//當前列
int curColIndex = cell.getColumnIndex();
if (curRowIndex > mergeRowIndex) {
for (int i = 0; i < mergeColumnIndex.length; i++) {
if (curColIndex == mergeColumnIndex[i]) {
mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
break;
}
}
}
}
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
//獲取當前行的當前列的資料和上一行的當前列列資料,通過上一行資料是否相同進行合并
Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() :
cell.getNumericCellValue();
Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() :
preCell.getNumericCellValue();
// 比較當前行的第一列的單元格與上一行是否相同,相同合并當前單元格與上一行
//
if (curData.equals(preData)) {
Sheet sheet = writeSheetHolder.getSheet();
List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
CellRangeAddress cellRangeAddr = mergeRegions.get(i);
// 若上一個單元格已經被合并,則先移出原有的合并單元,再重新添加合并單元
if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
sheet.removeMergedRegion(i);
cellRangeAddr.setLastRow(curRowIndex);
sheet.addMergedRegion(cellRangeAddr);
isMerged = true;
}
}
// 若上一個單元格未被合并,則新增合并單元
if (!isMerged) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex,
curColIndex);
sheet.addMergedRegion(cellRangeAddress);
}
}
}
}
該方法匯出后表格資料會像圖中第二種情況,但客戶實際需求是根據條款內容的行數進行合并(也就是圖中第三種),第二列和第三列對應的考核部門以及推送狀態是動態行數數量不固定的,有easyExcel運用的熟練的大佬指點一下我該如何撰寫合并的方法?目前用的2.2.3的版本和3.17的poi
uj5u.com熱心網友回復:
補充一點:真實環境可能表格合并資料形式沒有這么極端(畢竟每個條款對應的審核部門大部分不相同以及分值也不相同),但如果用這個合并方法肯定會有這種情況uj5u.com熱心網友回復:
頂一下頂一下頂一下轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/231616.html
標籤:Web 開發
