如何基于一个Freemarker模板创建多个文件

时间:2015-05-23 08:40:08

标签: java code-generation freemarker

我现在对freemarker有点麻烦。我想在我的模板中做什么:迭代元素列表并为每个元素创建一个新文件。

<#assign x=3>
<#list 1..x as i>
  ${i}
...create a new file with the output of this loop iteration...
</#list>

我在freemarker手册或谷歌中没有找到任何相关信息。有没有办法做到这一点?

3 个答案:

答案 0 :(得分:1)

您可以使用自定义指令实现此目的。请参阅LogLine record; FileHelperAsyncEngine<LogLines> engine = new FileHelperAsyncEngine<LogLines>(); engine.BeginReadFile(@"C:\logs\Log.log"); while (engine.ReadNext() != null) { record = engine.LastRecord; //record.Reported = true; <---I want to be able to edit this! // Your Code Here } ,尤其是freemarker.template.TemplateDirectiveModel。自定义指令可以指定其嵌套内容中使用的TemplateDirectiveBody。因此,您可以执行Writer之类的操作,其中嵌套内容将写入您在<@output file="...">...</@output>实现中提供的Writer,在这种情况下应该写入指定的文件。 (FMPP也这样做:single quotes vs double quotes

答案 1 :(得分:0)

仅使用FreeMarker无法做到这一点。它的想法是从模板生成单个输出流。它甚至不关心你是将结果保存到文件,直接传递给TCP套接字,以字符串形式存储在内存中还是做其他事情。

如果你真的想要实现这一点,你必须自己处理文件分离。例如,您可以插入特殊行,如:

//

之后你应该自己对FreeMarker输出进行后期处理,寻找以<#assign x=3> <#list 1..x as i> ${i} %%%%File=output${i}.html ... </#list> 开头的行并在此时创建一​​个新文件。

答案 2 :(得分:0)

正如 ddekany 所说,您可以通过实现指令来做到这一点。我编写了一个小例子:

package spikes;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import freemarker.core.Environment;
import freemarker.template.Configuration;
import freemarker.template.SimpleScalar;
import freemarker.template.Template;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

class OutputDirective implements TemplateDirectiveModel {
    
    @Override
    public void execute(
            Environment env, 
            @SuppressWarnings("rawtypes") Map params, 
            TemplateModel[] loopVars, 
            TemplateDirectiveBody body)
            throws TemplateException, IOException {
        
        SimpleScalar file = (SimpleScalar) params.get("file");
        
        FileWriter fw = new FileWriter(new File(file.getAsString()));
        body.render(fw);
        fw.flush();
    }
}

public class FreemarkerTest {   
    
    public static void main(String[] args) throws Exception {
        
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
        cfg.setDefaultEncoding("UTF-8");
        
        JsonObject model = new JsonObject()
                .put("entities", new JsonArray()
                        .add(new JsonObject()
                                .put("name", "Entity1"))
                        .add(new JsonObject()
                                .put("name", "Entity2")));
        
        Template template = new Template("Test", "<#assign model = model?eval_json><#list model.entities as entity><@output file=entity.name + \".txt\">This is ${entity.name} entity\n</@output></#list>", cfg);
        
        Map<String, Object> root = new HashMap<String, Object>();
        root.put("output", new OutputDirective());
        root.put("model", model.encode());
        Writer out = new OutputStreamWriter(System.out);
        template.process(root, out);
    }
}

这将生成两个文件:

“Entity1.txt”:这是Entity1实体

“Entity2.txt”:这是Entity2实体

:-)