springboot對接poi實現(xiàn)導(dǎo)出excel并動態(tài)生成折線圖
在Spring Boot項目中,使用Apache POI庫可以實現(xiàn)將數(shù)據(jù)導(dǎo)出為Excel并嵌入動態(tài)生成的折線圖。下面為您詳細(xì)介紹具體的實現(xiàn)步驟、核心代碼以及注意事項。
環(huán)境準(zhǔn)備:添加依賴
首先,在您的pom.xml文件中添加必要的依賴。推薦使用較新版本的POI以確保功能穩(wěn)定。
<dependencies>
<!-- Spring Boot Web 支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Apache POI 核心庫 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<!-- 處理 xlsx 格式的OOXML支持 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- 可選的模式支持,某些圖表功能需要 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
</dependencies>
定義數(shù)據(jù)模型
為了清晰管理圖表數(shù)據(jù)和在Excel中的位置,建議先定義兩個實體類。
??1. 折線圖數(shù)據(jù)模型 (LineChart):?? 這個類用于封裝折線圖的所有元素,包括標(biāo)題、數(shù)據(jù)系列和X軸標(biāo)簽。
@Data
@Accessors(chain = true)
public class LineChart {
/**
* 圖表的名稱(主標(biāo)題)
*/
private String chartTitle;
/**
* 每條折線的名稱(圖例)
*/
private List<String> titleList;
/**
* 每條折線對應(yīng)的數(shù)據(jù)值
*/
private List<List<Double>> dataList;
/**
* X軸的數(shù)據(jù)點標(biāo)簽(如:月份、季度)
*/
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;
// 以下偏移量通常可設(shè)為0
private int dx1 = 0;
private int dy1 = 0;
private int dx2 = 0;
private int dy2 = 0;
}
核心工具類:創(chuàng)建折線圖
這是最關(guān)鍵的步驟,我們將創(chuàng)建一個工具類ChartUtils,其中的createLine方法負(fù)責(zé)在指定的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. 獲取數(shù)據(jù)
List<Object> xAxisList = lineChart.getXAxisList();
List<String> chartTitleList = lineChart.getTitleList();
List<List<Double>> chartDataList = lineChart.getDataList();
String chartTitle = lineChart.getChartTitle();
// 2. 創(chuàng)建繪圖對象和圖表錨點
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0,
chartPosition.getCol1(), chartPosition.getRow1(),
chartPosition.getCol2(), chartPosition.getRow2());
// 3. 創(chuàng)建圖表并設(shè)置標(biāo)題
XSSFChart chart = drawing.createChart(anchor);
chart.setTitleText(chartTitle);
chart.setTitleOverlay(false);
// 4. 設(shè)置圖例位置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.TOP);
// 5. 創(chuàng)建坐標(biāo)軸
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
// 6. 準(zhǔn)備數(shù)據(jù)源
// 6.1 X軸數(shù)據(jù)(類別)
XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(
Arrays.copyOf(xAxisList.toArray(), xAxisList.size(), String[].class));
// 6.2 創(chuàng)建折線圖數(shù)據(jù)對象
XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
// 7. 為每個數(shù)據(jù)系列創(chuàng)建折線
for (int i = 0; i < chartDataList.size(); i++) {
List<Double> values = chartDataList.get(i);
// 創(chuàng)建Y軸數(shù)據(jù)源
XDDFNumericalDataSource<Double> dataSource = XDDFDataSourcesFactory.fromArray(
values.toArray(new Double[0]));
// 將數(shù)據(jù)系列添加到圖表
XDDFLineChartData.Series series = (XDDFLineChartData.Series) data.addSeries(countries, dataSource);
series.setTitle(chartTitleList.get(i), null);
series.setSmooth(false); // 設(shè)置為折線,非平滑曲線
series.setMarkerSize((short) 2); // 設(shè)置數(shù)據(jù)點標(biāo)記的大小
// (可選)特殊樣式處理,例如為"警戒值"設(shè)置虛線
if ("警戒值".equals(chartTitleList.get(i))) {
XDDFLineProperties lineProps = new XDDFLineProperties();
lineProps.setPresetDash(new XDDFPresetLineDash(PresetLineDash.DOT));
series.setLineProperties(lineProps);
}
}
// 8. 繪制圖表
chart.plot(data);
}
}
業(yè)務(wù)層整合與導(dǎo)出接口
最后,在Spring Boot的Controller中,將數(shù)據(jù)導(dǎo)出和圖表生成功能整合起來,提供一個HTTP接口供前端調(diào)用。
@RestController
public class ExcelExportController {
@GetMapping("/export/excel-with-chart")
public void exportExcelWithChart(HttpServletResponse response) throws IOException {
// 1. 設(shè)置響應(yīng)頭,告訴瀏覽器這是一個要下載的Excel文件
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename="data_with_chart.xlsx"");
// 2. 創(chuàng)建工作簿和工作表
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("數(shù)據(jù)報表");
// 3. (可選)向工作表填充數(shù)據(jù)行...
// 例如:createDataRows(sheet);
// 4. 準(zhǔn)備折線圖數(shù)據(jù)
LineChart lineChart = new LineChart()
.setChartTitle("銷售趨勢圖")
.setXAxisList(Arrays.asList("1月", "2月", "3月", "4月", "5月"))
.setTitleList(Arrays.asList("產(chǎn)品A", "產(chǎn)品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列結(jié)束)
ChartPosition position = new ChartPosition()
.setCol1(0).setRow1(10).setCol2(10).setRow2(25);
// 6. 調(diào)用工具類創(chuàng)建折線圖
ChartUtils.createLine(sheet, position, lineChart);
// 7. 將工作簿寫入HTTP響應(yīng)流
OutputStream out = response.getOutputStream();
workbook.write(out);
workbook.close();
out.flush();
}
}
關(guān)鍵要點與優(yōu)化建議
在實際使用中,請注意以下幾點以確保最佳效果:
- ??版本兼容性??:確保所有POI相關(guān)依賴(如
poi,poi-ooxml,poi-ooxml-schemas)的版本一致,以避免潛在的沖突。 - ??圖表位置規(guī)劃??:在插入圖表前,最好先規(guī)劃好數(shù)據(jù)表格的布局。
ChartPosition中的行索引應(yīng)考慮表格已占用的行數(shù),防止圖表覆蓋數(shù)據(jù)。 - ??大數(shù)據(jù)量優(yōu)化??:當(dāng)需要導(dǎo)出的數(shù)據(jù)量非常大時,建議使用
SXSSFWorkbook來代替XSSFWorkbook,它以流式處理方式工作,可以顯著降低內(nèi)存消耗。 - ??前端調(diào)用??:前端Vue或React應(yīng)用可以使用
axios等庫調(diào)用此導(dǎo)出接口,并通過處理返回的Blob對象實現(xiàn)文件下載。
通過以上步驟,您就可以在Spring Boot應(yīng)用中靈活地導(dǎo)出包含專業(yè)折線圖的Excel報表了。這套方法可以根據(jù)實際業(yè)務(wù)需求,輕松調(diào)整以生成柱狀圖或餅圖等其他圖表類型。
到此這篇關(guān)于springboot對接poi實現(xiàn)導(dǎo)出excel并動態(tài)生成折線圖的文章就介紹到這了,更多相關(guān)springboot導(dǎo)出excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot+EasyPOI實現(xiàn)百萬級數(shù)據(jù)導(dǎo)出Excel實戰(zhàn)指南
- SpringBoot整合EasyPoi實現(xiàn)復(fù)雜多級表頭Excel導(dǎo)出的完整方案
- SpringBoot集成EasyExcel實現(xiàn)百萬級別的數(shù)據(jù)導(dǎo)入導(dǎo)出實踐指南
- SpringBoot后臺使用EasyExcel實現(xiàn)數(shù)據(jù)報表導(dǎo)出(含模板、樣式、美化)
- SpringBoot導(dǎo)出Excel的四種方式小結(jié)
- SpringBoot集成Apache POI實現(xiàn)Excel的導(dǎo)入導(dǎo)出
相關(guān)文章
Windows10系統(tǒng)下修改jar中的文件并重新打包成jar文件然后運行的操作步驟
這篇文章主要介紹了Windows10系統(tǒng)下修改jar中的文件并重新打包成jar文件然后運行的操作步驟,文中通過圖文結(jié)合的形式給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-08-08
Springboot集成minio實現(xiàn)文件存儲的實現(xiàn)代碼
MinIO?是一款基于Go語言的高性能對象存儲服務(wù),本文主要介紹了Springboot集成minio實現(xiàn)文件存儲的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
如何通過RabbitMq實現(xiàn)動態(tài)定時任務(wù)詳解
工作中經(jīng)常會有定時任務(wù)的需求,常見的做法可以使用Timer、Quartz、Hangfire等組件,這次想嘗試下新的思路,使用RabbitMQ死信隊列的機(jī)制來實現(xiàn)定時任務(wù),下面這篇文章主要給大家介紹了關(guān)于如何通過RabbitMq實現(xiàn)動態(tài)定時任務(wù)的相關(guān)資料,需要的朋友可以參考下2022-01-01
Springboot Redis?哨兵模式的實現(xiàn)示例
本文主要介紹了Springboot Redis?哨兵模式的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
IntelliJ IDEA導(dǎo)入Gradle項目的方法
這篇文章主要介紹了IntelliJ IDEA導(dǎo)入Gradle項目的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03

