百木园-与人分享,
就是让自己快乐。

java 导出word 包含echarts图表

需求是导出word,里面有数据统计图表。

要从后端直接导出图表的话,思路是这样的:

  先通过echarts生成图片,通过phantomjs 截图,将图片暂存在本地,再将图片转换成base64,然后放入word。

 

phantomjs 是一个基于js的webkit内核无头浏览器 也就是没有显示界面的浏览器。

 

一、准备word模板,转换成xml,需要填入数据的地方用${字段},需要天出图片的地方可以先随便一张用图片替代,方便之后找到图片插入位置。这里就不多说了

 

二、准备环境、依赖

 1、准备js,需要用到的,放在同一个文件夹下面。自己更改echarts-convert.js的路径

  

 

 

   echarts.min.js 和jquery.js 去官网下载

  echarts-convert.js的内容如下:

  

(function () {
    var system = require(\'system\');
    var fs = require(\'fs\');
    var config = {
        // define the location of js files
        //这样写要求这三个js在同一个文件夹下
        JQUERY: \'jquery-3.5.1.min.js\',
        //ESL: \'esl.js\',
        ECHARTS: \'echarts.min.js\',
        // default container width and height
        DEFAULT_WIDTH: \'400\',
        DEFAULT_HEIGHT: \'600\'
    }, parseParams, render, pick, usage;

    usage = function () {
        console.log(\"\\nUsage: phantomjs echarts-convert.js -options options -outfile filename -width width -height height\"
            + \"OR\"
            + \"Usage: phantomjs echarts-convert.js -infile URL -outfile filename -width width -height height\\n\");
    };

    pick = function () {
        var args = arguments, i, arg, length = args.length;
        for (i = 0; i < length; i += 1) {
            arg = args[i];
            if (arg !== undefined && arg !== null && arg !== \'null\' && arg != \'0\') {
                return arg;
            }
        }
    };

    parseParams = function () {
        var map = {}, i, key;
        if (system.args.length < 2) {
            usage();
            phantom.exit();
        }
        for (i = 0; i < system.args.length; i += 1) {
            if (system.args[i].charAt(0) === \'-\') {
                key = system.args[i].substr(1, i.length);
                if (key === \'infile\') {
                    // get string from file
                    // force translate the key from infile to options.
                    key = \'options\';
                    try {
                        map[key] = fs.read(system.args[i + 1]).replace(/^\\s+/, \'\');
                    } catch (e) {
                        console.log(\'Error: cannot find file, \' + system.args[i + 1]);
                        phantom.exit();
                    }
                } else {
                    map[key] = system.args[i + 1].replace(/^\\s+/, \'\');
                }
            }
        }
        return map;
    };

    render = function (params) {
        var page = require(\'webpage\').create(), createChart;

        var bodyMale = config.SVG_MALE;
        page.onConsoleMessage = function (msg) {
            console.log(msg);
        };

        page.onAlert = function (msg) {
            console.log(msg);
        };

        createChart = function (inputOption, width, height,config) {
            var counter = 0;
            function decrementImgCounter() {
                counter -= 1;
                if (counter < 1) {
                    console.log(messages.imagesLoaded);
                }
            }

            function loadScript(varStr, codeStr) {
                var script = $(\'<script>\').attr(\'type\', \'text/javascript\');
                script.html(\'var \' + varStr + \' = \' + codeStr);
                document.getElementsByTagName(\"head\")[0].appendChild(script[0]);
                if (window[varStr] !== undefined) {
                    console.log(\'Echarts.\' + varStr + \' has been parsed\');
                }
            }

            function loadImages() {
                var images = $(\'image\'), i, img;
                if (images.length > 0) {
                    counter = images.length;
                    for (i = 0; i < images.length; i += 1) {
                        img = new Image();
                        img.onload = img.onerror = decrementImgCounter;
                        img.src = images[i].getAttribute(\'href\');
                    }
                } else {
                    console.log(\'The images have been loaded\');
                }
            }
            // load opitons
            if (inputOption != \'undefined\') {
                // parse the options
                loadScript(\'options\', inputOption);
                // disable the animation
                options.animation = false;
            }

            // we render the image, so we need set background to white.
            $(document.body).css(\'backgroundColor\', \'white\');
            var container = $(\"<div>\").appendTo(document.body);
            container.attr(\'id\', \'container\');
            container.css({
                width: width,
                height: height
            });
            // render the chart
            var myChart = echarts.init(container[0]);
            myChart.setOption(options);
            // load images
            loadImages();
            return myChart.getDataURL();
        };

        // parse the params
        page.open(\"about:blank\", function (status) {
            // inject the dependency js
            page.injectJs(config.ESL);
            page.injectJs(config.JQUERY);
            page.injectJs(config.ECHARTS);


            var width = pick(params.width, config.DEFAULT_WIDTH);
            var height = pick(params.height, config.DEFAULT_HEIGHT);

            // create the chart
            var base64 = page.evaluate(createChart, params.options, width, height,config);
            fs.write(\"base64.txt\",base64);
            // define the clip-rectangle
            page.clipRect = {
                top: 0,
                left: 0,
                width: width,

                height: height
            };
            // render the image
            page.render(params.outfile);
            console.log(\'render complete:\' + params.outfile);
            // exit
            phantom.exit();
        });
    };
// get the args
    var params = parseParams();

// validate the params
    if (params.options === undefined || params.options.length === 0) {
        console.log(\"ERROR: No options or infile found.\");
        usage();
        phantom.exit();
    }
// set the default out file
    if (params.outfile === undefined) {
        var tmpDir = fs.workingDirectory + \'/tmp\';
        // exists tmpDir and is it writable?
        if (!fs.exists(tmpDir)) {
            try {
                fs.makeDirectory(tmpDir);
            } catch (e) {
                console.log(\'ERROR: Cannot make tmp directory\');
            }
        }
        params.outfile = tmpDir + \"/\" + new Date().getTime() + \".png\";
    }

// render the image
    render(params);
}());

 

  2、安装phantomjs

    网站:https://phantomjs.org/download.html

    选择合适的版本,我下载的是windows的,下载解压

    

 

 

     配置环境变量:

 

 

 

 

     

 

 

   

    然后测试是否安装成功,在命令行 输入:phantomjs -- version

    

 

 

     出现版本就表示安装成功了。

  

  3、构建echarts数据,就是option

    可以看原文档:https://gitee.com/free/ECharts#https://gitee.com/link?target=http%3A%2F%2Fblog.csdn.net%2Fisea533%2Farticle%2Fdetails%2F43225717

    

<dependency>
     <groupId>com.github.abel533</groupId>
     <artifactId>ECharts</artifactId>
     <version>3.0.0.6</version>
</dependency>                

 

三、生成echarts图表

  1、构建echarts 的数据option

   

    /**
     * 构建柱状图
     * @param cate x轴数据
     * @param enterpriseCnt 数据
     * @return
     */
    private static String getOption(List<String> cate, List<Integer> enterpriseCnt){
        GsonOption option = new GsonOption();
        option.title().setText(\"测试点位数图片\"); // 标题
        // 设置图例
        option.legend().data(\"点位数\").x(\"center\");

        Bar bar = new Bar();
        // x轴
        CategoryAxis category = new CategoryAxis();
        category.data(cate.toArray());

        //y 轴
        ValueAxis valueAxis = new ValueAxis();

        bar.data().addAll(enterpriseCnt); // 数据

        option.xAxis(category);  //x轴
        option.yAxis(valueAxis);  //y轴

        option.series(bar);// 多条柱子放多个bar就行

        String optionStr = option.toString().replace(\" \", \"\");
        log.info(optionStr);
        return optionStr;
    }

  2、生成echarts图片

  

    public static String generateEChart(String option, String filepath, String fileName) {
        String dataPath = writeOptionToFile(option, filepath); // 将option 数据写磁盘上用文件保存
        String path = filepath + fileName+\".png\"; //生成图片路径
        try {
            String JSpath = \"D:\\\\data\\\\tmp\\\\echarts-convert.js\";
            String cmd = \"phantomjs \" + JSpath + \" -infile \" + dataPath + \" -outfile \" + path;
            log.info(cmd);
            Process process = Runtime.getRuntime().exec(cmd);
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream(), \"UTF-8\"));
            String line = \"\";
            while ((line = input.readLine()) != null) {
                log.info(line);
            }
            input.close();
            // 删除json数据
            File jsonFile = new File(dataPath);
            jsonFile.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return path;
    }

  

    public static String writeOptionToFile(String options, String filepath) {
        String dataPath = filepath +\"echart.json\";
        try {
            File writename = new File(dataPath);
            if (!writename.getParentFile().exists()) {   //文件目录不存在,则先创建,不然会报错
                writename.getParentFile().mkdirs();
            }
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(writename), \"UTF-8\"));
            out.write(options);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataPath;
    }

 

  先测试一哈:

   

  这个时候在文件夹下可以看到图片啦:

  

 

 

 

四、导出word

  准备好数据,图片需要base64编码的,将之前生成的echart图片读入转base64

  

    public static String imageToBase64(String imgPath) {
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(imgPath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch(Exception ex) {
            ex.printStackTrace();
        }
        Base64Encoder encoder = new Base64Encoder();
        return encoder.encode(data);
    }

  

  然后就是正常word的导出了

  

 

   

  


来源:https://www.cnblogs.com/junnnnnnnn/p/16624351.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » java 导出word 包含echarts图表

相关推荐

  • 暂无文章