【问题标题】:How to correctly evaluate Velocity context?如何正确评估 Velocity 上下文?
【发布时间】:2021-01-12 16:24:24
【问题描述】:

我是 Apache Velocity 的新手,我想知道评估我的上下文的正确方法是什么。这是我的情况:

我想打开一个用作模板的.docx 文件,将其中的一些单词替换为Apache Velocity,然后将结果保存到一个新的.docx 文件中。为此,我的代码如下:

    public static void main(String[] args) {

    Velocity.init();

    final VelocityContext context = new VelocityContext();
    context.put("city", "Firenze");
    context.put("user", "Federico");
    context.put("date", "23/09/20");
    context.put("op", "Mario Rossi");
    ArrayList<String> list = new ArrayList<String>();
    list.add("Data futura");
    list.add("Scrittura indecifrabile");
    context.put("list", list);

    String name = "tempWord.docx";
    List<XWPFParagraph> paragraphs;

    try {
        paragraphs = readDocxFile(name);
        XWPFDocument doc = new XWPFDocument();
        final FileOutputStream fos = new FileOutputStream(new File("outFile.docx"));

        for(XWPFParagraph para : paragraphs) {
            StringWriter sw = new StringWriter();
            System.out.println(para.getText());
            Velocity.evaluate(context, sw, "test1", para.getText());
            XWPFParagraph par = doc.createParagraph();
            XWPFRun run = par.createRun();
            run.setText(sw.toString());
        }
        doc.write(fos);
        fos.close();

    } catch(Exception rnfe) {
        rnfe.printStackTrace();
    }

}

readDocxFile() 是一种我已经定义并且可以完美运行的方法。我担心的是给定这个模板:

    ${city}, ${date}

    Gentile ${user},
    Con la seguente la informiamo che non abbiamo potuto processare la sua richiesta a causa dei seguenti errori:
    #foreach(${name} in ${list})
        ${name}
    #end
    La preghiamo dunque di correggere e sottoporre nuovamente il modulo entro e non oltre la data di scadenza.
    Cordiali saluti,

    ${op}

我收到此错误

    1606 [main] ERROR org.apache.velocity.parser - test1: Encountered "<EOF>" at line 1, column 29.

它在解析 #foreach 循环时发生,它似乎与 Velocity.evaluate() 方法有关,因为如果我创建一个 tmp.txt 文件并将其用作 Velocity 模板以及 Velocity.mergeTemplate() 方法代码正确运行。这种方法的问题是我不想在每次必须评估上下文时都存储.txt,而且我必须保持原始文件格式。

据我了解,evaluate() 逐行计算,因此显然 #foreach 块的计算不正确。

我知道Apache POI 也可以像docx4j 一样执行上下文替换,但我必须使用 Velocity。

如何正确评估上下文?

【问题讨论】:

    标签: java velocity vtl


    【解决方案1】:

    我会尝试使用自定义分隔符合并所有段落,然后在该分隔符上拆分结果以重建段落。大致如下:

    try {
        paragraphs = readDocxFile(name);
        XWPFDocument doc = new XWPFDocument();
        final FileOutputStream fos = new FileOutputStream(new File("outFile.docx"));
    
        StringWriter sw = new StringWriter();
        String separator = "_PARA_";
        for(XWPFParagraph para : paragraphs) {
            System.out.println(para.getText());
            sw.append(para.getText());
            sw.append(separator);
        }
    
        StringWriter rst = new StringWriter();
        Velocity.evaluate(context, rst, "test1", sw.toString);
        
        for (String para : rst.toString().split(separator))
            XWPFParagraph par = doc.createParagraph();
            XWPFRun run = par.createRun();
            run.setText(para);
        }
        doc.write(fos);
        fos.close();
    
    } catch(Exception rnfe) {
        rnfe.printStackTrace();
    }
    

    不过,您可能已经意识到,通过将段落来回转换为这样的文本,您很容易受到格式标签松散的影响,更不用说标题、表格、枚举等了。它应该适用于标准正文不过是文字。

    【讨论】:

      猜你喜欢
      • 2021-07-23
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多