Java中合并Excel单元格的方法
在Java中操作Excel合并单元格,常用的库有Apache POI和EasyExcel,以下是使用这两种方法合并单元格的示例:

(图片来源网络,侵删)
使用Apache POI合并单元格
Apache POI是Java操作Excel最常用的库之一。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
public class MergeCellsExample {
public static void main(String[] args) throws IOException {
// 创建新的工作簿
Workbook workbook = new XSSFWorkbook();
// 创建工作表
Sheet sheet = workbook.createSheet("合并单元格示例");
// 创建行和单元格
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("合并的单元格");
// 合并单元格 (起始行, 结束行, 起始列, 结束列)
sheet.addMergedRegion(new CellRangeAddress(0, 2, 0, 2)); // 合并第1-3行,第1-3列
// 写入文件
try (FileOutputStream fileOut = new FileOutputStream("merged_cells.xlsx")) {
workbook.write(fileOut);
}
// 关闭工作簿
workbook.close();
System.out.println("Excel文件已创建,单元格已合并");
}
}
使用EasyExcel合并单元格
EasyExcel是阿里巴巴开源的Excel处理库,性能更好,内存占用更小。
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.*;
import java.io.FileOutputStream;
import java.io.IOException;
public class EasyExcelMergeExample {
public static void main(String[] args) throws IOException {
// 创建Excel写入器
String fileName = "easyexcel_merged_cells.xlsx";
// 创建样式策略
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short) 10);
headWriteCellStyle.setWriteFont(headWriteFont);
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
WriteFont contentWriteFont = new WriteFont();
contentWriteFont.setFontHeightInPoints((short) 10);
contentWriteCellStyle.setWriteFont(contentWriteFont);
HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
// 构建写入器
EasyExcel.write(fileName)
.registerWriteHandler(horizontalCellStyleStrategy)
.registerWriteHandler(new CustomMergeStrategy())
.sheet("合并单元格示例")
.doWrite(() -> {
// 这里可以添加数据,但合并操作由CustomMergeHandler处理
return null;
});
System.out.println("EasyExcel文件已创建,单元格已合并");
}
// 自定义合并策略
public static class CustomMergeStrategy implements WriteHandler {
@Override
public void sheetCreateBefore(WriteSheetHolder writeSheetHolder) {
}
@Override
public void sheetCreateAfter(WriteSheetHolder writeSheetHolder) {
}
@Override
public void rowCreateBefore(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void rowCreateAfter(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void cellCreateBefore(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead, Integer relativeCellIndex) {
}
@Override
public void cellCreateAfter(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead, Integer relativeCellIndex) {
// 在这里实现合并逻辑
if (relativeRowIndex == 0) { // 假设第一行需要合并
sheet.addMergedRegion(new CellRangeAddress(0, 2, 0, 2));
}
}
}
}
注意事项
- 合并范围:合并区域必须是连续的矩形区域,不能是分散的单元格。
- 数据覆盖:合并后,只有左上角的单元格有数据,其他单元格的数据会被忽略。
- 样式继承:合并后的单元格会继承左上角单元格的样式。
- 性能考虑:对于大型Excel文件,EasyExcel通常比Apache POI更高效。
更复杂的合并场景
如果需要根据数据动态合并单元格(例如合并相同值的单元格),可以实现更复杂的逻辑:
// Apache POI示例 - 合并相同值的单元格
public void mergeCellsByValue(Sheet sheet, int columnIndex) {
int firstRow = 0;
String prevValue = "";
for (int i = 0; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row == null) continue;
Cell cell = row.getCell(columnIndex);
String currentValue = getCellValueAsString(cell);
if (currentValue.equals(prevValue)) {
// 合并相同值的单元格
sheet.addMergedRegion(new CellRangeAddress(firstRow, i - 1, columnIndex, columnIndex));
}
prevValue = currentValue;
firstRow = i;
}
}
private String getCellValueAsString(Cell cell) {
if (cell == null) return "";
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf(cell.getNumericCellValue());
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
return cell.getCellFormula();
default:
return "";
}
}
代码可以根据实际需求进行调整和扩展。

(图片来源网络,侵删)

(图片来源网络,侵删)
