easypoi 导出word并插入echart图片和文件

一 pom 文件引入:

<!-- 目前的版本对应  poi 4.1.2   和 xmlbeans 3.1.0   , poi 3.17   和 xmlbeans 2.6.0 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- easypoi导出word -->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.4.0</version>
        </dependency>

二  DownloadReportController 层

/**
     *下载word
     * @param response
     * @throws Exception
     */
    @ApiOperation("下载word")
    @PostMapping("/exportToWord")
    public void exportToWord(HttpServletResponse response, @RequestBody DownloadReportSearchVo downloadReportSearchVo) {
        String secCode = SecurityContextHolder.getUserStockCode();
        HengShenCompanyInfoDto companyInfoDto = remoteBasicService.getCompanyInfoByCode(secCode).getData();
        String companyReferred = companyInfoDto.getCompanyReferred();
        String day = DateUtil.format(new Date(),"yyyyMMdd");
        String wordFileName = companyReferred+"("+secCode+")"+"市值诊断报告_"+day+".docx";
        try {
            downloadReportSearchVo.setSecCode(secCode);
            Map<String, Object> wordInitDataMaps = downloadReportService.exportToWord(downloadReportSearchVo);
            // 前端调用下面初始化word数据方法,下载时候从缓存取word map类型替换数据;
            // Map<String, Object> wordInitDataMaps = redisService.getCacheMap(DOWNLOADREPORT_WORDDATA+secCode);
            //读取模板 并 一次性提交maps里要替换的文字和图片内容,然后导出word;
            XWPFDocument  word = null;
            try {
                word = WordExportUtil.exportWord07(phantomjsRoot+"/市值诊断报告_YYYYMMDD.docx", wordInitDataMaps);
            } catch (Exception e) {
                e.printStackTrace();
            }
            response.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(wordFileName,"UTF-8"));
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            ServletOutputStream outputStream = response.getOutputStream();
            word.write(outputStream);
            outputStream.close();
            word.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

三 service 层



    @Override
    public Map<String, Object> exportToWord(DownloadReportSearchVo downloadReportSearchVo) {
        String secCode = downloadReportSearchVo.getSecCode();
        Map<String, Object> maps=new HashMap<>();
        // 1-1 诊断结果>市值表现


        // 1-2 诊断结果>流动性情况
        //获取本模块4个echart图形数据和文字描述
        LiquidityAnalysisVO liquidityAnalysisVO = liquiditySituationService.analysisResult(secCode);
        //生成echart图片,并替换图片和文字
        maps = liquiditySituationService.analysisResultToEchartImg(liquidityAnalysisVO,maps);


        // 1-3 诊断结果>股东结构分析


        //2-1 A股市值表现>市值对比

        //2-2 A股市值表现>估值对比

        //2-3 A股市值表现>股价对比


        return maps;
    }



/**
     * 根据原图表数据,封装echart json option 格式,并生成echart图片
     *
     * @param liquidityAnalysisVO
     */
    @Override
    public Map<String, Object> analysisResultToEchartImg(LiquidityAnalysisVO liquidityAnalysisVO, Map<String, Object> maps) {
        List<String> colorList = Arrays.asList("rgb(52,113,219)", "rgb(46,167,224)", "rgb(16,197,121)", "rgb(248,180,0)");

        String suggest = liquidityAnalysisVO.getSuggest();
        String yearAvgSuggest = liquidityAnalysisVO.getYearAvgSuggest();

        // 1 第一张echart图 生成echart option
        //换手率 替换第一张图片和文字
        List<OverviewVO> listYearAvgAnalysis = liquidityAnalysisVO.getYearAvgAnalysis();
        List<String> indexkeyYearAvgAnalysis = listYearAvgAnalysis.stream().map(overviewVO -> overviewVO.getIndexKey()).collect(Collectors.toList());
        List<BigDecimal> indexValueYearAvgAnalysis = listYearAvgAnalysis.stream().map(overviewVO -> overviewVO.getIndexValue()).collect(Collectors.toList());
        maps.put(DownloadReportEnum.DIAGNOSTIC_RESULT_FLOW_SUGGEST.getName(), suggest);
        maps.put(DownloadReportEnum.DIAGNOSTIC_RESULT_FLOW_1_YEARAVGSUGGEST.getName(), yearAvgSuggest.replaceAll("<span>", "").replaceAll("</span>", ""));
        String option = "{\n" +
                "  title: {\n" +
                "    text: '换手率'\n" +
                "  },\n" +
                "  tooltip: {\n" +
                "    trigger: 'axis',\n" +
                "    axisPointer: {\n" +
                "      type: 'shadow'\n" +
                "    }\n" +
                "  },\n" +
                "  legend: {},\n" +
                "  grid: {\n" +
                "    left: '3%',\n" +
                "    right: '4%',\n" +
                "    bottom: '3%',\n" +
                "    containLabel: true\n" +
                "  },\n" +
                "  xAxis: {\n" +
                "    type: 'value',\n" +
                "    boundaryGap: [0, 0.01]\n" +
                "  },\n" +
                "  yAxis: {\n" +
                "    type: 'category',\n" +
                "    data: ['" + StringUtils.join(indexkeyYearAvgAnalysis, "','") + "'] \n" +
                "  },\n" +
                "  series: [\n" +
                "    {\n" +
                "      barWidth:30, " +
                "      name: '当年度年平均换手率(%)',\n" +
                "      type: 'bar',\n" +
                "      data: [ \n ";
        for (int i = 0; i < indexValueYearAvgAnalysis.size(); i++) {
            BigDecimal value = indexValueYearAvgAnalysis.get(i);
            String color = colorList.get(i);
            option += " { " +
                    "value: " + numberUtils.formatToBigDecimal(value) + ", " +
                    "itemStyle: { " +
                    "color: '" + color + "' " +
                    "} " +
                    "}, ";
        }
        option += " ]} \n" +
                "  ]\n" +
                "};\n";
        String echartImgPath1 = eChartImgService.generateEChartImg(option);
        // 2 生成要代替word里图像英文单词字符串
        ImageEntity imageEntity = new ImageEntity();
        imageEntity.setUrl(echartImgPath1);
        imageEntity.setWidth(500);
        imageEntity.setHeight(300);   // 这里的宽高一定要设置,不然图片出不来
        maps.put(DownloadReportEnum.DIAGNOSTIC_RESULT_FLOW_1_IMG1.getName(), imageEntity);//替换图片
}


四: phantomjs 插件生成echart 图片

package com.realize.market.value.service.impl;

import com.realize.market.value.service.IEChartImgService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.UUID;

@Service
@Slf4j
public class EChartImgServiceImpl  implements IEChartImgService {

    private static final Logger logger = LoggerFactory.getLogger(EChartImgServiceImpl.class);

    private static  String  phantomjsRoot;
    private static  String  phantomjsWindowPath;
    private static  String  phantomjsLinuxPath;
    private static  String  JSpath;

    @Value("${phantomjs.root}")
    public void setSender(String phantomjs) {
        phantomjsRoot = phantomjs;
        phantomjsWindowPath=phantomjsRoot+"/phantomjs-2.1.1-windows/bin/phantomjs.exe";
        phantomjsLinuxPath=phantomjsRoot+"/phantomjs-2.1.1-linux-x86_64/bin/phantomjs";
        JSpath=phantomjsRoot+"/echarts-convert/echarts-convert1.js";
    }


    @Override
    public  String generateEChartImg(String options) {
        // 1此处可根据操作系统获取对应phantomjs文件路径(phantomjs.exe对应Windows,phantomjs对应Linux)
        String phantomjsPath = "";
        String os = System.getProperty("os.name").toLowerCase();
        if (os.contains("windows")) {
            phantomjsPath = phantomjsWindowPath;
        }else{
            phantomjsPath = phantomjsLinuxPath;
        }
        // 2根据各模块传递过来的 echart  json, 生成服务器本地 echart json文件
        //String inputDataPath = writeLocalJsonFile(options);
        String filename = UUID.randomUUID().toString().replaceAll("-","");
        String inputDataPath=phantomjsRoot+"/data/"+filename+".json";
        try {
            /* 写入json文件 */
            File writename = new File(inputDataPath); // 相对路径,如果没有则要建立一个新的output.json文件
            if (!writename.exists()) {   //文件不存在则创建文件,先创建目录
                File dir = new File(writename.getParent());
                dir.mkdirs();
                writename.createNewFile(); // 创建新文件
            }
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(writename),"utf-8"));
            out.write(options); // \r\n即为换行
            out.flush(); // 把缓存区内容压入文件
            out.close(); // 最后记得关闭文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 3读取本地echart json 格式文件生成 echart 图片
        String outfilePath = phantomjsRoot+"/Echart/" +filename+ ".png";
        try {
            File file = new File(outfilePath);     //文件路径(路径+文件名)
            if (!file.exists()) {   //文件不存在则创建文件,先创建目录
                File dir = new File(file.getParent());
                dir.mkdirs();
                file.createNewFile();
            }
            // 执行 phantomjs 插件命令,输入json ,输出echart图片生成;
            String cmd = phantomjsPath+" " + JSpath + " -infile " + inputDataPath + " -outfile " + outfilePath;
            excuteCMDBatFile(cmd,filename);
            //Process process = Runtime.getRuntime().exec(cmd);
            //BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            //input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            return outfilePath;
        }
    }


    /**
     * 1.将执行的命名写入到sh/cmd文件中,没有用 Runtime 直接执行命令,避免系统阻塞卡顿
     * @param exportFile
     * @param content
     * @return
     */
    public  boolean writeFile(File exportFile,  String content) {
        if (exportFile == null || StringUtils.isEmpty(content)) {
            return false;
        }
        if (!exportFile.exists()) {
            try {
                exportFile.getParentFile().mkdirs();
                exportFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
                logger.error("create local json file exception: " + e.getMessage());
                return false;
            }
        }
        BufferedWriter bufferedWriter = null;
        try {
            FileOutputStream os = new FileOutputStream(exportFile);
            FileDescriptor fd = os.getFD();
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
            bufferedWriter.write(content);
            //Flush the data from the streams and writes into system buffers
            //The data may or may not be written to disk.
            bufferedWriter.flush();
            //block until the system buffers have been written to disk.
            //After this method returns, the data is guaranteed to have
            //been written to disk.
            fd.sync();
            //设置文件权限
            exportFile.setExecutable(true);
            exportFile.setReadable(true);
            exportFile.setWritable(true);
        } catch (UnsupportedEncodingException e) {
            logger.error("saveDBData#catch an UnsupportedEncodingException (" + e.getMessage() + ")");
            return false;
        } catch (FileNotFoundException e) {
            logger.error("saveDBData#catch an FileNotFoundException (" + e.getMessage() + ")");
            return false;
        } catch (IOException e) {
            logger.error("saveDBData#catch an IOException (" + e.getMessage() + ")");
            return false;
        } catch (Exception e) {
            logger.error("saveDBData#catch an exception (" + e.getMessage() + ")");
            return false;
        } finally {
            try {
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                    bufferedWriter = null;
                }
            } catch (IOException e) {
                logger.error("writeJsonToFile#catch an exception (" + e.getMessage() + ")");
            }
        }
        return true;
    }


    //2.执行命令 phantomjs 插件生成echart 图片
    public  boolean excuteCMDBatFile(String cmd,String filename) {
        String os = System.getProperty("os.name").toLowerCase();
        String batFilePath="";
        if (os.contains("windows")) {
             batFilePath = phantomjsRoot+"/data/"+filename+".bat";
        }else{
             batFilePath = phantomjsRoot+"/data/"+filename+".sh";
        }

        final String METHOD_NAME = "excuteCMDBatFile#";
        boolean result = true;
        Process p;
        File batFile = new File(batFilePath);
        //System.out.println(batFile.getAbsolutePath());
        //命令写入bat文件
        boolean isSuccess = writeFile(batFile, cmd);
        if(!isSuccess) {
            logger.error(METHOD_NAME + "write cmd to File failed.");
            return false;
        }

        logger.info("cmd path:" + batFilePath);
        try {
            //执行命令 bat文件
            p = Runtime.getRuntime().exec(batFilePath);
            InputStream fis = p.getErrorStream();//p.getInputStream();
            InputStreamReader isr = new InputStreamReader(fis, System.getProperty("file.encoding"));
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            StringBuilder builder = new StringBuilder();
            while ((line = br.readLine()) != null) {
                builder.append(line);
            }

            p.waitFor();
            int i = p.exitValue();
            logger.info(METHOD_NAME + "exitValue = " + i);
            if (i != 0) {
                result = false;
                logger.error(METHOD_NAME + "excute cmd failed, [result = " + result + ", error message = " + builder.toString() + "]");
                //System.out.println(METHOD_NAME + "excute cmd failed, [result = " + result + ", error message = " + builder.toString() + "]");
            }else {
                // logger.debug(METHOD_NAME + "excute cmd result = " + result);
                System.out.println(METHOD_NAME + "result = " + result);
            }
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
            logger.error(METHOD_NAME + "fail to excute bat File [ErrMsg=" + e.getMessage() + "]");
        }
        return result;
    }

    /*public static void main(String[] args) {
        //String cmd="F:/usr/local/plugin/phantomjs-2.1.1-windows/bin/phantomjs.exe F:/usr/local/plugin/echarts-convert/echarts-convert1.js -infile F:/usr/local/plugin/data/37da9189.json -outfile F:/usr/local/plugin/Echart/37da9189-1.png";
        String cmd="/usr/local/plugin/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/plugin/echarts-convert/echarts-convert1.js -infile /usr/local/plugin/data/37da9189.json -outfile /usr/local/plugin/Echart/37da9189-1.png";

        excuteCMDBatFile(cmd);
    }*/
}

插件包含内容:

1 phantomjs-2.1.1-windows 执行转化图片命令

2 echarts-convert js生成ecahrt 图片

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/32534.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《后端存储实战课》课程学习笔记(三)

流量大、数据多的商品详情页系统该如何设计&#xff1f; 电商的商品系统主要功能就是增删改查商品信息&#xff0c;没有很复杂的业务逻辑&#xff0c;支撑的主要页面就是商品详情页。设计这个系统的存储&#xff0c;你仍然需要着重考虑两个方面的问题。 第一&#xff0c;要考虑…

【计算机网络】可靠传输的实现机制

参考视频 https://www.bilibili.com/video/BV1c4411d7jb 1、停止-等待协议SW (Stop-and-Wait) 1.1 信道利用率 1.2 题目 1.3 小结 2.回退N帧协议GBN (Go-Back-N) 1.1 题目 1.2 小结 3.选择重传协议SR (Selective-Repeat) 3.1 过程 3.2 发送窗口 和 接收窗口尺寸范围 4.小结 5.…

Centos7单机安装Redis

安装Redis依赖 Redis是基于C语言&#xff0c;因此首先需要安装Redis所需要的gcc依赖&#xff1a; yum install -y gcc tcl ​ 上传安装包并解压 上传安装包redis-6.2.12至/home目录下 ​ # 解压 tar -xzf redis-6.2.12.tar.gz # 安装 cd redis-6.2.12 make && mak…

第七十天学习记录:高等数学:微分(宋浩板书)

微分的定义 基本微分公式与法则 复合函数的微分 微分的几何意义 微分在近似计算中应用 sin(xy) sin(x)cos(y) cos(x)sin(y)可以用三角形的几何图形来进行证明。 假设在一个单位圆上&#xff0c;点A(x,y)的坐标为(x,y)&#xff0c;点B(x’, y’)的坐标为(x’, y’)。则以两点…

文言一心,ChatGLM-6B和ChatGPT等模型概述

原文首发于博客文章大语言模型概况 定义 &#xff08;个人理解的&#xff09;大语言模型&#xff08;Large Language Model&#xff09;是一种基于深度学习技术的自然语言处理通用模型&#xff0c;它可以通过学习大规模文本数据的模式和规律&#xff0c;从而实现对自然语言的理…

生物群落(生态)数据统计分析与绘图

R 语言作的开源、自由、免费等特点使其广泛应用于生物群落数据统计分析。生物群落数据多样而复杂&#xff0c;涉及众多统计分析方法。以生物群落数据分析中的最常用的统计方法回归和混合效应模型、多元统计分析技术及结构方程等数量分析方法为主线&#xff0c;通过多个来自经典…

Vue Router 相关理解 基本路由 多级路由

6.1.相关理解 6.1.1.vue-router 的理解 vue的一个插件库&#xff0c;专门用来实现SPA应用 6.1.2.对SPA应用的理解 单页Web应用&#xff08;single page web application&#xff0c;SPA&#xff09;整个应用只有一个完整的页面点击页面中的导航链接不会刷新页面&#xff0c…

2023.6.27宝塔面板无法正常进入

解决访问宝塔面板提示404 Not Found 情况说明&#xff1a;访问宝塔面板提示404&#xff0c;或者忘记外网面板地址 大概率访问路径不够全 输入以下内容查看 /etc/init.d/bt default 如果还是不行再重启宝塔面板&#xff0c;执行上面步骤 /etc/init.d/bt stop /etc/init.d/b…

初识mysql数据库之mysql数据库安装(centos)

目录 一、卸载不需要的环境 二、安装mysql yum源 三、安装mysql 四、登录mysql 1. 直接登录 2. 设置免密码登录 五、配置my.cnf 六、mysql登录时的一些选项介绍 一、卸载不需要的环境 要注意&#xff0c;在安装mysql数据库时&#xff0c;最好将用户切换为root&#xf…

git介绍和安装/git,github,gitee,gitlab区别/git使用流程/ git常用命令/git忽略文件

git介绍和安装 # 版本管理软件-1 对代码版本进行管理---》首页功能完成---》课程功能完成---》可以回退到某个版本-2 协同开发--》多人开发--》合并代码---》可能会有冲突&#xff0c;解决冲突# 版本管理软件&#xff1a;主流就两个-git&#xff1a;现在用的最多&#xff08;学…

IMX6ULL系统移植篇-镜像烧写方法

一. 烧录镜像简介 本文我们就来学习&#xff1a;windows 系统下烧录镜像的方法。 如何使用 NXP 官方提供的 MfgTool 工具通过 USB OTG 口来 烧写系统。 二. windows下烧录镜像 1. 烧录镜像前准备工作 &#xff08;1&#xff09;从开发板上拔下 SD卡。 &#xff08;2…

fatal error: ‘type_traits‘ file not found错误解决

错误如下 In file included from ../test_opencv_qt/main.cpp:1: In file included from ../../Qt/6.5.1/android_x86_64/include/QtGui/QGuiApplication:1: In file included from ../../Qt/6.5.1/android_x86_64/include/QtGui/qguiapplication.h:7: In file included from .…

springDatajpa动态sql根据时间范围将数据导出为excel并使用vue的按钮去触发

用到的技术点&#xff1a; 1.springDatajpa 2.EasyExcel 3.数据库 4.vue 前端实现&#xff1a; 1.创建按钮&#xff08;点击此按钮弹出填写导出条件的弹出框&#xff09; <el-button type"primary" round click"dialogVisible true"><svg-icon …

什么是Session

1、web中什么是会话 &#xff1f; 用户开一个浏览器&#xff0c;点击多个超链接&#xff0c;访问服务器多个web资源&#xff0c;然后关闭浏览器&#xff0c;整个过程称之为一个会话。 2、什么是Session &#xff1f; Session:在计算机中&#xff0c;尤其是在网络应用中&…

MySQL数据同步到ES的4种解决方案

一、背景 大家应该都在各种电商网站检索过商品&#xff0c;检索商品一般都是通过什么实现呢&#xff1f;搜索引擎Elasticsearch。那么问题来了&#xff0c;商品上架&#xff0c;数据一般写入到MySQL的数据库中&#xff0c;那么用于检索的数据又是怎么同步到Elasticsearch的呢&…

分布式定时任务框架 PowerJob

业务背景 1.1 为什么需要使用定时任务调度 &#xff08;1&#xff09;时间驱动处理场景&#xff1a;整点发送优惠券&#xff0c;每天更新收益&#xff0c;每天刷新标签数据和人群数据。 &#xff08;2&#xff09;批量处理数据&#xff1a;按月批量统计报表数据&#xff0c;批…

使用nodejs操作postgresql

环境准备 1 navicat premium 2 postgresql 14 装完上述软件后&#xff0c;远程连接上之后如下&#xff1a; 自己建立一个用户表users,然后随机生成一些数据即可 步骤 这里我将项目放到了gticode里&#xff0c;可以下载下来使用 https://gitcode.net/wangbiao9292/nodejs-p…

数据技术在金融行业有哪些应用_光点科技

随着信息技术的迅猛发展&#xff0c;大数据技术逐渐成为金融行业的重要工具。大数据技术的应用&#xff0c;不仅可以提高金融机构的运营效率&#xff0c;还能够提供更准确的风险评估和预测&#xff0c;从而为投资者和决策者提供更好的决策依据。 那么&#xff0c;大数据技术在…

Keil MDK编程环境下的 STM32 IAP下载(学习笔记)

IAP的引入 不同的程序下载方式 ICP ICP(In Circuit Programing)。在电路编程&#xff0c;可通过 CPU 的 Debug Access Port 烧录代码&#xff0c;比如 ARM Cortex 的 Debug Interface 主要是 SWD(Serial Wire Debug) 或 JTAG(Joint Test Action Group)&#xff1b; ISP ISP(I…

【VUE】ElementUI实现表格拖拽功能及行大图预览

一. 背景 elementui没自带的拖拽排序功能&#xff0c;所以需要借助第三方插件sortablejs 二. 步骤 安装 npm install sortablejs --save 引入 import Sortable from ‘sortablejs’ template文件应用 row-key填写唯一标识 id"dragTable"是为了通过document找到…