JAVA后端使用echarts生成折线表格转成图片保存在本地

java后台生成ECharts的PDF文档(phantomjs) 一、需求 没有HTML预览页面,要求前台提交数据后,在服务端生成一份带ECharts图表的PDF文件 二、分析 存在以下几个难点: 1、没有浏览器,怎么渲染生成ECharts图并且放到PDF中 2、后台生成PDF的方案比较少,怎么保证样式,同时要有可维护性 解决方案: 1、直接生成PDF局限性较大,可以先生成word,再转PDF 2、寻找一个工具,可以把ECharts转成图片,插入到word中 三、实现 这里我以生成一个简历PDF为例 1、word的生成 采用POI-TL转为模板 官网地址:http://d 阅读详情

效果图:

准备工作:

由于echarts是前端的包,后端需要用到依赖工具。

工具下载:

链接:https://pan.baidu.com/s/1NX9pf77SlEtU_QdKMn3_Ow
提取码:wli7

解压后我是直接放在D盘根目录下,echarts-convert.js:

 

PhantomJS工具(执行命令工具,需要配置环境变量)

官方文档:http://phantomjs.org/headless-testing.html

 配置环境变量:

 

具体代码:

        <!--导出echarts图片-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.28</version>
        </dependency>
        <dependency>
            <groupId>com.github.abel533</groupId>
            <artifactId>ECharts</artifactId>
            <version>2.2.6</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.13</version>
        </dependency>
package com.chen.test;

import com.chen.entity.MetricsMonitor;
import com.chen.entity.PmsMetricsMonitorIndexVO;
import com.github.abel533.echarts.Grid;
import com.github.abel533.echarts.Label;
import com.github.abel533.echarts.Legend;
import com.github.abel533.echarts.Option;
import com.github.abel533.echarts.Title;
import com.github.abel533.echarts.axis.Axis;
import com.github.abel533.echarts.axis.AxisLabel;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.code.AxisType;
import com.github.abel533.echarts.code.LineType;
import com.github.abel533.echarts.code.Orient;
import com.github.abel533.echarts.code.Position;
import com.github.abel533.echarts.code.SeriesType;
import com.github.abel533.echarts.code.Trigger;
import com.github.abel533.echarts.code.X;
import com.github.abel533.echarts.series.Line;
import com.google.gson.Gson;
import lombok.SneakyThrows;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @Author: Chen
 * @Date: 2023/4/18 10:44
 * @Desc:
 */
public class LeetCodeTest {

    private static final String JSpath = "D:\\echarts-convert\\echarts-convert1.js";

    @SneakyThrows
    public static void main(String[] args) {
        MetricsMonitor metricsMonitor = new MetricsMonitor();
        PmsMetricsMonitorIndexVO vo = new PmsMetricsMonitorIndexVO();
        vo.setTechDeliDura(new BigDecimal(345));
        metricsMonitor.setTargetValue(vo);
        List<PmsMetricsMonitorIndexVO> monitorIndexVOList = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //造数据
        for (int i = 1; i < 12; i++) {
            PmsMetricsMonitorIndexVO monitorIndexVO = new PmsMetricsMonitorIndexVO();
            monitorIndexVO.setCurrentTimeStr(format.format(new Date()));
            if (i%2 == 0) {
                monitorIndexVO.setTechDeliDura(new BigDecimal((192.5 - i)));
            } else {
                monitorIndexVO.setTechDeliDura(new BigDecimal((92.9 + i)));
            }
            if (i==9) {
                monitorIndexVO.setTechDeliDura(new BigDecimal(55));
            }
            if (i==10 || i==11) {
                monitorIndexVO.setTechDeliDura(new BigDecimal(367));
            }
            monitorIndexVOList.add(monitorIndexVO);
        }
        metricsMonitor.setMetricsMonitorList(monitorIndexVOList);
        Option option = getTechDeliDuraOption(metricsMonitor);
        Map<String,Object> resultMap=new HashMap<>();

        String path = generateEChart(new Gson().toJson(option), resultMap);

        // 构建HTTP POST请求,发送ECharts配置项和echarts.min.js文件
        HttpPost httpPost = new HttpPost("https://www.echartsjs.com/api/echarts/export");

        // 发送HTTP请求并获取响应
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();

        // 将响应内容保存为PNG图像文件
        OutputStream outputStream = new FileOutputStream("chart.png");
        entity.writeTo(outputStream);
        outputStream.close();
    }

    public static String generateEChart(String options, Map<String,Object> resultMap) {
        //获取时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HHmmss");
        String nowDate = sdf.format(new Date());
        String dataPath = writeFile(options);
        String fileName= String.format("%s库位移动量趋势图.png", nowDate);
        String path = "D:/temp/Echart/" + fileName;
        try {
            File file = new File(path);     //文件路径(路径+文件名)
            if (!file.exists()) {   //文件不存在则创建文件,先创建目录
                File dir = new File(file.getParent());
                dir.mkdirs();
                file.createNewFile();
            }
            String cmd = "phantomjs " + JSpath + " -infile " + dataPath + " -outfile " + path;
            Process process = Runtime.getRuntime().exec(cmd);
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = "";
            while ((line = input.readLine()) != null) {
                System.out.println("line++++++++++++++++++++"+line);
            }
            input.close();

        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            return path;
        }
    }

    public static String writeFile(String options) {
        String dataPath="D:\\chartData\\data" + UUID.randomUUID().toString().substring(0, 8) +".json";
        try {
            File writename = new File(dataPath); // 相对路径,如果没有则要建立一个新的output.txt文件
            if (!writename.exists()) {   //文件不存在则创建文件,先创建目录
                File dir = new File(writename.getParent());
                dir.mkdirs();
                writename.createNewFile(); // 创建新文件
            }
            BufferedWriter out = new BufferedWriter(new FileWriter(writename));
            out.write(options); // \r\n即为换行
            out.flush(); // 把缓存区内容压入文件
            out.close(); // 最后记得关闭文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataPath;
    }

    public static Option getTechDeliDuraOption(MetricsMonitor metricsMonitor) {
        List<PmsMetricsMonitorIndexVO> metricsMonitorList = metricsMonitor.getMetricsMonitorList();
        Option optionTechDeliDura = new Option();

        // 设置标题
        Title title = new Title();
        title.setText("平均技术交付时长趋势图(自然日)");
        title.setTextAlign(X.left);
        optionTechDeliDura.setTitle(title);

        // 设置提示框
        /*Tooltip tooltip = new Tooltip();
        tooltip.setTrigger(Trigger.axis);
        optionTechDeliDura.setTooltip(tooltip);*/
        optionTechDeliDura.tooltip().trigger(Trigger.axis);
        // 设置图例
        Legend legend = new Legend();
        List<Object> legendData = new ArrayList<>();
        legendData.add("平均技术交付时长");
        legendData.add("目标值");
        legend.setData(legendData);
        legend.setOrient(Orient.vertical);
        optionTechDeliDura.setLegend(legend);

        // 设置网格
        Grid grid = new Grid();
        grid.setWidth(800);
        grid.setHeight(450);
        optionTechDeliDura.setGrid(grid);

        // 设置x轴
        CategoryAxis xAxis = new CategoryAxis();
        xAxis.setType(AxisType.category);
        xAxis.setBoundaryGap(false);
        List<Object> xAxisData = new ArrayList<>();
        for (PmsMetricsMonitorIndexVO monitorIndexVO : metricsMonitorList) {
            xAxisData.add(monitorIndexVO.getCurrentTimeStr());
        }
        xAxis.setData(xAxisData);
        AxisLabel axisLabel = new AxisLabel();
        axisLabel.setRotate(45);
        xAxis.setAxisLabel(axisLabel);
        List<Axis> axisListX = new ArrayList<>();
        axisListX.add(xAxis);
        optionTechDeliDura.setxAxis(axisListX);

        // 设置y轴
        ValueAxis yAxis = new ValueAxis();
        yAxis.setType(AxisType.value);
        List<Axis> axisListY = new ArrayList<>();
        axisListY.add(yAxis);
        optionTechDeliDura.setyAxis(axisListY);


        Label lineLabel = new Label();
        lineLabel.setShow(true);
        lineLabel.setPosition(Position.top);
        // 设置平均技术交付时长的线条
        Line lineTechDeliDura = new Line();
        List<Object> techDeliDuraData = new ArrayList<>();
        for (PmsMetricsMonitorIndexVO monitorIndexVO : metricsMonitorList) {
            if (monitorIndexVO.getTechDeliDura() != null) {
                lineTechDeliDura.setType(SeriesType.line);
                lineTechDeliDura.setName("平均技术交付时长");
                techDeliDuraData.add(monitorIndexVO.getTechDeliDura());
            } else {
                techDeliDuraData.add("-");
            }
        }
        lineTechDeliDura.setData(techDeliDuraData);
        lineTechDeliDura.itemStyle().normal().label(lineLabel);
        lineTechDeliDura.setShowAllSymbol(true);
        optionTechDeliDura.series(lineTechDeliDura);

        // 设置目标值的线条
        Line targetLine = new Line();
        List<Object> targetLineData = new ArrayList<>();
        for (PmsMetricsMonitorIndexVO monitorIndexVO : metricsMonitorList) {
            targetLine.setType(SeriesType.line);
            targetLine.setName("目标值");
            targetLineData.add(metricsMonitor.getTargetValue().getTechDeliDura());
        }
        targetLine.setData(targetLineData);
        targetLine.itemStyle().normal().lineStyle().width(4).type(LineType.dotted);
        lineTechDeliDura.setShowAllSymbol(true);
        optionTechDeliDura.series(targetLine);

        return optionTechDeliDura;
    }
}

生成的文件:

chartData

temp 

 

EXCEL导出数据并导出ECharts图片 poi的版本 ECharts的版本 在做excel导出数据及ECharts图片时页面有几点要注意:1.在option中设置animation:false 2.获取url路径的Base64位编码,默认是png,所以括号后不用写图片类型,我一开始在括号中写了png页面反而报错; 在这里我将imagesBase64定义为全局变量,以便在调用下载方法时传到后端。 . 3.下载方法不能... 阅读详情

相关推荐

基于VUE + Echarts 实现可视化数据大屏任务大数据

前言???? 基于 vue、datav、Echart 框架的大数据可视化(大屏展示)源码,基于VUE+Echarts 制作,实现大数据可视化。通过 vue 组件实现数据动态刷新渲染,内部图表可自由替换。部分图表使用 DataV 自带组件,可自由进行更改, 可以在此基础上重新开发。本项目中使用的是echarts图表库,EChart...

qq_365392777 874

java导出excel并生成折线图.java

资源描述:一个使用java做的导出数据,并且可以在excel表生成折线图的工具类,使用简单操作方便。

花桥中学用的成绩分析系统源码:SpringBoot后端+MySQL数据库+ECharts动态图表

专为中学教师设计的成绩分析工具,支持考试安排、成绩批量录入、按班级/学科/学生多维度统计,自动生成柱状图、折线图、饼图等可视化图表。后端基于SpringBoot 2.x构建,集成Spring Data JPA操作MySQL 8.0数据库,权限控制采用Spring Security;前端使用原生HTML/CSS/JS搭配jQuery和ECharts 5.x,适配Chrome、Firefox、Edge、360、搜狗及IE9+浏览器。压缩包内含完整可运行源码、pas.sql建库脚本、需求文档.md、12张真实界面

raspberrypi5的博客 218

java后台生成echarts图表

echarts-java 通过phantomjs java后台生成echats图表,echartspoi相关jar包及phantomjs都在压缩包内

生成PDF】【JAVA】纯后台生成Echarts图片,并将图片生成到PDF文档

本次任务:要求不经过web页面,Java如何生成含有Echarts图的PDF

qq_41773784的博客 1万+

java后台生成echarts图表图片

项目需求,生成报表并发送邮件给指定邮箱,报表中包含echarts图表,由于无法在邮件中渲染图表,所以需要后台生成图表图片再嵌入到邮件中。

zixuanyankai的博客 7152

SptingBoot基于Echarts生成图表,后端生成ECharts图片

SptingBoot基于Echarts生成折线图,柱状图;后端生成Echarts图表;使用phantomJs服务器端导出Echarts图片java生成Echarts图表;Echarts后端导出Base64图片;echarts写入Word中;Echarts图片生成失败问题解决

青冘的技术学习博客 5399

java根据模板导出word,并在word中插入echarts相关统计图片以及表格

java根据word模板生成对应的word文档,并且要在word文档中插入Echarts的一些统计图表,例如柱状图、折线图、柱状混合图等。思路是根据Echatrs的option生成json文件,然后通过命令行调用phantomjs执行echarts-convert的js脚本生成Echarts对应图表的图片,然后将图片转为Base64的字符串,替换word文档中的图片占位符,实现往word文档中插入统计图表的需求。

weixin_42123075的博客 1827

SptingBoot基于Echarts生成折线图,柱状图,超详细~~

近期产品团伙给了一个生成PDF数据报的需求,PDF中需要生成折线图,梯状折现图,柱状图等需求以及一些表格信息的东西,我这边就去找到前端开发工程师,但是前端工程师并没有好的方案给出,于是乎就由后台开发来生成图片,并写入PDF中。下面我把我生成统计图的方法(大部分参考+整合)写成文章,需要的兄弟姐妹们可以参考和纠正我。

qq1328585964的博客 3566

Java 使用freemaker导出word(带echarts图片表格)

一.导入freemaker和Echarts的jar包 下载地址:https://mvnrepository.com/ 二. 制作模板 1.把需要替换的内容或图片用xxx替换(也可以直接用${xxx}格式,不过转xml的时候会被拆分开)。 2.表格只需要画一行,循环在xml中配置 3.如果多张图片的话,一定要选择不同的图片,不能为了省事使用同一张图片! 4.模板画好...

lifezxcasdqwe的博客 2186

Echart图表在项目中如何使用?(前后端详细技术讲解)

Echart图表在项目中的详细使用 第二章 Echart图表在项目中的详细使用-折线图篇 提示:我们在讲解Echart使用时首先要安装Echart,使用的前端框架时vue,后端时springboot项目或者spring,或者读者不会java,也可以学习,原理时一样的。vue环境的搭建大家可以在csdn上找到教程,我就不在赘述了。 环境安装的详细教程看我的第一章教程。 第一章 echart准备 文章目录Echart图表在项目中的详细使用前言一、项目架构二、进入Echart官网学会自我分析2.1 Echart

ILOVEMYDEAR的博客 7284

Java后台批量生产echarts图表并保存图片

主要介绍了Java后台批量生产echarts图表并保存图片,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

Java后端生成Echarts并渲染Word转PDF

生成pdf文件 文件要素 文件中包含图片 文件中包含列表 文件中包含表格 文件中包含循环嵌套写入的内容 文件需要后端生成echarts图表数据 基于以上几点考虑 技术选取 方式一 itext7是一款用于生成PDF文档的一个java类库,通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。 网上资料比较少, 可以通过写段落/图片/表格,也可以定制pdf模板然后通过填充域属性值,达到生成PDF文件的结果; 难点; 通过代码写PDF,某些排版不好配置, 可以通过

qq_34898847的博客 4453

java echarts 案例,Echarts个人实例

1.deviceOperateTrendIndex.jsp设备操作趋势主界面//设置默认访问的界面var indexPage = "/device/deviceListAjax.do";$(document).ready(function(){//绑定tab页$("#tabs span").click(function(){var tabHtml = $(this).html();switch(t...

weixin_39530509的博客 866

java报表技术-图形报表

java平台上的一个开放的图标绘制类库。完全使用java编写,可生成饼图、柱状图、散点图、时许图、甘特图等等多种图表,并且可以产生png和jpeg格式的输出,还可以与pdf或excel关联Highcharts是一个用纯js编写的一个图标库,能够很简单便携的在web网络或者web应用程序添加有交互性的图标,并且免费提供给个人学习、个人网站和非商业用途使用。HighCharts支持的图表类型有曲线图、区域图、柱状图、饼状图、散装点图和综合图标。......

m0_63475429的博客 2199

SeleniumChrome使用及问题解决

java生成pdf,SeleniumChrome使用及问题解决

qq_36263426的博客 1523

EasyReport图表报表深度解析:ECharts与Highcharts集成指南

EasyReport是一款简单易用的Java Web报表工具,能够将SQL查询结果转换为美观的HTML表格并支持强大的图表可视化功能。本文将深入解析EasyReport如何集成两大主流图表库ECharts和Highcharts,帮助您快速构建专业级数据可视化报表。📊 ## 为什么选择EasyReport进行图表集成? EasyReport作为一款成熟的Web报表系统,不仅支持多种数据库(包括

gitblog_00886的博客 343

<若依开源框架>使用记录

若依官方文档 有不会的多看官方文档。 1.建表 注意:字段注释和表注释都得写上。 2.导入 运行项目,点击代码生成。 导入我们刚才建的表。 3.配置 点击编辑。 基本信息可以保持不变。 字段信息一般会改改某些字段的插入编辑列表查询功能,还有查询方式不少都要模糊Like查询。显示类型改为下拉框的话,选上右侧的字典类型。 生成信息按需要改包路径和模块名,选上级菜单。等下生成的时候会在这个菜单下生成新菜单。 点保存。 4.代码生成 点击生成代码,然后下载压缩包后解压,得到这些。 把main直接复制进

lisz的博客 1554
上一篇: Docker:命令详解
下一篇: S3 Browser介绍、基础操作
从乌托邦醒来
博客等级 码龄5年 31粉丝 26原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值