javavelocitystringwriter

Velocity Template merge method takes in a StringWriter but buff size not enough


I am trying to read from an excel file that contains more than 5000 rows and more than 10 worksheets using Apache POI , I get all the columns and row values and store it in a ArrayListMultiMap>, this logic works perfectly fine , then I store this object in the VelocityContext like this :

       VelocityContext context = new VelocityContext();
        context.put("excelMap", excelMap);

I need to use this collection in a velocity template, to populate a XML file with the values by iterating through excelMap, for that :

     VelocityEngine vEngine = new VelocityEngine();
    vEngine.setProperty("resource.loader", "class");
    vEngine.setProperty("class.resource.loader.class",  "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
    Template t = vEngine.getTemplate(vmTemplate);
    **StringWriter sw = new StringWriter(excelMap.size());**
    **t.merge(context,sw)**

However , the StringWriter capacity is always 1024 , and have already tried PrintWriter in combination with BufferedWriter, StringBuilderWriter, when the application reaches the merge line, it hangs and finally shows OutOfMemory exception.

Can anyone please help me , I have already ready all posts related to StringWriter and PrintWriter , but no luck.

Thank you


Solution

  • The 1024 limitation is a red herring. You're not getting out of memory error because of that. If the Writer exceeds the initial capacity more memory will be allocated. Your real problem is the spreadsheet and data, not Velocity.

    From the StringWriter javadocs:

    initialSize - The number of char values that will fit into this buffer before it is automatically expanded (emphasis mine)

    Instead of reading the entire spreadsheet into memory, you should try converting one worksheet or one entry at a time into XML. It might be that Velocity isn't your best choice.