美文网首页
【java】Echarts导出为word文档

【java】Echarts导出为word文档

作者: 浮生丷 | 来源:发表于2019-05-22 15:19 被阅读0次

    最近在使用Echarts做图表分析,同时要求有导出分析报告的功能,这时Echarts自带的保存图片功能就不能满足自己的需求,因此在网上找了许多前辈的资料,在此拾人牙慧,小作总结。

    主要思路:

    前台echarts生成图片后,获取base64码,传给后台解析,然后写入freemarker模板,进行下载。


    第一步:

    echarts的生成就不再多做赘述,可参考:echarts官网

    图表生成后,使用 myChart.getDataURL("png")获取base64码,其格式为:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABI4AAAEsCAYAAAClh/jbAAA ..."

    定义一个简单的测试点击按钮:<button type="button" id="button1">导出报告</button>,考虑到后台要接收base64码,同时要下载,因此选择使用ajax传递

    
    document.getElementById("button1").onclick = function(){
    
    //alert(myChart.getDataURL("png"))
    
    var image = myChart.getDataURL("png");
    
    $.ajax({
    
              type: 'post',
    
              url: "/****Servlet?method=getImage",
    
              data : {'image':image},
    
             dataType : "text",
    
             success : function(data) {
    
                      window.location.href="/*****Servlet?method=download"
    
             },
    
             error : function(error, status) {
    
             alert("机构数据错误!");
    
    }
    
    });
    
    }
    
    

    第二步:
    生成word文档的freemarker模板。
    首先创建一个word文档,里面加上自己所需要的内容
    如:

    image.png
    其中${name}的内容,即为所需动态写入的内容。
    然后选择另存为Word 2003 XML 文档(*.xml),注意名称不要包含中文。用xml编译器打开文件,推荐使用Firstobject free XML editor,按F8格式化文档,左边是文档结构,右边就是文档内容。找到原图片的base64码部分,替换成自己的${image}。代码如:
    <w:binData w:name="wordml://自定义.png" xml:space="preserve">${image}</w:binData>

    注意:>${image}<这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。

    同时需注意文档中:

    <w:t>${</w:t>
    </w:r>
    <w:r>
    <w:t>name</w:t>
    </w:r>
    <w:r>
    <w:rPr>
    <w:rFonts w:hint="fareast"/>
    </w:rPr>
    <w:t>}</w:t>
    

    之前修改的动态内容,由于word的xml格式化,也需要再次调整,改为<w:t>${name}</w:t>即可,一定注意删除和修改的标签。都调整完之后,就可以另存为.ftl后缀文件即可。注意:一定不要用word打开ftl模板文件,否则xml内容会发生变化,导致前面的工作白做了。


    第三步:
    工具类WordUtils.Java

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.net.URLEncoder;
    import java.util.Map;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    
    public class WordUtil {
         //配置信息,代码本身写的还是很可读的,就不过多注解了  
        private static Configuration configuration = null;  
        //这里注意的是利用WordUtils的类加载器动态获得模板文件的位置  
       // private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/templetes/";  
        private static final String templateFolder = "D:/***/js2";  
        static {  
            configuration = new Configuration();  
            configuration.setDefaultEncoding("utf-8");  
            try {  
                configuration.setDirectoryForTemplateLoading(new File(templateFolder));  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
       }  
      
        private WordUtil() {  
            throw new AssertionError();  
        }  
      
        public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map,String title,String ftlFile) throws IOException {  
            Template freemarkerTemplate = configuration.getTemplate(ftlFile);  
            File file = null;  
            InputStream fin = null;  
            ServletOutputStream out = null;  
            try {  
                // 调用工具类的createDoc方法生成Word文档  
                file = createDoc(map,freemarkerTemplate);  
                fin = new FileInputStream(file);  
      
                response.setCharacterEncoding("utf-8");  
                response.setContentType("application/msword");  
                // 设置浏览器以下载的方式处理该文件名  
                String fileName = title+ ".doc";  
                response.setHeader("Content-Disposition", "attachment;filename="  
                        .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));  
      
                out = response.getOutputStream();  
                byte[] buffer = new byte[512];  // 缓冲区  
                int bytesToRead = -1;  
                // 通过循环将读入的Word文件的内容输出到浏览器中  
                while((bytesToRead = fin.read(buffer)) != -1) {  
                    out.write(buffer, 0, bytesToRead);  
                }  
            } finally {  
                if(fin != null) fin.close();  
                if(out != null) out.close();  
                if(file != null) file.delete(); // 删除临时文件  
            }  
        }  
      
        private static File createDoc(Map<?, ?> dataMap, Template template) {  
            String name =  "sellPlan.doc";  
            File f = new File(name);  
            Template t = template;  
            try {  
                // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开  
                Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");  
                t.process(dataMap, w);  
                w.close();  
            } catch (Exception ex) {  
                ex.printStackTrace();  
                throw new RuntimeException(ex);  
            }  
            return f;  
        }  
    }
    

    servlet中
    设置全局变量private static String image
    doGet()中

              if(method.equals("download")){
                try {
                    download(request, response);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(method.equals("getImage")){
                try {
                    getImage(request, response);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    

    处理前台传递的base64码

        public void getImage(HttpServletRequest request, HttpServletResponse response){
            String src = request.getParameter("image");
            System.out.println(src);
            String base64 = src.replaceAll(" ", "+");
            // 数据中:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABI4AAAEsCAYAAAClh/jbAAA ...  在"base64,"之后的才是图片信息
            String[] arr = base64.split("base64,"); 
            image = arr[1];
            System.out.println(image);
    
        }
    

    使用map,写入模板

        /**
         * echarts导出
         * @throws IOException 
         */
        public void download(HttpServletRequest request, HttpServletResponse response){
            Map<String, String> map = new HashMap<String, String>();
            map.put("name", "机构预警");
            map.put("title", "预警玫瑰图");
            map.put("image", image);
            map.put("bz", "12");
            map.put("jl", "12");
            map.put("hb", "12");
            map.put("jk", "12");
            map.put("lj", "12");
            map.put("dw", "12");
            map.put("jx", "12");
            map.put("gw", "12");
            map.put("qp", "12");
            
            try {
                WordUtil.exportMillCertificateWord(request, response, map, "分析报告", "test.ftl");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    最后就是测试了
    效果图:


    image.png

    结语:
    第一次写,轻喷。由于多为测试代码,故细节部分未做处理,主要注重于功能的实现。
    完结撒花

    相关文章

      网友评论

          本文标题:【java】Echarts导出为word文档

          本文链接:https://www.haomeiwen.com/subject/slluzqtx.html