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

news2024/9/21 2:47:44
一 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 图片

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新人必看的Java基础知识点大梳理

一个Java程序可以认为是一系列对象的集合&#xff0c;而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。 对象&#xff1a;对象是类的一个实例&#xff0c;有状态和行为。例如&#xff0c;一条狗是一个对象&#xff0c;它的状态有&…

树莓派Pico|SHELL中microPython命令行|pico sdk开发环境搭建|点灯代码|必备开发工具|gcc涉及的include文件目录

文章目录 SHELL中microPython命令行SHELL中基于microPython的控制代码Hello Pico 代码SHELL中简单点灯代码SHELL中循环亮灯代码 基于pico sdk开发环境搭建及点灯代码必备开发工具Mingw-w64&#xff1a;著名C/C编译器GCCarm-none-eabi&#xff1a;交叉编译工具Git&#xff1a;开…

js翻转数组

arr [red, green, "blue", "pink", "purple"];var arr1 [];for (var i 1; i < arr.length; i) {console.log(arr1.length)arr1[arr1.length] arr[arr.length - i];console.log(arr1.length)}console.log(arr1);

echarts饼装图自定义图例和扇形区的文字

最近因为工作需要&#xff0c;需要开发一个大屏&#xff0c;后台给的数据是这个的&#xff0c;echarts是默认将数据data例的name属性作为图例和扇形图上展示文本&#xff0c;这里我需要自定义图例信息和内容&#xff0c;通过这篇文章&#xff0c;记录下如何修改这些内容&#x…

spring IOC详解

一、IOC IoC就是Inversion of Control&#xff0c;控制反转。在Java开发中&#xff0c;IoC意味着将你设计好的类交给系统去控制&#xff0c;而不是在你的类内部控制。这称为控制反转。 下面我们以几个例子来说明什么是IoC。假设我们要设计一个Girl和一个Boy类&#xff0c;其中G…

【PostgreSQL-16新特性之普通用户的保留连接个数(reserved_connections)】

PostgreSQL数据库为了保证在高并发&#xff0c;高连接数情况下某些用户能够正常连接到数据库里&#xff0c;设立了几个用户连接的保留个数。 本文介绍了PostgreSQL16版本前为超级用户保留的连接数&#xff08;superuser_reserved_connections&#xff09;以及PostgreSQL16版本…

【江西省研究生数学建模竞赛】题目之三 植物的多样性 建模方案及参考文献

【江西省研究生数学建模竞赛】题目之三 植物的多样性 建模方案及参考文献 1 题目 2023年江西省研究生数模竞赛题目之三 植物的多样性 植物作为食物链中的生产者&#xff0c;通过光合作用吸收二氧化碳&#xff0c;制造氧气&#xff0c;同时为其他生物提供食物和栖息地&#x…

前端JavaScript入门-day04

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 函数 为什么需要函数 函数使用 函数的声明语法 函数名命名规范 函数的调用语法 函数体 函数传参 声…

Scala集合与Java集合的互转函数asScala与asJava

只有引入隐式转换类 JavaConverters&#xff0c;才能使用Scala集合与Java集合之间的转换函数。 为方便理解&#xff0c;看下面的例子&#xff1a; import scala.collection.JavaConverters._ val javaList java.util.Arrays.asList("hi", "bye") val sca…

Restic文件备份工具

一、Restic介绍 Restic 是一款 GO 语言开发的开源免费且快速、高效和安全的跨平台备份工具。Restic 使用加密技术来保证你的数据安全性和完整性&#xff0c;可以将本地数据加密后传输到指定的存储。Restic 同样支持增量备份&#xff0c;可随时备份和恢复备份。Restic 支持大多数…

一个自动下载网页图片的python小程序

文章目录 1.一些杂七杂八的引入2.实现2.1 安装所需python包2.1.1 requests包2.1.1 BeautifulSoup包 3.源码分享4.效果展示 1.一些杂七杂八的引入 最近是端午节&#xff0c;本人碰巧又刚考完试&#xff08;数学砸了&#xff0c;估分115&#xff0c;别的还行&#xff09; 于是……

Oracle 查询优化改写(第六章)

第六章 使用数字 1 常用聚集函数&#xff08;空值处理&#xff09; 2 生成累计和 --公司为了查看用人成本&#xff0c;需要对员工的工资进行累加&#xff0c; --以便查看员工人数与工资支出之间的对应关系。 SELECT Empno,Ename,Sal,SUM(Sal) Over(ORDER BY Empno) AS 成本累…

绿色能源外交:国际间合作促进可再生能源全球普及

随着全球气候变化的威胁日益凸显&#xff0c;减少碳排放和转向可持续能源已经成为国际社会的共同目标。在这个背景下&#xff0c;绿色能源外交应运而生。绿色能源外交是指国际间合作&#xff0c;通过技术转让、政策协调和资金支持等手段&#xff0c;推动可再生能源在全球范围内…

文字PDF转换为图片格式的PDF

在我们的日常工作和生活中&#xff0c;有时候我们需要对PDF文件进行一些特殊处理。有时候&#xff0c;我们希望将PDF的每一页提取出来作为图片&#xff0c;方便在其他场景中使用&#xff1b;而有时候&#xff0c;我们则需要将PDF内的内容转换为图片格式&#xff0c;以防止他人对…

docker 操作手册

名词解释 images&#xff1a;封装了应用程序的镜像 tag&#xff1a;镜像的标记&#xff0c;一个镜像可以创建多个标记 container&#xff1a;装载镜像并运行 常用命令 查看容器 docker ps -a //查看全部镜像 启动容器 docker start mysql //启动mysql容器 停止容器 doc…

Python篇——数据结构与算法(第七部分:树)

目录 1.树与二叉树 2.树的实例&#xff1a;模拟文件系统 3.二叉树 4.二叉树的遍历 5.二叉搜索树 5.1插入 5.2查询 5.3删除 1.树与二叉树 2.树的实例&#xff1a;模拟文件系统 # 树的实例 class Node:def __init__(self, name, typedir):self.name nameself.type typ…

springboot集成mybatisPlus

1、添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-jav…

Mysql快速生成Java实体类

需求缘由 在使用MybatisPlus过程中&#xff0c;就肯定会创建实体类&#xff0c;虽然 MybatisPlus 也为我们提供了代码生成器&#xff0c;但是我感觉功能有点多了&#xff0c;我只需要创建实体的方法即可&#xff0c;假如我想快速将上述表转为如下的Bean对象&#xff0c;该怎么搞…

arcgis api for JavaScript4.2x 在vue中白膜图层的加载、(分类、分段)渲染

这篇文章是对有webgis前端开发经验的人 1、假设之前的三维视图均已成功加载&#xff0c;获取到了三维视图&#xff0c;这里的三维视图变量定义的名字是mapView。&#xff08;PS&#xff1a;三维视图mapview在项目初始化已经设置了&#xff0c;本示例中会直接使用调用结果&…

CentOS 8安装Oracle 19c rpm包

一、环境 centos 8 oracle 19c rpm安装 二、安装前准备 1、创建用户组 groupadd oinstall groupadd dba useradd -g oinstall -G dba oracle passwd oracle2、安装依赖包 如果yum找不到安装包&#xff0c;可以去下载 https://centos.pkgs.org/ 点击跳转 缺少的依赖包可…