在Spring Boot项目中,使用Apache POI库可以实现将数据导出为Excel并嵌入动态生成的折线图。下面为您详细介绍具体的实现步骤、核心代码以及注意事项。
环境准备:添加依赖
首先,在您的pom.xml文件中添加必要的依赖。推荐使用较新版本的POI以确保功能稳定。
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>5.2.3version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>5.2.3version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxml-schemasartifactId>
<version>4.1.2version>
dependency>
dependencies>
定义数据模型
为了清晰管理图表数据和在Excel中的位置,建议先定义两个实体类。 1. 折线图数据模型 (LineChart): 这个类用于封装折线图的所有元素,包括标题、数据系列和X轴标签。
@Data
@Accessors(chain = true)
public class LineChart {
/**
* 图表的名称(主标题)
*/
private String chartTitle;
/**
* 每条折线的名称(图例)
*/
private List<String> titleList;
/**
* 每条折线对应的数据值
*/
private List<List<Double>> dataList;
/**
* X轴的数据点标签(如:月份、季度)
*/
private List<Object> xAxisList;
}
2. 图表位置模型 (ChartPosition): 这个类用于精确定义图表在Excel工作表中的位置和大小。
@Data
@Accessors(chain = true)
public class ChartPosition {
/** 图表左上角所在的列索引(从0开始) */
private int col1;
/** 图表左上角所在的行索引(从0开始) */
private int row1;
/** 图表右下角所在的列索引 */
private int col2;
/** 图表右下角所在的行索引 */
private int row2;
// 以下偏移量通常可设为0
private int dx1 = 0;
private int dy1 = 0;
private int dx2 = 0;
private int dy2 = 0;
}
️ 核心工具类:创建折线图
这是最关键的步骤,我们将创建一个工具类ChartUtils,其中的createLine方法负责在指定的Excel工作表中绘制折线图。
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.xddf.usermodel.chart.*;
public class ChartUtils {
public static void createLine(XSSFSheet sheet, ChartPosition chartPosition, LineChart lineChart) {
// 1. 获取数据
List
业务层整合与导出接口
最后,在Spring Boot的Controller中,将数据导出和图表生成功能整合起来,提供一个HTTP接口供前端调用。
@RestController
public class ExcelExportController {
@GetMapping("/export/excel-with-chart")
public void exportExcelWithChart(HttpServletResponse response) throws IOException {
// 1. 设置响应头,告诉浏览器这是一个要下载的Excel文件
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename="data_with_chart.xlsx"");
// 2. 创建工作簿和工作表
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("数据报表");
// 3. (可选)向工作表填充数据行...
// 例如:createDataRows(sheet);
// 4. 准备折线图数据
LineChart lineChart = new LineChart()
.setChartTitle("销售趋势图")
.setXAxisList(Arrays.asList("1月", "2月", "3月", "4月", "5月"))
.setTitleList(Arrays.asList("产品A", "产品B", "警戒值"))
.setDataList(Arrays.asList(
Arrays.asList(120.0, 150.0, 180.0, 160.0, 200.0),
Arrays.asList(90.0, 120.0, 140.0, 130.0, 150.0),
Arrays.asList(150.0, 150.0, 150.0, 150.0, 150.0) // 警戒线
));
// 5. 定义图表位置(例如:从第0行第0列开始,到第15行第10列结束)
ChartPosition position = new ChartPosition()
.setCol1(0).setRow1(10).setCol2(10).setRow2(25);
// 6. 调用工具类创建折线图
ChartUtils.createLine(sheet, position, lineChart);
// 7. 将工作簿写入HTTP响应流
OutputStream out = response.getOutputStream();
workbook.write(out);
workbook.close();
out.flush();
}
}
关键要点与优化建议
在实际使用中,请注意以下几点以确保最佳效果:
- 版本兼容性:确保所有POI相关依赖(如
poi,poi-ooxml,poi-ooxml-schemas)的版本一致,以避免潜在的冲突。 - 图表位置规划:在插入图表前,最好先规划好数据表格的布局。
ChartPosition中的行索引应考虑表格已占用的行数,防止图表覆盖数据。 - 大数据量优化:当需要导出的数据量非常大时,建议使用
SXSSFWorkbook来代替XSSFWorkbook,它以流式处理方式工作,可以显著降低内存消耗。 - 前端调用:前端Vue或React应用可以使用
axios等库调用此导出接口,并通过处理返回的Blob对象实现文件下载。
通过以上步骤,您就可以在Spring Boot应用中灵活地导出包含专业折线图的Excel报表了。这套方法可以根据实际业务需求,轻松调整以生成柱状图或饼图等其他图表类型。