在Java中导出带有自定义复杂表头的Excel文件,通常会使用Apache POI库,这是一个强大的API,专为操作Microsoft Office格式的文件而设计,特别是处理Excel(.xlsx和.xls)文件。本文将详细介绍如何使用Java和Apache POI库来创建一个具有多级表头和复杂样式的Excel文件。
准备工作
添加依赖
首先,确保你的项目中包含了Apache POI的依赖。如果你使用的是Maven,可以在pom.xml
中添加以下依赖:
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
</dependencies>
创建Excel文件
接下来,我们将逐步创建一个具有多级表头的Excel文件。
- 创建工作簿和工作表
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Complex Header Example");
- 设置列宽
sheet.setColumnWidth(0, 6 * 256); // 第1列宽度
sheet.setColumnWidth(1, 20 * 256); // 第2列宽度
- 创建单元格样式
CellStyle bigTitleCellStyle = createCellStyle(workbook, "仿宋_GB2312", 18, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
CellStyle headerCellStyle = createCellStyle(workbook, "宋体", 12, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, true);
- 创建大标题
Row bigTitleRow = sheet.createRow(0);
Cell bigTitleCell = bigTitleRow.createCell(0);
bigTitleCell.setCellValue("复杂表头示例");
bigTitleCell.setCellStyle(bigTitleCellStyle);
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 8)); // 合并第一行的所有列
- 创建二级表头
Row secondHeaderRow = sheet.createRow(1);
String[] secondHeader = {"序号", "个人信息", "工作信息", "", "", "财务信息", "", "", ""};
for (int i = 0; i < secondHeader.length; i++) {
Cell cell = secondHeaderRow.createCell(i);
cell.setCellValue(secondHeader[i]);
cell.setCellStyle(headerCellStyle);
}
- 创建三级表头
Row thirdHeaderRow = sheet.createRow(2);
String[] thirdHeader = {"", "姓名", "性别", "部门", "职位", "入职日期", "工资", "奖金", "备注"};
for (int i = 0; i < thirdHeader.length; i++) {
Cell cell = thirdHeaderRow.createCell(i);
cell.setCellValue(thirdHeader[i]);
cell.setCellStyle(headerCellStyle);
}
- 合并单元格
sheet.addMergedRegion(new CellRangeAddress(1, 1, 1, 2)); // 合并 "个人信息"
sheet.addMergedRegion(new CellRangeAddress(1, 1, 3, 4)); // 合并 "工作信息"
sheet.addMergedRegion(new CellRangeAddress(1, 1, 5, 7)); // 合并 "财务信息"
- 设置单元格背景颜色
CellStyle colorCellStyle = createCellStyle(workbook, "宋体", 12, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, true, IndexedColors.LIGHT_GREEN.getIndex());
thirdHeaderRow.getCell(1).setCellStyle(colorCellStyle);
thirdHeaderRow.getCell(3).setCellStyle(colorCellStyle);
thirdHeaderRow.getCell(5).setCellStyle(colorCellStyle);
- 设置单元格字体颜色
CellStyle fontColorCellStyle = createCellStyle(workbook, "宋体", 12, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, true, null, IndexedColors.RED.getIndex());
thirdHeaderRow.getCell(6).setCellStyle(fontColorCellStyle);
- 填充数据
List<Map<String, Object>> dataList = new ArrayList<>();
Map<String, Object> data1 = new HashMap<>();
data1.put("序号", 1);
data1.put("姓名", "张三");
data1.put("性别", "男");
data1.put("年龄", 28);
data1.put("部门", "研发部");
data1.put("职位", "软件工程师");
data1.put("入职日期", "2020-01-01");
data1.put("工资", 8000.00);
data1.put("备注", "");
dataList.add(data1);
int rowNum = 3; // 数据从第四行开始
for (Map<String, Object> data : dataList) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue((Integer) data.get("序号"));
row.createCell(1).setCellValue((String) data.get("姓名"));
row.createCell(2).setCellValue((String) data.get("性别"));
row.createCell(3).setCellValue((Integer) data.get("年龄"));
row.createCell(4).setCellValue((String) data.get("部门"));
row.createCell(5).setCellValue((String) data.get("职位"));
row.createCell(6).setCellValue((String) data.get("入职日期"));
row.createCell(7).setCellValue((Double) data.get("工资"));
row.createCell(8).setCellValue((String) data.get("备注"));
}
- 导出到文件
try (FileOutputStream fileOut = new FileOutputStream("complex_header_example.xlsx")) {
workbook.write(fileOut);
}
// 关闭工作簿
workbook.close();
- 创建单元格样式方法
private static CellStyle createCellStyle(Workbook workbook, String fontName, short fontSize, boolean bold,
HorizontalAlignment horizontalAlign, VerticalAlignment verticalAlign,
boolean bordered, Integer backgroundColor, Integer fontColor) {
CellStyle cellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setFontName(fontName);
font.setFontHeightInPoints(fontSize);
font.setBold(bold);
if (fontColor != null) {
font.setColor(fontColor);
}
cellStyle.setFont(font);
cellStyle.setAlignment(horizontalAlign);
cellStyle.setVerticalAlignment(verticalAlign);
if (bordered) {
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
}
if (backgroundColor != null) {
cellStyle.setFillForegroundColor(backgroundColor);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
}
return cellStyle;
}
完整代码
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExcelExporter {
public static void main(String[] args) throws Exception {
// 创建一个新的 Excel 工作簿
Workbook workbook = new XSSFWorkbook();
// 创建一个工作表
Sheet sheet = workbook.createSheet("Complex Header Example");
// 设置列宽
sheet.setColumnWidth(0, 6 * 256); // 第1列宽度
sheet.setColumnWidth(1, 20 * 256); // 第2列宽度
sheet.setColumnWidth(2, 20 * 256); // 第3列宽度
sheet.setColumnWidth(3, 22 * 256); // 第4列宽度
sheet.setColumnWidth(4, 10 * 256); // 第5列宽度
sheet.setColumnWidth(5, 10 * 256); // 第6列宽度
sheet.setColumnWidth(6, 12 * 256); // 第7列宽度
sheet.setColumnWidth(7, 13 * 256); // 第8列宽度
sheet.setColumnWidth(8, 14 * 256); // 第9列宽度
// 创建大标题单元格样式
CellStyle bigTitleCellStyle = createCellStyle(workbook, "仿宋_GB2312", 18, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
// 创建普通表头单元格样式
CellStyle headerCellStyle = createCellStyle(workbook, "宋体", 12, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, true);
// 创建第一行大标题
Row bigTitleRow = sheet.createRow(0);
Cell bigTitleCell = bigTitleRow.createCell(0);
bigTitleCell.setCellValue("复杂表头示例");
bigTitleCell.setCellStyle(bigTitleCellStyle);
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 8)); // 合并第一行的所有列
// 创建第二行表头
Row secondHeaderRow = sheet.createRow(1);
String[] secondHeader = {"序号", "个人信息", "工作信息", "", "", "财务信息", "", "", ""};
for (int i = 0; i < secondHeader.length; i++) {
Cell cell = secondHeaderRow.createCell(i);
cell.setCellValue(secondHeader[i]);
cell.setCellStyle(headerCellStyle);
}
// 创建第三行表头
Row thirdHeaderRow = sheet.createRow(2);
String[] thirdHeader = {"", "姓名", "性别", "部门", "职位", "入职日期", "工资", "奖金", "备注"};
for (int i = 0; i < thirdHeader.length; i++) {
Cell cell = thirdHeaderRow.createCell(i);
cell.setCellValue(thirdHeader[i]);
cell.setCellStyle(headerCellStyle);
}
// 合并二级表头的单元格
mergeCells(sheet, 1, 1, 1, 2); // 合并 "个人信息"
mergeCells(sheet, 1, 1, 3, 4); // 合并 "工作信息"
mergeCells(sheet, 1, 1, 5, 7); // 合并 "财务信息"
// 设置单元格背景颜色
CellStyle colorCellStyle = createCellStyle(workbook, "宋体", 12, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, true, IndexedColors.LIGHT_GREEN.getIndex());
thirdHeaderRow.getCell(1).setCellStyle(colorCellStyle);
thirdHeaderRow.getCell(3).setCellStyle(colorCellStyle);
thirdHeaderRow.getCell(5).setCellStyle(colorCellStyle);
// 设置单元格字体颜色
CellStyle fontColorCellStyle = createCellStyle(workbook, "宋体", 12, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER, true, null, IndexedColors.RED.getIndex());
thirdHeaderRow.getCell(6).setCellStyle(fontColorCellStyle);
// 示例数据
List<Map<String, Object>> dataList = new ArrayList<>();
Map<String, Object> data1 = new HashMap<>();
data1.put("序号", 1);
data1.put("姓名", "张三");
data1.put("性别", "男");
data1.put("年龄", 28);
data1.put("部门", "研发部");
data1.put("职位", "软件工程师");
data1.put("入职日期", "2020-01-01");
data1.put("工资", 8000.00);
data1.put("备注", "");
dataList.add(data1);
// 填充数据
int rowNum = 3; // 数据从第四行开始
for (Map<String, Object> data : dataList) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue((Integer) data.get("序号"));
row.createCell(1).setCellValue((String) data.get("姓名"));
row.createCell(2).setCellValue((String) data.get("性别"));
row.createCell(3).setCellValue((Integer) data.get("年龄"));
row.createCell(4).setCellValue((String) data.get("部门"));
row.createCell(5).setCellValue((String) data.get("职位"));
row.createCell(6).setCellValue((String) data.get("入职日期"));
row.createCell(7).setCellValue((Double) data.get("工资"));
row.createCell(8).setCellValue((String) data.get("备注"));
}
// 导出到文件
try (FileOutputStream fileOut = new FileOutputStream("complex_header_example.xlsx")) {
workbook.write(fileOut);
}
// 关闭工作簿
workbook.close();
}
/**
* 创建单元格样式
*
* @param workbook 工作簿
* @param fontName 字体名称
* @param fontSize 字体大小
* @param bold 是否加粗
* @param horizontalAlign 水平对齐方式
* @param verticalAlign 垂直对齐方式
* @param bordered 是否有边框
* @param backgroundColor 背景颜色(可选)
* @param fontColor 字体颜色(可选)
* @return 单元格样式
*/
private static CellStyle createCellStyle(Workbook workbook, String fontName, short fontSize, boolean bold,
HorizontalAlignment horizontalAlign, VerticalAlignment verticalAlign,
boolean bordered, Integer backgroundColor, Integer fontColor) {
CellStyle cellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setFontName(fontName);
font.setFontHeightInPoints(fontSize);
font.setBold(bold);
if (fontColor != null) {
font.setColor(fontColor);
}
cellStyle.setFont(font);
cellStyle.setAlignment(horizontalAlign);
cellStyle.setVerticalAlignment(verticalAlign);
if (bordered) {
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
}
if (backgroundColor != null) {
cellStyle.setFillForegroundColor(backgroundColor);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
}
return cellStyle;
}
/**
* 合并单元格
*
* @param sheet 工作表
* @param startRow 开始行索引
* @param endRow 结束行索引
* @param startColumn 开始列索引
* @param endColumn 结束列索引
*/
private static void mergeCells(Sheet sheet, int startRow, int endRow, int startColumn, int endColumn) {
sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, startColumn, endColumn));
}
}
总结
通过上述代码,我们创建了一个具有多级表头和复杂样式的Excel文件,并且实现了单元格的合并、背景颜色和字体颜色的设置。这些功能使得生成的Excel文件更加美观和易读。