java服务端生成带echars图片的word

最近项目有个需求 :服务器定时跑数据生成分析图并导出word文档。附加word转pdf功能。

首先,关于服务器端(java)生成echars图片。

原理:通过无头浏览器调用js方法,使用服务端查出来的数据生成echars图片,此处使用了phantomjs作为无头浏览器(此开源项目目前处于终止状态,谷歌浏览器等都开发出类似功能,源码贡献者成员之一终止继续更新版本)。下附详细代码。

package com.gelpag.business.echarsWord.utils;

import org.apache.commons.lang.StringUtils;

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

/**
 * Created by zhangzhiqiang on 2019/6/4.
 */
public class EchartGenerate {

    private static final String JSpath = "/Users/zhangzhiqiang/Downloads/phantomjs/echarts-convert/echarts-convert1.js";


    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("水");
        list.add("温度");
        List alist = new ArrayList();
        alist.add("120");
        alist.add("132");
        alist.add("101");
        alist.add("134");
        alist.add("90");
        alist.add("230");
        alist.add("210");
        alist.add("132");
        alist.add("210");
        alist.add("132");
        alist.add("101");
        alist.add("134");

        //此处option直接从echars官网copy即可,需要什么样的类型的分析图就写什么
        String optiona = "{tooltip : {trigger: 'axis'}, legend: {data:['" + listToString(list, "','") + "'] }, toolbox: {show : true, feature : {saveAsImage : {show: true} } }, calculable : true, xAxis : [{type : 'category', data : ['" + listToString(alist, "','") + "'] } ], yAxis : [{type : 'value'} ], series : [{name:'水', type:'bar', data:[2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3], }, {name:'温度', type:'bar', data:[2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3], } ] }";
        Map resultMap=new HashMap<>();
        generateEChart(optiona, resultMap);
    }


    public static String generateEChart(String options, Map resultMap) {
        String dataPath = writeFile(options);
        String fileName= "test-"+UUID.randomUUID().toString().substring(0, 8) + ".png";
        String path = "/Users/zhangzhiqiang/Downloads/temp/Echart/" +fileName;
        try {
            //文件路径(路径+文件名)
            File file = new File(path);
            //文件不存在则创建文件,先创建目录
            if (!file.exists()) {
                File dir = new File(file.getParent());
                dir.mkdirs();
                file.createNewFile();
            }
            //此处phantomjs命令调用应为全路径
            String cmd = "/Users/zhangzhiqiang/Downloads/phantomjs/phantomjs/bin/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) {
            }
            input.close();

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

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

    public static String listToString(List list, String separator) {
        return StringUtils.join(list.toArray(),separator);
    }
}
phantomjs插件及相关js地址

其次,附加echars图片的word文档导出

这里在网上查了好多POI导出及调用软件导出等方法,都不理想(代码不够简洁,实现复杂且所需jar繁多,易冲突),最后找到一个基于POI的开源模板poi-tl,实现代码相当简洁,且功能强大。下附代码及实现效果。

package com.gelpag.business.echarsWord.utils;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * Created by zhangzhiqiang on 2019/6/13.
 * poi-tl模板替换文字与图片
 */
public class PoitlTest {
    private static final Logger log = LoggerFactory.getLogger(PoitlTest.class);

    /** 项目资源路径. */
    private static final String PATH = "/Users/zhangzhiqiang/Downloads";

    /** word模板路径. */
    private static final String DOC_PATH = PATH + "/Java_echars_word/csWord.docx";

    /** 图片路径. */
    private static final String PIC_PATH = PATH + "/temp/Echart/1.png";

    /** 输出文件及路径. */
    private static final String OUTPUT_PATH = "/Users/zhangzhiqiang/Downloads/Java_echars_word/poitl_out_word.docx";

    /**
     * main方法.
     * @param args 数组参数
     */
    public static void main(String[] args) throws IOException {
        Map map = new HashMap();
        map.put("company_name","麦克奥迪");
        map.put("picture",new PictureRenderData(600, 400, PIC_PATH));
        RowRenderData header = new RowRenderData();
        List cellRenderDataList = new ArrayList();
        cellRenderDataList.add(new CellRenderData(new TextRenderData("")));
        cellRenderDataList.add(new CellRenderData(new TextRenderData("1月")));
        cellRenderDataList.add(new CellRenderData(new TextRenderData("2月")));
        cellRenderDataList.add(new CellRenderData(new TextRenderData("3月")));
        header.setCellDatas(cellRenderDataList);


        RowRenderData row0 = RowRenderData.build("张三", "研究生");
        RowRenderData row1 = RowRenderData.build("李四", "博士");
        RowRenderData row2 = RowRenderData.build("王五", "博士后");

        map.put("table", new MiniTableRenderData(header, Arrays.asList(row0, row1, row2)));
        XWPFTemplate template = XWPFTemplate.compile(DOC_PATH).render(map);
        FileOutputStream out = new FileOutputStream(OUTPUT_PATH);
        template.write(out);
        out.flush();
        out.close();
        template.close();
        log.info("通过'poi-tl'导出word成功!");
    }
}

模板:java服务端生成带echars图片的word_第1张图片

导出结果

java服务端生成带echars图片的word_第2张图片

关于word转pdf

网上许多实现我都看了一下,如JobConverter + OpenOffice     ( Windows系统下 ) ,SaveAsPDFandXPS + jacob (Windows操作系统下,电脑里有office),或者纯POI解决(jar繁琐易冲突)。(这三种方法可以去地址看一下)

最终采用了aspose.words的方法实现(此为商业jar,我用的破解,正版实在太贵了!),实现颇为简单。下附代码

 

package com.gelpag.business.echarsWord.utils;

import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

/**
 * Created by zhangzhiqiang on 2019/6/14.
 */
public class Word2PdfUtil {
    public static void main(String[] args) {
        doc2pdf("/Users/zhangzhiqiang/Downloads/Java_echars_word/csWord.docx","/Users/zhangzhiqiang/Downloads/Java_echars_word/word_to_pdf.pdf");
    }
    public static boolean getLicense() {
        boolean result = false;
        try {
            //引用当前项目中的license.xml
            InputStream is = Word2PdfUtil.class.getResourceAsStream("/license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    public static void doc2pdf(String inPath, String outPath) {
        //验证License 若不验证则转化出的pdf文档会有水印产生
        if (!getLicense()) {
            return;
        }
        try {
            long old = System.currentTimeMillis();
            // 新建一个空白pdf文档
            File file = new File(outPath);
            FileOutputStream os = new FileOutputStream(file);
            // Address是将要被转化的word文档
            Document doc = new Document(inPath);
            // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
            doc.save(os, SaveFormat.PDF);
            // EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

相关jar包及破解地址

多有借鉴大神https://www.colabug.com/331128.html

上述方法实测完美实现服务端生成echars图片插入word文档并保存,以及word转pdf功能。

 

你可能感兴趣的:(java服务端生成带echars图片的word)