如何用SpringBoot+Thymeleaf+Echart生成好看的柱状图,折线图,饼状图
一、前言
上篇文章我们用POI技术读取Excel并生成了相应的图表。但是实际的效果比较一般,因为本身WPS生成图表就比较简单,如果用程序操作远比人工耗时费力,效果远不如一些付费模板。如下图所示:
然后我就想到前端不是有一个简单易上手的Echart.js是专门做图表。所以就用它去做图表生成,后台数据解析还是用springBoot+Ajax+POI工具类。这样实现的效果就会好看和实用很多。来看一下效果图。
二、准备数据
1、首先新建一个xls统计表。
2、数据填充
手机型号 测评分数 销售数量
OPPO Reno9 Pro+ 5G 1210365 7523423
Xiaomi 12 Pro天现版 1187600 343242
ROG游戏手机6 天现至尊版 1187449 535362
一加 Ace Pro 1183234 83234
小米12S Pro 1176850 2346625
Redmi K50 至尊版 1172517 4324324
Xiaomi 12S 1164309 3424234
联想救者 Y90 1164235 234434
小米MIX FOLD 2 1164109 32423432
iQo0 10 Pro 1151258 9403424
三、前端代码
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title>ECharts</title><!-- 引入刚刚下载的 ECharts 文件 --><!-- <script src="https://cdn.staticfile.org/jquery/3.6.1/jquery.min.js"></script>--><!-- 引入 echarts.js --><!-- <script src="https://cdn.staticfile.org/echarts/5.3.0/echarts.min.js"></script>--><script src="./js/echarts.min.js"></script><script src="./js/jquery-3.6.1.min.js"></script></head>
<body>
<div id="title" style="width:1200px;height:100px"></div>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="line" style="width: 1200px;height:800px;"></div>
<div id="pie" style="width: 1200px;height:800px;"></div>
<div id="bak" style="width:200px;height:100px"></div>
<div id="bar" style="width: 1200px;height:800px;"></div><script type="text/javascript">var title = echarts.init(document.getElementById('title'));// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('bar'));var pieChart = echarts.init(document.getElementById('pie'));var lineChart = echarts.init(document.getElementById('line'));var titleOption = {graphic: {elements: [{type: 'text',left: 'center',top: 'center',style: {text: '手机性能统计图',fontSize: 50,fontWeight: 'bold',lineDash: [0, 200],lineDashOffset: 0,fill: 'transparent',stroke: '#000',lineWidth: 1},keyframeAnimation: {duration: 3000,loop: true,keyframes: [{percent: 0.7,style: {fill: 'transparent',lineDashOffset: 200,lineDash: [200, 0]}},{// Stop for a while.percent: 0.8,style: {fill: 'transparent'}},{percent: 1,style: {fill: 'gray'}}]}}]}};$.ajax({type:"post",async:true,url:"/getData",dataType:"json",success:function (data) {if (data) {// 指定图表的配置项和数据var barOption = {title: {text: '手机性能柱状统计图'},tooltip: {},legend: {data: ['手机性能柱状统计图']},xAxis: {data: data[0].key,},yAxis: {},color: '#fac858',series: [{name: '评测分数',type: 'bar',data: data[0].value,}]};// 指定图表的配置项和数据var lineOption = {title: {text: '折线柱状统计图'},tooltip: {},legend: {data: ['品牌销量', '品牌评测分数']},xAxis: {data: data[0].key,},yAxis: {type: "log",},series: [{name: '品牌销量',type: 'line',data: data[1].value}, {name: '品牌评测分数',type: 'line',data: data[0].value}]};var pieOption = {title: {text: '品牌销量占比饼状图'},tooltip: {trigger: 'item'},legend: {top: '85%',left: 'center'},series: [{name: '品牌销量占比饼状图',type: 'pie',radius: ['30%', '70%'],avoidLabelOverlap: false,itemStyle: {borderRadius: 10,borderColor: '#fff',borderWidth: 2},label: {show: false,position: 'center'},emphasis: {label: {show: true,fontSize: 40,fontWeight: 'bold'}},labelLine: {show: false},data: data[2]}]};title.setOption(titleOption);// 使用刚指定的配置项和数据显示图表。myChart.setOption(barOption);lineChart.setOption(lineOption);pieChart.setOption(pieOption);}},error:function (errorMsg) {alert("图表请求数据失败!");myChart.hideLoading();totalChart.hideLoading();lineChart.hideLoading();pieChart.hideLoading();}
});
</script>
</body>
</html>
其中需要注意的是js依赖文件可以本地下载好引用本地。–适用于内网
或者将注释打开,直接从互联网依赖。–适用于外网
使用div布局,绑定各组件变量
标题组件定义
ajax异步请求及组件定义
绑定组件及ajax请求失败的处理方式。
四、后端代码
还是创建一个springboot功能。
1、配置文件application.yaml
server:port: 9999
resources:static-locations: classpath:/templates/, classpath:/static/
thymeleaf:prefix: classpath:/templates/ #thģ������·��suffix: .htmlmode: HTML5encoding: UTF-8cache: false
2、pom依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.icbc</groupId><artifactId>echartdemo</artifactId><version>1.0-SNAPSHOT</version><name>boottest</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.7.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target><poi-version>3.11</poi-version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.lucee</groupId><artifactId>jsch</artifactId><version>0.1.53</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency><!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.25</version><!-- <scope>test</scope> --></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.11</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.xmlbeans</groupId><artifactId>xmlbeans</artifactId><version>3.1.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.36</version></dependency></dependencies><build><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-jar-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin><!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --><plugin><artifactId>maven-site-plugin</artifactId><version>3.7.1</version></plugin><plugin><artifactId>maven-project-info-reports-plugin</artifactId><version>3.0.0</version></plugin></plugins></pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
</project>
3、在resource下创建templates目录,并将html放入
4、启动类
package com.icbc.echartdemo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class EchartdemoApplication {public static void main(String[] args) {SpringApplication.run(EchartdemoApplication.class, args);}}
5、excel数据处理工具类
package com.icbc.echartdemo;import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xddf.usermodel.PresetColor;
import org.apache.poi.xddf.usermodel.XDDFColor;
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDLbls;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;/*** ClassName: ExcelChartUtils <br/>* Description: 导出excel中绘制图表<br/>* date: 2022/11/17 11:39<br/>** @author DELL<br />* @since JDK 1.8*/
public class ExcelChartUtils2 {public static final String READ_FILE_PATH = "C:\\Users\\Administrator\\Desktop\\统计.xls";public static void main(String[] args) throws IOException {ExcelChartUtils2 excelChartUtils=new ExcelChartUtils2();XSSFWorkbook wb = new XSSFWorkbook();
// String sheetName = "当月业务量统计";
// String sheetName2 = "本周高频报错业务统计";
// String sheetName3 = "本周高频报错占比统计";
// excelChartUtils.exportLineDiagram(wb,sheetName2);
// excelChartUtils.exportPieDirgram(wb,sheetName3);
// excelChartUtils.exportBarDiagram(wb,sheetName);}public void exportPieDirgram(XSSFWorkbook wb,String sheetName){XSSFSheet sheet = wb.createSheet(sheetName);// 创建一个画布XSSFDrawing drawing = sheet.createDrawingPatriarch();// 前四个默认0,[0,4]:从0列4行开始;[7,20]:到7列20行结束// 默认宽度(14-8)*12XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 30, 40);// 创建一个chart对象XSSFChart chart = drawing.createChart(anchor);// 标题chart.setTitleText("高频报错占比统计");// 标题是否覆盖图表chart.setTitleOverlay(false);// 图例位置XDDFChartLegend legend = chart.getOrAddLegend();legend.setPosition(LegendPosition.TOP_RIGHT);//解析数据Map<String, List<String>> dataMap = ExcelChartUtils2.getData(READ_FILE_PATH,3,0,6);;List<String> keylist = dataMap.get("key");List<String> valueList = dataMap.get("value");List<Integer> vList = new ArrayList<>();for(int i = 0;i<valueList.size();i++){if(valueList.get(i).isEmpty()){vList.add(0);}else{vList.add(Integer.valueOf(valueList.get(i).split("\\.")[0]));}}//XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(0, 0, 0, 6));//从指定表格中的位置上获取对应数据XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(keylist.toArray(new String[keylist.size()]));// 数据1,单元格范围位置[1, 0]到[1, 6]// XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, 6));XDDFNumericalDataSource<Integer> area = XDDFDataSourcesFactory.fromArray(vList.toArray(new Integer[vList.size()]));// XDDFChartData data = chart.createData(ChartTypes.PIE3D, null, null);XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);// 设置为可变颜色data.setVaryColors(true);// 图表加载数据data.addSeries(countries, area);// 绘制chart.plot(data);CTDLbls dLbls = chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDLbls();dLbls.addNewShowVal().setVal(false);dLbls.addNewShowLegendKey().setVal(false);dLbls.addNewShowCatName().setVal(true);// 类别名称dLbls.addNewShowSerName().setVal(false);dLbls.addNewShowPercent().setVal(true);// 百分比dLbls.addNewShowLeaderLines().setVal(true);// 引导线dLbls.setSeparator("\n");// 分隔符为分行符dLbls.addNewDLblPos().setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STDLblPos.Enum.forString("inEnd"));// 数据标签内// 打印图表的xml// System.out.println(chart.getCTChart());}public void exportLineDiagram(XSSFWorkbook wb,String sheetName) throws IOException {FileOutputStream fileOut = null;XSSFSheet sheet = wb.createSheet(sheetName);// 创建一个画布XSSFDrawing drawing = sheet.createDrawingPatriarch();// 前四个默认0,[0,5]:从0列5行开始;[7,26]:到7列26行结束// 默认宽度(14-8)*12XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 30, 40);// 创建一个chart对象XSSFChart chart = drawing.createChart(anchor);// 标题chart.setTitleText("高频报错业务统计");// 标题覆盖chart.setTitleOverlay(false);// 图例位置XDDFChartLegend legend = chart.getOrAddLegend();legend.setPosition(LegendPosition.TOP);// 分类轴标(X轴),标题位置XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.LEFT);// bottomAxis.setTitle("国家");// 值(Y轴)轴,标题位置XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.BOTTOM);// leftAxis.setTitle("面积大小");Map<String, List<String>> dataMap = ExcelChartUtils2.getData(READ_FILE_PATH,3,2,6);List<String> keylist = dataMap.get("key");List<String> valueList = dataMap.get("value");List<Integer> vList = new ArrayList<>();for(int i = 0;i<valueList.size();i++){if(valueList.get(i).isEmpty()){vList.add(0);}else{vList.add(Integer.valueOf(valueList.get(i).split("\\.")[0]));}}
// keylist.remove(0);
// valueList.remove(0);// CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)// 分类轴标(X轴)数据,单元格范围位置[0, 0]到[0, 6]//XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(0, 0, 0, 6));//从指定表格中的位置上获取对应数据XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(keylist.toArray(new String[keylist.size()]));// 数据1,单元格范围位置[1, 0]到[1, 6]// XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, 6));XDDFNumericalDataSource<Integer> area = XDDFDataSourcesFactory.fromArray(vList.toArray(new Integer[vList.size()]));// bar:条形图,XDDFLineChartData bar = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);// 设置为可变颜色bar.setVaryColors(false);// 如果需要设置成自己想要的颜色,这里可变颜色要设置成false// 图表加载数据,条形图XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) bar.addSeries(countries, area);// 条形图例标题series1.setTitle("业务量统计", null);XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.BLUE));// 条形图,填充颜色series1.setFillProperties(fill);// 绘制chart.plot(bar);// CTBarSer ser = chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0);// CTLegend legend2 = chart.getCTChartSpace().getChart().getLegend();//更详细的图例设置// 打印图表的xmlSystem.out.println(chart.getCTChart());}public String exportBarDiagram(XSSFWorkbook wb,String sheetName) throws IOException {FileOutputStream fileOut = null;try {XSSFSheet sheet = wb.createSheet(sheetName);// 创建一个画布XSSFDrawing drawing = sheet.createDrawingPatriarch();// 前四个默认0,[0,5]:从0列5行开始;[7,26]:到7列26行结束// 默认宽度(14-8)*12XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 30, 40);// 创建一个chart对象XSSFChart chart = drawing.createChart(anchor);// 标题chart.setTitleText("业务量统计");// 标题覆盖chart.setTitleOverlay(false);// 图例位置XDDFChartLegend legend = chart.getOrAddLegend();legend.setPosition(LegendPosition.TOP);// 分类轴标(X轴),标题位置XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);// bottomAxis.setTitle("国家");// 值(Y轴)轴,标题位置XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);// leftAxis.setTitle("面积大小");Map<String, List<String>> dataMap = ExcelChartUtils2.getData(READ_FILE_PATH,4,2,6);List<String> keylist = dataMap.get("key");List<String> valueList = dataMap.get("value");List<Integer> vList = new ArrayList<>();for(int i = 0;i<valueList.size();i++){if(valueList.get(i).isEmpty()){vList.add(0);}else{vList.add(Integer.valueOf(valueList.get(i).split("\\.")[0]));}}
// keylist.remove(0);
// valueList.remove(0);// CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)// 分类轴标(X轴)数据,单元格范围位置[0, 0]到[0, 6]//XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(0, 0, 0, 6));//从指定表格中的位置上获取对应数据XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(keylist.toArray(new String[keylist.size()]));// 数据1,单元格范围位置[1, 0]到[1, 6]// XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, 6));XDDFNumericalDataSource<Integer> area = XDDFDataSourcesFactory.fromArray(vList.toArray(new Integer[vList.size()]));// bar:条形图,XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);// 设置为可变颜色bar.setVaryColors(false);// 如果需要设置成自己想要的颜色,这里可变颜色要设置成false// 条形图方向,纵向/横向:纵向bar.setBarDirection(BarDirection.COL);// 图表加载数据,条形图1XDDFBarChartData.Series series1 = (XDDFBarChartData.Series) bar.addSeries(countries, area);// 条形图例标题series1.setTitle("业务量统计", null);XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.BLUE));// 条形图,填充颜色series1.setFillProperties(fill);// 绘制chart.plot(bar);// CTBarSer ser = chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0);// CTLegend legend2 = chart.getCTChartSpace().getChart().getLegend();//更详细的图例设置// 打印图表的xmlSystem.out.println(chart.getCTChart());// 将输出写入excel文件// String filename = "排行榜前七的国家.xlsx";// out = new FileOutputStream(getAbsoluteFile(filename));String filename = encodingFilename();fileOut = new FileOutputStream("E:\\"+File.separator+filename);wb.write(fileOut);} catch (Exception e) {e.printStackTrace();} finally {wb.close();if (fileOut != null) {fileOut.close();}}return "success";}public static Map<String,List<String>> getData(String filePath, int sheetIndex,int keyNum,int valueNum){Map<String, List<String>> resMap = new HashMap<>();FileInputStream fis = null;HSSFWorkbook workbook = null;List<String> keylist = new ArrayList();List<String> valueList = new ArrayList<>();try {fis = new FileInputStream(filePath);workbook = new HSSFWorkbook(fis);Sheet sheet = workbook.getSheetAt(sheetIndex);Row row;Cell cell;for (int i = 1; i < sheet.getLastRowNum(); i++) {row = sheet.getRow(i);cell = row.getCell(keyNum); // 0 is the column indexSystem.out.println(cell.getStringCellValue());keylist.add(cell.getStringCellValue());cell = row.getCell(valueNum); // 0 is the column indexdouble numericCellValue;if(cell.getCellType().equals(CellType.NUMERIC)){numericCellValue = cell.getNumericCellValue();}else {numericCellValue = Double.valueOf(cell.getStringCellValue());}valueList.add( String.valueOf(numericCellValue) );}System.out.println("name:"+keylist);System.out.println("value:"+valueList);workbook.close();fis.close();} catch (IOException e) {e.printStackTrace();}
// resMap.put("key",keylist.toArray(new String[keylist.size()]));
// resMap.put("value",valueList.toArray(new String[valueList.size()]));resMap.put("key",keylist);resMap.put("value",valueList);return resMap;}/*** 编码文件名*/public String encodingFilename(){String filename = UUID.randomUUID().toString() + ".xlsx";//String filename = "20230222.xlsx";return filename;}/*** 获取下载路径** @param filename 文件名称*/public String getAbsoluteFile(String filename){String downloadPath = "d://";File desc = new File(downloadPath);if (!desc.getParentFile().exists()){desc.getParentFile().mkdirs();}return downloadPath;}
}
6、controller处理类
package com.icbc.echartdemo;import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;import java.util.ArrayList;
import java.util.List;
import java.util.Map;import static com.icbc.echartdemo.ExcelChartUtils2.READ_FILE_PATH;/*** @Author stalin* @Desc Echarts入门案例*/
@RestController
public class EchartController {@RequestMapping(value = "/echarts", method = RequestMethod.GET)@ResponseBodypublic ModelAndView echarts() {//test为在为你的html文件名字,SpringBoot会自动找到这个html文件return new ModelAndView("echart");}@RequestMapping("/getData")@ResponseBodypublic JSONArray getData() {List<ReportData> dataList = new ArrayList<>();Map<java.lang.String, List<java.lang.String>> dataMap = ExcelChartUtils2.getData(READ_FILE_PATH, 0, 0, 1);JSONArray arr = new JSONArray();JSONObject obj = new JSONObject();obj.put("key", dataMap.get("key"));obj.put("value", dataMap.get("value"));Map<java.lang.String, List<java.lang.String>> dataMap2 = ExcelChartUtils2.getData(READ_FILE_PATH, 0, 0, 2);arr.clear();arr.add(obj);JSONObject obj2 = new JSONObject();obj2.put("key", dataMap2.get("key"));obj2.put("value", dataMap2.get("value"));arr.add(obj2);JSONArray array = new JSONArray();List<String> key = dataMap.get("key");List<String> value = dataMap.get("value");for (int i = 0; i < key.size(); i++) {JSONObject o = new JSONObject();o.put("name", key.get(i));o.put("value", value.get(i));array.add(o);}arr.add(array);return arr;}// @RequestMapping(value = "/index", method = RequestMethod.GET)
// @ResponseBody
// public ModelAndView index() {
// //test为在为你的html文件名字,SpringBoot会自动找到这个html文件
// return new ModelAndView("index");
// }
}
注意:html名字与要返回的ModelAndView名字要一致。否则后端程序会找不到对应的页面。
然后启动项目即可。
相关文章:
如何用SpringBoot+Thymeleaf+Echart生成好看的柱状图,折线图,饼状图
一、前言 上篇文章我们用POI技术读取Excel并生成了相应的图表。但是实际的效果比较一般,因为本身WPS生成图表就比较简单,如果用程序操作远比人工耗时费力,效果远不如一些付费模板。如下图所示: 然后我就想到前端不是有一个简单易…...
LeetCode819. 最常见的单词(python)
题目 给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。 题目保证至少有一个词不在禁用列表中,而且答案唯一。 禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。…...
【深入理解C指针】经典笔试题——指针和数组
🔹内容专栏:【C语言】进阶部分 🔹本文概括:一些指针和数组笔试题的解析 。 🔹本文作者:花香碟自来_ 🔹发布时间:2023.3.12 目录 一、指针和数组练习题 1. 一维数组 2. 字符数组 …...
雷达散射截面
雷达散射截面(Radar Cross Section, RCS)是表征目标散射强弱的物理量。 σ = 4 π R 2 ∣ E s ∣ 2 ∣ E i ∣ 2 \sigma = 4\pi R^2 \frac{|E_s |^2}{|E_i|^2}...
希腊棺材之谜——复盘
文章目录梗概推导伪解答虽然花费6-8小时来看小说,是一件很奢侈的事情。但是再荒诞的事情终归有它背后的逻辑链条。这正如Ellery所坚持的那样,逻辑为王。希腊棺材之谜是Ellery Queen首次展露头角, 因此作者特地给他安排了3次伪解答和1次真解答…...
CentOS的下载和安装
文章目录前言一、CentOS的下载二、如何下载1.选择下载版本2.选择isos3.点击isos后,进入如下页面,接着点击X86_644.一般选择下面框住的进行下载三、安装软件选择设置接着进行分区设置设置网络和主机名前言 在学习Linux时,记录下CentOS的安装 …...
new bing的chatGPT如何解析英文论文pdf
昨天我的new bing申请下来了,有了聊天的界面: 但是解析pdf的英文文献,还是不行,没有对话窗口。就问了一下chatGPT,方案如下: 要使用New Bing解析PDF文献,你需要以下几个步骤: 1&a…...
学会这12个Python装饰器,让你的代码更上一层楼
学会这12个Python装饰器,让你的代码更上一层楼 Python 装饰器是个强大的工具,可帮你生成整洁、可重用和可维护的代码。某种意义上说,会不会用装饰器是区分新手和老鸟的重要标志。如果你不熟悉装饰器,你可以将它们视为将函数作为输…...
企业使用ERP的好处
ERP系统是企业管理信息系统的简称,它是以信息技术为手段,以物流、资金流、信息流为主线,以企业的核心业务流程为对象,建立的一套适用于企业管理的、高效的企业管理信息系统。它是通过科学方法和计算机信息技术,将企业运…...
【QT】如何获取屏幕(桌面)的大小或分辨率
目录1. QDesktopWidget 获取系统屏幕大小2. QScreen 获取系统屏幕大小3. geometry() 与 availableGeometry() 的区别1. QDesktopWidget 获取系统屏幕大小 QDesktopWidget 提供了详细的位置信息,其能够自动返回窗口在用户窗口的位置和应用程序窗口的位置 QDesktopW…...
ETL工具的选择
正确选择 ETL 工具,可以从 ETL 对平台的支持、对数据源的支持、数据转换功能、管理 和调度功能、集成和开放性、对元数据管理等功能出发,具体如下。 支持平台 随着各种应用系统数据量的飞速增长和对业务可靠性等要求的不断提高,人们对数据抽…...
SpringBoot仿天猫商城java web购物网站的设计与实现
1,项目介绍 基于 SpringBoot 的仿天猫商城拥有两种角色,分别为管理员和用户。 迷你天猫商城是一个基于SSM框架的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程。 后端页面兼容IE10及以上现代浏览器,Chrome,Edge,Firebox…...
C#基础教程22 文件的输入与输出
C# 文件的输入与输出 一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。 从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操作),输出流用于向文件写入数…...
Ubuntu18.04 python 开发usb通信
一、安装环境 1.安装pip sudo python3 get-pip.py 或 sudo -i apt update apt install python3-pip 确定pip是否安装成功: xxx-desktop:~$ pip3 --versionpip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)2.安装pyusb pip3 install pyusb --use…...
RabbitMq 消息确认机制详解 SpringCloud
1 消息可靠性 消息从发送,到消费者接收,会经理多个过程,其中的每一步都可能导致消息丢失. #### 2 常见的丢失原因 发送时丢失: 生产者发送的消息未送达exchange 消息到达exchange后未到达queueMQ宕机,queue将消息丢失 consumer…...
后台导航布局
五、后台导航实例 参考链接: 页面后台导航制作 如何实现html后台导航iframe点击换url(代码) 如何消除html页面下边和右边的滚动条 html页面有多个滚动条时的优化 页面出现不必要的滚动条,怎么调试? 一个页面有两…...
设计模式——抽象工厂模式(创建型)
一、介绍抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。问题假设你正在开发一款家具商店模拟器。 你的代码中包括一些类, 用于表示:一系列相关产品, 例如 椅子Chair 、 沙发Sofa和…...
Java面试题--SpringMVC的执行流程
概要 SpringMVC是一种基于MVC(Model-View-Controller)框架的Web应用开发框架。下面是SpringMVC的详细执行流程。 客户端向DispatcherServlet发送请求。DispatcherServlet收到请求后,根据HandlerMapping(处理器映射)找…...
c# 32位程序突破2G内存限制
起因 在开发过程中,由于某些COM组件只能在32位程序下运行,程序不得不在X86平台下生成。而X86的32位程序默认内存大小被限制在2G。由于程序中可能存在大数量处理,期间对象若没有及时释放或则回收,内存占用达到了1.2G左右ÿ…...
【C语言】指针详解总结
指针1. 指针是什么2. 指针和指针类型2.1 指针-整数2.2 指针的解引用3. 野指针3.1 野指针成因3.2 如何规避野指针4. 指针运算4.1 指针-整数4.2 指针-指针4.3 指针的关系运算5. 指针和数组6. 二级指针7. 指针数组1. 指针是什么 指针是什么? 指针理解的2个要点…...
Java加解密(八)工具篇
目录Java加解密实用工具1 OpenSSL2 Keytool3 XCA4 KeyStore ExplorerJava加解密实用工具 1 OpenSSL OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。 例如Apache 使用它加…...
Go框架三件套(Web/RPC/ORM)
🧡 三件套介绍 Gorm Gorm 是一个已经迭代了10年的功能强大的 ORM 框架,在字节内部被广泛使用并且拥有非常丰富的开源扩展。 Kitex Kitex 是字节内部的 Golang 微服务 RPC 框架,具有高性能、强可扩展的主要特点,支持多协议并且拥有…...
HR问:假如公司给不到你期望的薪资怎么办?这个问题该如何体面地回答?
对大多数人而言,跳槽就是为了涨薪,工作就是为了挣钱。但如果面试时hr问:假如公司给不到你期望的薪资呢?面对这种问题,该怎么回答才体面?来看一波网友的机智回答:有人委婉拒绝,说“愿…...
LearnOpenGL-高级OpenGL-2.模板测试
本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject 文章目录简单理解模板测试模板介绍模板函数物体轮廓介绍代码给加载的模型添加轮廓简单理解 同深度测试一样…...
【Git从入门到精通】Git入门
什么是版本控制 版本控制是一套系统,按时间记录某一个或一系列文件的变更,查看以前的特定版本。 使用版本控制系统,你可以将文件或者整个项目恢复到先前的状态,还可以对以前的文件进行对比。 本地版本控制系统 本地版本控制系…...
软件测试18
在桌面上打开终端窗口, 执行如下操作: 查看当前系统中开放的端口有哪些查看哪个程序正在使用 3306 端口(需要 root 用户权限) 注意: 1.某些端口号具备固定用途: 例如: 远程访问常用端口号:22 默认情况下是mysql使用的端口号&…...
C语言实现快速排序(hoare法、挖坑法、前后指针法与非递归实现)——不看后悔系列
目录 1. hoare法 方法与步骤 代码实现 2. 挖坑法 方法与步骤 代码实现 3. 前后指针法 方法与步骤 代码实现 4. 快速排序的缺点与优化 1.快速排序的缺点 2.快速排序的优化 ① 三数取中法选 key 代码实现 ② 小区间优化 代码实现 5. 快速排序的非递归实现 附录…...
如何为系统可靠性的量化提供依据
SLA 即 Service Level Agreement,也就是服务等级协议,它指的是系统服务提供者(Provider)对客户(Customer)的一个服务承诺。 而 SLO 就是 SLA 的具体目标管理办法,它由一系列相关的指标 SLI &am…...
量化投资中的因子是什么?因子是如何分类的,包括哪些?
因子就是对个股有解释的因素。因子的种类很多,不同类别的因子从不同的维度对个股收益进行解释。比如基本面因子的数据来源方面有很大一部分是财务报表,从估值、成长、盈利能力等多个方面对股票收益进行解释。量价因子是围绕价格、成交量等技术指标构建的…...
力扣-修复表中的名字
大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:1667. 修复表中的名字二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他…...
徐州网站建设优化宣传/百度平台客服人工电话
一、什么是生产线3D可视化解决方案? 生产线3D可视化解决方案,是结合物联网监控系统(智慧工厂)、虚实联动与三维建模先进技术,以三维立体模式呈现出来,使得界面直观、简单,便于监控人员识别异常信…...
武汉专业网站排名推广/影视后期哪个培训靠谱
考试路线 1 【2】 3 转载于:https://www.cnblogs.com/rhxuza1993/p/9485975.html...
深圳电商网站设计/海外发布新闻
Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。 简书支持程序员写技术博客的模式,Markdown具有一系列衍生版本,用于扩展Markdown的功能(如表格、脚注、…...
wordpress一键分享插件/在线收录
前言: 与其每天浑水摸鱼、浑浑噩噩,不如多进阶学习,提升自己的竞争力。 Android中高级必会知识点: 一、性能优化 1、APP稳定性优化 1.做过哪些稳定性方面的优化? 2.性能稳定性是怎么做的? 3.业务稳定性…...
部门网站建设的工作领导小组/app开发工具哪个好
在学习《modern c design》的时候,学习到了如何在 compile-time 检测两个类型之间是否可以转化. 这里的转换,既包括 int,long,double 这些数据类型之间的转换,也包括基类和子类之间的转换(也就是两个类之前…...
遵义市网站制作/渠道推广平台
Epic 在昨天公布其最新次世代引擎「虚幻引擎5」,并重点介绍了新引擎的两项新技术 Nanite 和 Lumen。下面给大家简单介绍一下这两个新技术到底厉害在哪里,以及为什么许多游戏开发者们看完之后纷纷拍手叫好。 首先,整段 Demo 采用动态分辨率&…...