Java实现Excel带层级关系的数据导出功能
在Java中实现Excel带层级关系的数据导出,可以使用Apache POI库。Apache POI是一个强大的API,用于操作各种基于Office Open XML标准(OOXML)和微软的OLE 2复合文档格式(OLE2)的文件格式,包括Excel文件。
以下是一个简单的示例,展示如何使用Apache POI创建一个带有层级关系的Excel文件。假设我们有一个简单的数据结构,其中每个生产订单(MoHeadDO)可以包含多个子项(MoItemDO),每个子项又可以包含多个工序(MoProcessItemDO)。
1. 添加依赖
首先,确保在你的项目中添加了Apache POI的依赖。如果你使用的是Maven,可以在pom.xml中添加以下依赖:
<dependencies>
<!-- Apache POI for Excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- Apache POI for Excel XSSF (for .xlsx files) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
<!-- XMLBeans for POI -->
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>5.1.1</version>
</dependency>
<!-- Commons Compress for handling compressed files -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
</dependencies>
2. 定义数据模型
假设我们有以下数据模型:
import java.util.List;
// 生产订单主表
public class MoHeadDO {
private String id;
private String name;
private List<MoItemDO> items;
// Getters and Setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<MoItemDO> getItems() {
return items;
}
public void setItems(List<MoItemDO> items) {
this.items = items;
}
}
// 生产订单子表
public class MoItemDO {
private String id;
private String description;
private List<MoProcessItemDO> processItems;
// Getters and Setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<MoProcessItemDO> getProcessItems() {
return processItems;
}
public void setProcessItems(List<MoProcessItemDO> processItems) {
this.processItems = processItems;
}
}
// 生产订单工序子表
public class MoProcessItemDO {
private String id;
private String processName;
// Getters and Setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getProcessName() {
return processName;
}
public void setProcessName(String processName) {
this.processName = processName;
}
}
3. 实现Excel导出功能
创建一个类来处理Excel导出逻辑:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
public class ExcelExporter {
public void exportToExcel(List<MoHeadDO> moHeadList, String filePath) throws IOException {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Production Orders");
// Create header row
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("Order ID");
headerRow.createCell(1).setCellValue("Order Name");
headerRow.createCell(2).setCellValue("Item ID");
headerRow.createCell(3).setCellValue("Item Description");
headerRow.createCell(4).setCellValue("Process ID");
headerRow.createCell(5).setCellValue("Process Name");
int rowNum = 1;
for (MoHeadDO moHead : moHeadList) {
for (MoItemDO moItem : moHead.getItems()) {
for (MoProcessItemDO moProcessItem : moItem.getProcessItems()) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(moHead.getId());
row.createCell(1).setCellValue(moHead.getName());
row.createCell(2).setCellValue(moItem.getId());
row.createCell(3).setCellValue(moItem.getDescription());
row.createCell(4).setCellValue(moProcessItem.getId());
row.createCell(5).setCellValue(moProcessItem.getProcessName());
}
}
}
// Auto-size columns
for (int i = 0; i < 6; i++) {
sheet.autoSizeColumn(i);
}
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
workbook.write(fileOut);
}
workbook.close();
}
}
4. 使用示例
创建一些示例数据并导出到Excel文件:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
List<MoHeadDO> moHeadList = new ArrayList<>();
// Create some sample data
MoHeadDO moHead1 = new MoHeadDO();
moHead1.setId("001");
moHead1.setName("Order 001");
MoItemDO moItem1 = new MoItemDO();
moItem1.setId("001-01");
moItem1.setDescription("Item 001-01");
MoProcessItemDO moProcessItem1 = new MoProcessItemDO();
moProcessItem1.setId("001-01-01");
moProcessItem1.setProcessName("Process 001-01-01");
MoProcessItemDO moProcessItem2 = new MoProcessItemDO();
moProcessItem2.setId("001-01-02");
moProcessItem2.setProcessName("Process 001-01-02");
moItem1.setProcessItems(List.of(moProcessItem1, moProcessItem2));
moHead1.setItems(List.of(moItem1));
moHeadList.add(moHead1);
// Export to Excel
ExcelExporter exporter = new ExcelExporter();
exporter.exportToExcel(moHeadList, "production_orders.xlsx");
System.out.println("Excel file has been created successfully.");
}
}
5. 运行结果
运行上述代码后,会在项目的根目录下生成一个名为 production_orders.xlsx 的Excel文件,内容如下:
Order ID Order Name Item ID Item Description Process ID Process Name
001 Order 001 001-01 Item 001-01 001-01-01 Process 001-01-01
001 Order 001 001-01 Item 001-01 001-01-02 Process 001-01-02
6. 增强功能
为了更好地展示层级关系,可以使用Excel的分组功能。以下是增强后的示例代码,展示如何使用分组来表示层级关系:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
public class ExcelExporter {
public void exportToExcel(List<MoHeadDO> moHeadList, String filePath) throws IOException {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Production Orders");
// Create header row
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("Order ID");
headerRow.createCell(1).setCellValue("Order Name");
headerRow.createCell(2).setCellValue("Item ID");
headerRow.createCell(3).setCellValue("Item Description");
headerRow.createCell(4).setCellValue("Process ID");
headerRow.createCell(5).setCellValue("Process Name");
int rowNum = 1;
for (MoHeadDO moHead : moHeadList) {
int startRow = rowNum;
for (MoItemDO moItem : moHead.getItems()) {
int itemStartRow = rowNum;
for (MoProcessItemDO moProcessItem : moItem.getProcessItems()) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(moHead.getId());
row.createCell(1).setCellValue(moHead.getName());
row.createCell(2).setCellValue(moItem.getId());
row.createCell(3).setCellValue(moItem.getDescription());
row.createCell(4).setCellValue(moProcessItem.getId());
row.createCell(5).setCellValue(moProcessItem.getProcessName());
}
// Group by Item
sheet.groupRow(itemStartRow, rowNum - 1);
}
// Group by Order
sheet.groupRow(startRow, rowNum - 1);
}
// Auto-size columns
for (int i = 0; i < 6; i++) {
sheet.autoSizeColumn(i);
}
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
workbook.write(fileOut);
}
workbook.close();
}
}
7.增强效果
运行上述代码后,生成的Excel文件将包含分组,展示层级关系:
• Order 001
• Item 001-01
• Process 001-01-01
• Process 001-01-02
通过这种方式,可以更清晰地展示生产订单、子项和工序之间的层级关系。
总结
通过使用Apache POI库,可以方便地在Java中创建带有层级关系的Excel文件。通过分组功能,可以进一步增强Excel文件的可读性和结构化展示。