使用Freemarker生成Word文档并在文档内添加Echarts图形报表或循环添加表格数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Alexshi5/article/details/84437300

一、制作.ftl后缀的word模板文件

1、新建一个word文档模板

        

使用其他文本编辑器编写表达式,如:Editplus

 

 2、将word文档另存为xml并改名为.ftl后缀的文件

另存完之后关闭word文档,将demo.xml的后缀修改为.ftl,然后使用文本编辑器打开demo.ftl文件

3、修改.ftl文件并生成最终的模板文件

① 修改图片的数据内容使用表达式代替

替换之后如下:

② 在数据表格中添加循环标签

 二、通过模板文件生成word文档

1、添加pom.xml的依赖

<dependency>
     <groupId>org.freemarker</groupId>
     <artifactId>freemarker</artifactId>
     <version>2.3.23</version>
</dependency>

2、index.jsp中添加一个Echarts图形报表

    var option = {
            angleAxis: {
                type: 'category',
                data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
                z: 10
            },
            radiusAxis: {
            },
            polar: {
            },
            series: [{
                type: 'bar',
                data: [1, 2, 3, 4, 3, 5, 1],
                coordinateSystem: 'polar',
                name: 'A',
                stack: 'a'
            }, {
                type: 'bar',
                data: [2, 4, 6, 1, 3, 2, 1],
                coordinateSystem: 'polar',
                name: 'B',
                stack: 'a'
            }, {
                type: 'bar',
                data: [1, 2, 3, 4, 1, 2, 5],
                coordinateSystem: 'polar',
                name: 'C',
                stack: 'a'
            }],
            legend: {
                show: true,
                data: ['A', 'B', 'C']
            }
        };

        var myChart = echarts.init(document.getElementById("content"));
        myChart.setOption(option);
        //获取Echart图形报表生成的Base64编码格式的数据
        var imgData = myChart.getConnectedDataURL();
        $.post('/demo/word',{'imgData':imgData},function (data) {
            alert(data);
        },'json');

3、后台处理请求并设置模板数据

@Controller
@RequestMapping("/demo")
public class DemoController {

    @RequestMapping("/word")
    @ResponseBody
    public String generateWord(String imgData){
        // 传递过程中  "+" 变为了 " " ,所以需要替换
        String newImageInfo = imgData.replaceAll(" ", "+");
        // 数据中:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABI4AAAEsCAYAAAClh/jbAAA ...
        // 在"base64,"之后的才是图片信息
        String[] arr = newImageInfo.split("base64,");

        //添加模板数据
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("userName","张三");
        dataMap.put("imgData",arr[1]);

        Person person1 = new Person("李四", "男", 36, "18811240001");
        Person person2 = new Person("王五", "女", 22, "18811240002");
        Person person3 = new Person("赵六", "男", 46, "18811240003");
        List<Person> personList = new ArrayList<>();
        personList.add(person1);
        personList.add(person2);
        personList.add(person3);
        dataMap.put("personList",personList);

        //文件生成路径
        String wordFilePath = "E:\\ftl";
        //文件生成名称
        String wordFileName = "演示文档.doc";
        //模板路径
        String templatePath = "E:\\ftl";
        //模板文件名称
        String templateFileName = "demo.ftl";

        //生成word文档
        Boolean result = WordUtil.writeWordReport(wordFilePath, wordFileName, templatePath, templateFileName, dataMap);
        if(result){
            return "success";
        }else {
            return "error";
        }
    }
}

4、生成word文档的工具类方法

/**
     * 根据freemarker生成word文档并存到指定目录
     * @param wordFilePath word文件生成的目录
     * @param wordFileName word文件名
     * @param templatePath 模板文件所在的目录
     * @param templateFileName 模板文件名
     * @param beanParams 生成word文件所需要的模板数据
     * @return
     */
    public static Boolean writeWordReport(String wordFilePath,String wordFileName,
        String templatePath,String templateFileName, Map<String, Object> beanParams) {
        Configuration config = new Configuration();
        Writer out = null;
        try {
            config.setDirectoryForTemplateLoading(new File(templatePath));
            config.setObjectWrapper(new DefaultObjectWrapper());
            Template template = config.getTemplate(templateFileName, "UTF-8");

            //获取文件目录,如果不存在则创建
            String filePath = "";
            int index = wordFilePath.lastIndexOf(File.separator);
            if(index != wordFilePath.length()-1){
                filePath = wordFilePath+ File.separator;
            }
            File file1 = new File(filePath);
            if(!file1.exists()){
                file1.mkdirs();
            }

            //输出文件
            File file = new File(filePath+wordFileName);
            FileOutputStream fos = new FileOutputStream(file);
            out = new OutputStreamWriter(fos, "UTF-8");
            template.process(beanParams, out);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }finally{
            try {
                if(out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

5、最终生成的word文档如下:

 

6、注意

        如果生成文档时报如下错误:

        Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??

        这有可能是你在传值过程中传了空值,导致模板引擎无法获取参数值,这时可以将表达式更改为${person.name?default('')}这种形式,这个表达式的意思是如果为空值就替换成'', 这样即便不小心传了空值也不会导致程序出错。

参考:

1、制作freemarker模板文件生成word文档

2、前端EChart图表转换为图片保存到服务器路径

3、使用JFreeChart做成柱状图写入word的总结

4、freemarker教程之list循环

5、FreeMarker 对null值的处理技巧

猜你喜欢

转载自blog.csdn.net/Alexshi5/article/details/84437300