I'm new to Apache Velocity and I would like to know what is the correct way of evaluating my context. Here is my situation:
I'd like to open a .docx
file used as template, replace some words in it with Apache Velocity
and then save the result in a new .docx
file. To do that, my code is the following:
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();
}
}
where readDocxFile()
is a method that I've already defined and works flawlessly. What concerns me is that given this template:
${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}
I get this error
1606 [main] ERROR org.apache.velocity.parser - test1: Encountered "<EOF>" at line 1, column 29.
It happens while parsing the #foreach
loop and it seems to be related to the Velocity.evaluate()
method, since if I create a tmp.txt
file and use it as a Velocity template along with the Velocity.mergeTemplate()
method the code runs correctly. The problem with this approach is that I don't want to store a .txt
every time that I have to evaluate a context, and I must maintain the original file format.
From what I've understood evaluate()
evaluates line by line, so apparently the #foreach
block is being evaluated incorrectly.
I know that Apache POI
could also perform context replacement as well as docx4j
, but I must use Velocity.
How can I correctly evaluate the context?