Git Product home page Git Product logo

scriptlet4docx's Introduction

Welcome to Scriptlet4Docx project

This project allows you to use Groovy template scriptlets inside a docx-document. Template document may be created directly from MS Word. All document styles will be preserved.

Usage

  1. Add scriptlet4docx maven dependency to your project com.github.snowindy:scriptlet4docx.
  2. Add Groovy scriptlets to your docx-document.
  3. Generate binding parameters to fill the template: Map<String, Object>.
  4. Use docxTemplater.process() process method to generate result docx.

Available scriptlet types

  1. ${contract.number}
  2. <%= contract.number %>
  3. <% out.print('This is your first contract!'); %>
  4. $[ @person.name ]

Scriptlet types explanation

${ data }

Equivalent to out.print(data)

<%= data %>

Equivalent to out.print(data)

<% any_code %>

Evaluates containing code. No output applied. May be used for divided conditions:

<% if (cond) { %>
This text block will be printed in case of "cond == true"
<% } else { %>
This text block will be printed otherwise.
<% } %>

$[ @listVar.field ]

This is a custom Scriptlet4docx scriptlet type designed to output collection of objects to docx tables. It must be used inside a table cell.

Say, we have a list of person objects. Each has two fields: 'name' and 'address'. We want to output them to a two-column table.

  1. Create a binding with key 'personList' referencing that collection.
  2. Create a two-column table inside a template docx-document: two columns, one row.
  3. $[@person.name] goes to the first column cell; $[@person.address] goes to the second.
  4. Voila, the whole collection will be printed to the table.

Live template example

You can check all mentioned scriptlets usage in a demonstration template.

Code example

// Setting up parameters for template processing
HashMap<String, Object>	params = new HashMap<String, Object>();
params.put("name", "John");
params.put("sirname", "Smith");

// Define template source
// Option 1. Template is read from file system
DocxTemplater docxTemplater = new DocxTemplater(new File("path_to_docx_template/template.docx"));
// Option 2. Template is read from a stream
DocxTemplater docxTemplater = new DocxTemplater(new FileInputStream(new File("path_to_docx_template/template1.docx")), "template1");

// Actual processing
// Option 1. Processing with file as result
docxTemplater.process(new File("path_to_result_docx/result.docx"), params);
// Option 2. Processing with writing result to OutputStream
docxTemplater.process(new FileOutputStream(new File("path_to_result_docx/result.docx")), params);
// Option 3. Processing with InputStream as result
InputStream docInputStream = docxTemplater.processAndReturnInputStream(params);

History

###0.8.5###

  1. Fixed issue "Line Break Characters aren't working correctly". issue#17

###0.8.4###

  1. Fixed issue "Gracefully use null replacements in case of missing property in template params". issue#15

###0.8.3###

  1. Fixed issue "Need ability to render <w:br/>". issue#14

###0.8.2###

  1. Merged pull request "Make TemplateEngine configurable". pull-request#13

###0.8.1###

  1. Fixed issue "Cannot use && in conditions". issue#11

###0.8.0###

  1. Fixed issue "Scriptlets don´t work in header and Footer". issue#8
  2. Fixed issue "Unable to use quotes in expressions". issue#9

###0.7.6###

  1. Fixed issue "Scriptlets don't allow using '>', '<', '"'". issue#6
  2. Updated dependencies versions

###0.7.5###

  1. Fixed issue "Table scripting does not work when there is <w:tr* tags inside table cell". issue#5

###0.7.4###

  1. Fixed issue "Table scripting does not work when <w:tr> construction is used within docx source". issue#4

###0.7.3###

  1. Added ability to specify nulls replacement for printing scriptlets. issue#3

###0.7.2###

  1. Added ability to write result directly to OutputStream.

###0.7.1###

  1. Added ability to return InputStream as process result.

###0.7.0###

  1. Added streaming feature. Based on issue#2
  2. Updated and simplified caching mechanism
  3. Updated API
  4. Added JavaDoc

###0.6.2###

  1. Fixed issue#1

Licence

Licenced under The (New) BSD License.

Authors and Contributors

Eugene Sapozhnikov (@snowindy).

githalytics.com alpha

scriptlet4docx's People

Contributors

jobinbasani avatar snowindy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

scriptlet4docx's Issues

Method code too large

I have a very large document (more than 200 forms). The first forms worked without problems. Currently I started to give the following error

Method code too large!

Stack:
groovy.lang.GroovyRuntimeException: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed: General error during class generation: Method code too large!

For what you can see is a limitation of the size of Java methods
https://stackoverflow.com/questions/24256316/method-code-too-large-in-groovy-grails

Any known workarround?

Cache cleanup for specific template key.

Now i have possibility to cleanup whole cache, but i can't cleanup cache for specific key.
Example of usage:

  1. I have my templates in database.
  2. Indentifier in DB is template key for cache.
  3. User have possibility to update templates.(So template key is the same, but content is not the same)
    In this scenario now i need cleanup whole cache.

Need ability to render <w:br/>

Hi,

Thank you for your excellent scriptlet4docx library. One missing feature seems to be ability to support parameters that contains '\n'. These need to be replaced with <w:br/> for appropriate rendering in most cases.

General suggestion, too much of the logic is private or package private. I looked into extending the DocxTemplater class but it is closed to extension because of private methods. I would suggest use of protected helper methods (similar to the Spring framework philosophy) for any significant logic that other might want to customize.

Thanks and Regards,
Farhan

Dynamic Images

There is a way to hava a byte[] or InputStream, that contains an image (jpeg or png) and put it in the template?

Code example:
Java Code:
byte[] image = loadImage();
map.put("image1", image);
InputStream docInputStream = docxTemplater.processAndReturnInputStream(map);

Template doc4x:

<%=image1%>

TableScriptingRowProcessor to support unicode

For TableScriptingRowProcessor.java

private static Pattern groovyFormPattern = Pattern
.compile("\$\[((.?)(@\w+).?)\]", Pattern.DOTALL | Pattern.MULTILINE);

we need to change this to

private static Pattern groovyFormPattern = Pattern
        .compile("\\$\\[((.*?)(@[\\w+\\W+][^.]*).*?)\\]", Pattern.DOTALL | Pattern.MULTILINE);

This will help in supporting the unicode names for the list.
Sample : $[@dgtag_test标签List.blahblah1]

Currently list comes as dgtag_testList

Unable to use quotes in expressions

I'm trying to do a String comparison operation and show/hide text in a template. The code is as below:

<% if(P_KEY == "ARF") { %>

Display ARF Text

<% } else { %>

Display non-ARF text

<% } %>

This throws an exception as below:

groovy.lang.GroovyRuntimeException: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed: 
GStringTemplateScript16.groovy: 2: Invalid variable name. Must start with a letter but was: ?ARF? 
. At [2:395]  @ line 2, column 395. 
   cd6c79a8e03"""; if(P_KEY == ?ARF?) { 
                                 ^ 

1 error 

        at groovy.text.GStringTemplateEngine$GStringTemplate.<init>(GStringTemplateEngine.java:190) 
        at groovy.text.GStringTemplateEngine.createTemplate(GStringTemplateEngine.java:105) 
        at groovy.text.TemplateEngine.createTemplate(TemplateEngine.java:38) 
        at org.scriptlet4docx.docx.DocxTemplater.processCleanedTemplate(DocxTemplater.java:158) 
        at org.scriptlet4docx.docx.DocxTemplater.process(DocxTemplater.java:255) 
        at org.scriptlet4docx.docx.DocxTemplater.processAndReturnInputStream(DocxTemplater.java:213) 
        at org.scriptlet4docx.docx.DocxTemplater.process(DocxTemplater.java:230) 

I tried to use def key="ARF" and then use the variable to compare, but that also didnt work.
I'm using v0.7.6
Can you please take a look?

Tags which are not part of param should be set as empty after the generation

Hi,

can we have the option to set the tags as empty if the param is not present in the parammap.

Template has ${EmployeeName} but param doesn't contain EmployeeName

So the final generated document should have empty value instead of ${EmptyName}.

Ex: My name is ${PERSON_NAME}.
After generation, if PERSON_NAME is not provided in the map it should be

My name is .

Scriptlets don't allow using '>', '<', '"'

My template has only one section now. So I'll just copy-paste the content here

<% if(L_TERM < 20) { %>

Show L_TERM less than 20 data

<% } else { %>

Show L_TERM greater than 20 data

<% } %>

and I'm getting the below error:

groovy.lang.GroovyRuntimeException: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed:
GStringTemplateScript4.groovy: 5: expecting ')', found ';' @ line 5, column 69.
c92364810"""; if(L_TERM < 20) {;
^

1 error

    at groovy.text.GStringTemplateEngine$GStringTemplate.<init>(GStringTemplateEngine.java:190) 
    at groovy.text.GStringTemplateEngine.createTemplate(GStringTemplateEngine.java:105) 
    at groovy.text.TemplateEngine.createTemplate(TemplateEngine.java:38) 
    at org.scriptlet4docx.docx.DocxTemplater.processCleanedTemplate(DocxTemplater.java:156) 
    at org.scriptlet4docx.docx.DocxTemplater.process(DocxTemplater.java:253) 
    at org.scriptlet4docx.docx.DocxTemplater.processAndReturnInputStream(DocxTemplater.java:211) 
    at org.scriptlet4docx.docx.DocxTemplater.process(DocxTemplater.java:228) 

I can use equal sign perfectly fine, but < and > will get escaped.

Gracefully use null replacements in case of missing property in template params

if i have ${agencyName} in my template and haven't key "agencyName" in params map, i ll get next exception:
: [http-thread-pool-7067(2)] | ERROR | Cannot process template: [3f8a977f-69e8-4947-8558-9859a35e977c${__docxTemplaterInstance.replaceIfNull(agencyName)}4cdce23e-9c89-4e70-894d-fb2d099a2695${__docxTemplaterInstance.replaceIfNull(applicant)}9a93a81f-817d-4542-9ab6-feeb6f6c00e5${__docxTemplaterInstance.replaceIfNull(dulSeries)}98917caf-49ae-4a91-9124-efc2921fc894${__docxTemplaterInstance.replaceIfNull(dulNumber)}05a5f06b-6fb5-4b30-b840-4250dbc5af8a${__docxTemplaterInstance.replaceIfNull(dulIssuedBy)}b3189a1a-3463-473d-a1e4-44e2b9588a16${__docxTemplaterInstance.replaceIfNull("serviceName")}626a17ed-1912-44fb-ac12-b86c50e5efc0].
groovy.lang.MissingPropertyException: No such property: agencyName for class: groovy.tmp.templates.GStringTemplateScript1
[12:38:45] Куксо Илья: 17.11.2015 12:34:14.276 | [http-thread-pool-7067(2)] | ERROR | java.lang.RuntimeException: java.lang.RuntimeException: groovy.lang.MissingPropertyException: No such property: agencyName for class: groovy.tmp.templates.GStringTemplateScript1
groovy.lang.MissingPropertyException: No such property: agencyName for class: groovy.tmp.templates.GStringTemplateScript1

Cannot use && in conditions

Multiple conditions cannot be used in if clauses.

<% if(VAL_1=="ABC" && VAL_2>5) { %>
Display text
<% } %>

Gives an error message that

GStringTemplateScript69.groovy: 2: expecting ')', found ';' @ line 2, column 412. 
   f(VAL_1=="ABC" &amp;&amp; VA 
                                 ^ 

1 error 

        at groovy.text.GStringTemplateEngine$GStringTemplate.<init>(GStringTemplateEngine.java:190) 
        at groovy.text.GStringTemplateEngine.createTemplate(GStringTemplateEngine.java:105) 
        at groovy.text.TemplateEngine.createTemplate(TemplateEngine.java:38) 
        at org.scriptlet4docx.docx.DocxTemplater.processCleanedTemplate(DocxTemplater.java:178) 
        at org.scriptlet4docx.docx.DocxTemplater.processCleanedTemplate(DocxTemplater.java:96) 
        at org.scriptlet4docx.docx.DocxTemplater.process(DocxTemplater.java:275) 
        at org.scriptlet4docx.docx.DocxTemplater.processAndReturnInputStream(DocxTemplater.java:233) 
        at org.scriptlet4docx.docx.DocxTemplater.process(DocxTemplater.java:250) 

However, a condition like

<% if(VAL_1=="ABC" || VAL_2>5) { %>
Display text
<% } %>

works fine.

No property in template.

Related to issue #15
if property is complex(${person.name} or ${person?.name}), nullreplacement doesn't work, also it doesn't work for tables ($[@person.name] or $[@person?.name]). In both situatioans if no property in top level params,i ll get an Exception

Null placeholder

If it is possible, to add custom replacement for null values?

Streams

Now exists only File api. Streams api will be very usefull.

Scriptlets don´t work in header and Footer

I tested using scriptlets in the header and footer of a docx file, but it didn´t work. This is a missing feature or a bug? I´m using verision 0.7.6

Ricardo Fraga Camelo

Line Break Characters aren't working correctly

Perhaps I'm doing something incorrectly, but looking at DocxTemplater.java and this line:

sv = sv.replace("\n", "<w:br/>");

It appears that new line characters (\r\n or \n) should result in <w:br/> elements being replaced within the XML. What I'm seeing instead is the <w:br/> text within the document post processing.

Expected:

Tyler Carver
Steven White
Amanda Bryant
Brenda Wout

Actual:

Tyler Carver<w:br/>Steven White<w:br/>Amanda Bryant<w:br/>Brenda Wout

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.