一.导入freemaker和Echarts的jar包

      下载地址:https://mvnrepository.com/

java 图片 富文本格式导出word java导出带图片的word_echarts图表

 二. 制作模板

1.把需要替换的内容或图片用xxx替换(也可以直接用${xxx}格式,不过转xml的时候会被拆分开)。

2.表格只需要画一行,循环在xml中配置

java 图片 富文本格式导出word java导出带图片的word_echarts图表_02

3.如果多张图片的话,一定要选择不同的图片,不能为了省事使用同一张图片!

4.模板画好以后另存为xml格式,然后关掉word。

java 图片 富文本格式导出word java导出带图片的word_freemaker_03

(一定要选Word 2003 XML文档!!!血的教训啊!!!)

5.用notepad++打开你保存的xml格式的文档 Ctrl+F找到你之前定义的单词,用${}包住。如图:

java 图片 富文本格式导出word java导出带图片的word_导出word_04

替换图片,搜索<pkg:binaryData>,把文档中的这些内容(这些内容就是插入图片的BASE64字符串)删掉 换成${imageName}这种名称的

java 图片 富文本格式导出word java导出带图片的word_导出word_05

循环生成表格

找到表格的<w:tr>标签,在<w:tr>标签前加上<#list listName as list>,在</w:tr>后边加上</#list>,list标签可以使标签内的表格自动循环生成相应的行数,listName就是你后台的数据, list是个别名,中间每个字段需要改成${list.xxx}格式。

 

java 图片 富文本格式导出word java导出带图片的word_freemaker_06

完成模板,保存并关闭xml,修改文件的名称,改成.ftl格式的。(最后保存一份xml,方便以后修改,xml模板千万不要用word打开!!!)

三.Java代码

1.生成数据并返回集合

public static Map<String, Object> parseToMap(String date, String jrgl, 
             List<Map<String, Object>> list_CBQS) {
         Map<String, Object> datas = new HashMap();
         datas.put("rb_date", date);
         datas.put("text_JRGL", jrgl);        datas.put("text_CBQS", text_CBQS);
         datas.put("text_XXFB", text_XXFB);
         datas.put("text_QGQX", text_QGQX);        此处把需要放入到word里边的数据都放到集合中并返回,图片需要转换成BASE64格式的字符串
        String imgPath_CBQS = MakeImages(map_CBQS, "line", parm, queryType, request);
        return datas;
}
//生成图表的json格式文件
public String MakeImages(List<Map<String,Object>> map, String type, Map<String,Object> parm, String queryType, HttpServletRequest request){
         GsonOption option = new GsonOption();
         String[] arrAxis;
         if(type.equals("line")) {//折线图
             Line line = new Line();
             CategoryAxis  category = new CategoryAxis(); //轴分类
             if(queryType.equals("day")) {
                 arrAxis = new String[24];
                 for(int a = 0; a < 24; a++) {
                     String axis = StringUtils.leftPad(a + "", 2, "0");
                     arrAxis[a] = axis + ":00";
                     String value = "0";
                     for (Map<String, Object> data : map) {
                         if(axis.equals((data.get("sj") + ""))){
                             value = data.get("count") + "";
                         }
                     }
                     line.data(value);
                 }
                 category.data(arrAxis);
             }
             else if(queryType.equals("week") || queryType.equals("month")) {
                 String startTime = parm.get("startTime") + "";
                 String endTime = parm.get("endTime") + "";
                 Date startDate = new Date();
                 Date endDate = new Date();    
                 SimpleDateFormat sdfa = new SimpleDateFormat("yyyy-MM-dd");
                 SimpleDateFormat sdf2 = new SimpleDateFormat("MM月dd日");
                 try {
                     if(startTime.length()>0) {
                         startDate = sdfa.parse(startTime);
                     }
                     if(endTime.length()>0) {
                         endDate = sdfa.parse(endTime);
                     }
                     Date tmp = startDate;
                     Calendar dd = Calendar.getInstance();
                     dd.setTime(startDate);
                     int days = WordGeneratorUtils.getDaysOfMonth(startDate);
                     int aLength = queryType.equals("week") ? 7 : days;
                     arrAxis = new String[aLength];
                     int i = 0;
                     do {
                         tmp = dd.getTime();
                         String axis = sdf2.format(tmp) + "";
                         String value = "0";
                         arrAxis[i] = axis;
                         for (Map<String, Object> data : map) {
                             if(axis.equals((data.get("sj") + ""))){
                                 value = data.get("count") + "";
                                 break;
                             }
                         }
                         line.data(value);
                         // 天数加上1
                         dd.add(Calendar.DAY_OF_MONTH, 1);
                         i++;
                     } while (tmp.getTime() < endDate.getTime());
                     category.data(arrAxis);
                 }
                 catch(Exception ex) {
                 }
             }
             category.boundaryGap(false);//起始和结束两端空白策略
             option.series(line);
             option.xAxis(category);//x轴
             option.yAxis(new ValueAxis());
         }
         else if(type.equals("bar")) {//柱状图
             Bar bar = new Bar();
             CategoryAxis  category = new CategoryAxis(); //轴分类
             arrAxis = new String[legend.size()];
             int i = 0;
             for(String s : legend) {
                 String axis = s;
                 arrAxis[i] = axis;
                 Map<String,Object> item = new HashMap<>();
                 item.put("name", s);
                 String value = "0";
                 for (Map<String, Object> data : map) {
                     if(s.equals(data.get("category"))) {
                         value = data.get("count") + "";
                     }
                 }
                 item.put("value", value);
                 bar.data(item);
                 i++;
             }
             //5.设置显示工具
             option.tooltip().show(true).
                     formatter("{a}</br>{b}:{c}");//设置显示的格式 当鼠标放到柱状图上时的显示格式
             category.data(arrAxis);
             //category.boundaryGap(false);//起始和结束两端空白策略
             option.series(bar);
             option.xAxis(category);//x轴
             option.yAxis(new ValueAxis());
         }
         else if(type.equals("pie")) {//饼图
             Pie pie = new Pie();//创建饼图对象
             String[] searchs = {"正面", "负面", "中立"};
             int i = 0;
             for (Map<String, Object> data : map) {
                 Map<String,Object> item = new HashMap<>();
                 item.put("value",data.get("count"));
                 item.put("name",data.get("sentiment"));
                 pie.data(item);
                 searchs[i] = data.get("sentiment") + "";
                 i++;
             }
             //设置工具栏 展示  能标记
             option.toolbox().show(true).feature(Tool.mark);
             //设置图例  图例位置  图例对齐方式 竖列对齐
             option.legend().data(searchs).x("right").orient(Orient.vertical);
             option.series(pie);
         }
         String json = new Gson().toJson(option);
         String fileDate = parm.get("fileDate") + "";
         Map<String,Object> resultMap=new HashMap<>();
         return generateEChart(json, resultMap, fileDate, type, request);
     }private static final String JSpath = "C:\\echarts\\echarts-convert\\echarts-convert1.js";
     private static final Logger logger = Logger.getLogger(ReportContentRequest.class);
     
     public static String generateEChart(String options, Map<String,Object> resultMap, String date, String type, HttpServletRequest request) {
         String dataPath = writeFile(options, request);
         String fileName= type + date + ".png";
         String serverPath = request.getServletContext().getRealPath("/");
         
         //String path = "C:/echarts/test/" +fileName;//   /template/images/
         String path = request.getServletContext().getRealPath("/") + "/template/images/" + fileName;
         try {
             File file = new File(path);     //文件路径(路径+文件名)
             if (!file.exists()) {   //文件不存在则创建文件,先创建目录
                 File dir = new File(file.getParent());
                 dir.mkdirs();
                 file.createNewFile();
             }
             String cmd = "phantomjs " + JSpath + " -infile " + dataPath + " -outfile " + path;
             Process process = Runtime.getRuntime().exec(cmd);
             BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
             String line = "";
             while ((line = input.readLine()) != null) {
                 logger.info(line);
             }
             input.close();
             //是否删除json数据?
         } catch (IOException e) {
             e.printStackTrace();
         } 
         return path;
     }
  
     public static String writeFile(String options, HttpServletRequest request) {
         String dataPath = request.getServletContext().getRealPath("/") + "/template/json/" 
                             + UUID.randomUUID().toString().substring(0, 8) +".json";
         try {
             /* 写入Txt文件 */
             File writename = new File(dataPath); // 相对路径,如果没有则要建立一个新的output.txt文件
             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();
         }
         return dataPath;
     }图片转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);
     }

Base64Encoder如果报错,就项目名右键,buildpath,选择JRE System Library 选中Access rules 点击Edit ,如图

java 图片 富文本格式导出word java导出带图片的word_表格_07

 

public class WordGeneratorUtils {
     private static Configuration configuration = null;
     private static Map<String, Template> allTemplates = null;    private static class FreemarkerTemplate {
         public static final String POVERTY = "template_RB";
         public static final String POVERTY_ZB = "template_ZB";
         public static final String POVERTY_YB = "template_YB";
     }    static {
         configuration = new Configuration(Configuration.VERSION_2_3_28);
         configuration.setDefaultEncoding("utf-8");
         configuration.setClassForTemplateLoading(WordGeneratorUtils.class, "/template");//存放模板的路径,在项目名/src下,template为包名称
         allTemplates = new HashMap();
         try {
             allTemplates.put(FreemarkerTemplate.POVERTY, configuration.getTemplate(FreemarkerTemplate.POVERTY + ".ftl"));
         } catch (IOException e) {
             e.printStackTrace();
             throw new RuntimeException(e);
         }
     }}
 public static File createDoc(Map<String, Object> dataMap, Map<String, Object> parm, HttpServletRequest request) {
         try {
             int max=1000000000,min=1;
             int ran2 = (int) (Math.random()*(max-min)+min); 
             String serverPath = request.getServletContext().getRealPath("/");
             
             String name = "";//   /template/word/
             String queryType = parm.get("queryKey") + "";
             Template t = null;
             if(queryType.equals("day")) {
                 name = serverPath + "/template/word/Report_RB" + parm.get("fileDate") + ran2 + ".doc";
                 //name = "F:/Report_RB" + parm.get("fileDate") + ran2 + ".doc";
                 t = allTemplates.get(FreemarkerTemplate.POVERTY);
             }
             File f = new File(name);
             //t = allTemplates.get(FreemarkerTemplate.POVERTY);
             // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
             Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
             t.process(dataMap, w);
             w.close();
             return f;
         } catch (Exception ex) {
             ex.printStackTrace();
             throw new RuntimeException("生成word文档失败");
         }
     }OK,利用freemaker导出到word就完成啦!