转自:https://www.cnblogs.com/coloz/p/12522229.html
一、自定义一个单元格样式
public class CustomCellWriteHandler implements CellWriteHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomCellWriteHandler.class);
//标黄行宽集合
private Set<Integer> yellowRowIndexs;
//构造
public CustomCellWriteHandler(Set<Integer> yellowRowIndexs) {
this.yellowRowIndexs = yellowRowIndexs;
}
public CustomCellWriteHandler() {
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
LOGGER.info("beforeCellCreate~~~~");
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
LOGGER.info("afterCellCreate~~~~");
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
// 这里可以对cell进行任何操作
LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex());
if (CollectionUtils.isNotEmpty(yellowRowIndexs)) {
Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
CellStyle cellStyle = workbook.createCellStyle();
//字体
Font cellFont = workbook.createFont();
cellFont.setBold(true);
cellStyle.setFont(cellFont);
//标黄,要一起设置
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); //设置前景填充样式
cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());//前景填充色
if (yellowRowIndexs.contains(cell.getRowIndex())) {
cell.setCellStyle(cellStyle);
}
}
}
}
二、测试方法
/**
* 写入到固定文件中,高亮显示某一行
*
* @throws IOException
*/
@Test
public void writeToExcelFile3() {
//这里自定义一个单元格的格式(标黄的行高亮显示)
Integer[] yellowRows = {3, 5, 7, 9};
Set<Integer> yellowRowsSet = new HashSet<>(Arrays.asList(yellowRows));
CustomCellWriteHandler customCellWriteHandler = new CustomCellWriteHandler(yellowRowsSet);
//写入的文excel文件
String fileName = "I:\\temp\\writeDemo3.xlsx";
/*------------------------------分割线------------------------------*/
//获取头和内容的策略
HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
//列宽的策略,宽度是小单位
Integer columnWidthArr[] = {3000, 3000, 2000, 6000};
List<Integer> columnWidths = Arrays.asList(columnWidthArr);
CustomSheetWriteHandler customSheetWriteHandler = new CustomSheetWriteHandler(columnWidths);
// 根据自定义导出的字段
String[] filds = {"uid", "name", "age", "birthday"};
String[] headers = {"唯一识别码", "姓名", "年龄", "生日"};
List head = getHeadByFilds(headers);
//获取模拟的实体数据集合
List<User> userList = getUserList();
//这里指定头的名字去写入,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcel.write(fileName)
.head(head)
.registerWriteHandler(horizontalCellStyleStrategy)
.registerWriteHandler(customSheetWriteHandler)
//注册单元格式
.registerWriteHandler(customCellWriteHandler)
.includeColumnFiledNames(Arrays.asList(filds))
.sheet("模板")
.doWrite(userList);
}
效果
三、自定义合并单元格的策略
/**
* 自定义的合并策略,参考官方文档的LoopMergeStrategy
*/
public class MyMergeStrategy extends AbstractMergeStrategy {
//合并坐标集合
private List<CellRangeAddress> cellRangeAddresss;
//构造
public MyMergeStrategy(List<CellRangeAddress> cellRangeAddresss) {
this.cellRangeAddresss = cellRangeAddresss;
}
/**
* merge
*
* @param sheet
* @param cell
* @param head
* @param relativeRowIndex
*/
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
//合并单元格
/**
* ****加个判断:if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) {}****
* 保证每个cell被合并一次,如果不加上面的判断,因为是一个cell一个cell操作的,
* 例如合并A2:A3,当cell为A2时,合并A2,A3,但是当cell为A3时,又是合并A2,A3,
* 但此时A2,A3已经是合并的单元格了
*/
if (CollectionUtils.isNotEmpty(cellRangeAddresss)) {
if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) {
for (CellRangeAddress item : cellRangeAddresss) {
sheet.addMergedRegionUnsafe(item);
}
}
}
}
}
四、测试合并
/**
* 模拟合并单元格的位置
*
* @return
*/
private List<CellRangeAddress> getCellRangeAddresss() {
List<CellRangeAddress> list = new ArrayList<>();
//合并第4行
CellRangeAddress item1 = new CellRangeAddress(3, 3, 0, 3);
//合并第第6行的第一列和第二列
CellRangeAddress item2 = new CellRangeAddress(5, 5, 0, 1);
//合并第9行和第10行
CellRangeAddress item3 = new CellRangeAddress(10, 11, 0, 3);
list.add(item1);
list.add(item2);
list.add(item3);
return list;
}
/**
* 写入到固定文件中,合并单元格
*
* @throws IOException
*/
@Test
public void writeToExcelFile4() {
//定义合并单元格的坐标范围
List<CellRangeAddress> cellRangeAddresss = getCellRangeAddresss();
//定义合并单元格策略
MyMergeStrategy myMergeStrategy = new MyMergeStrategy(cellRangeAddresss);
//写入的文excel文件
String fileName = "I:\\temp\\writeDemo4.xlsx";
/*------------------------------分割线------------------------------*/
//这里自定义一个单元格的格式(标黄的行高亮显示)
Integer[] yellowRows = {3, 5, 7, 9};
Set<Integer> yellowRowsSet = new HashSet<>(Arrays.asList(yellowRows));
CustomCellWriteHandler customCellWriteHandler = new CustomCellWriteHandler(yellowRowsSet);
//获取头和内容的策略
HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
//列宽的策略,宽度是小单位
Integer columnWidthArr[] = {3000, 3000, 2000, 6000};
List<Integer> columnWidths = Arrays.asList(columnWidthArr);
CustomSheetWriteHandler customSheetWriteHandler = new CustomSheetWriteHandler(columnWidths);
// 根据自定义导出的字段
String[] filds = {"uid", "name", "age", "birthday"};
String[] headers = {"唯一识别码", "姓名", "年龄", "生日"};
List head = getHeadByFilds(headers);
//获取模拟的实体数据集合
List<User> userList = getUserList();
//这里指定头的名字去写入,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcel.write(fileName)
.head(head)
.registerWriteHandler(horizontalCellStyleStrategy)
.registerWriteHandler(customSheetWriteHandler)
//注册单元格式
.registerWriteHandler(customCellWriteHandler)
//注册合并策略
.registerWriteHandler(myMergeStrategy)
.includeColumnFiledNames(Arrays.asList(filds))
.sheet("模板")
.doWrite(userList);
}