Sambhashanam
तकनीकी संभाषणम्
Navigation
  • Microsoft Technologies
  • Java Technologies
  • LAMP Technologies
  • Opensource
    • Microsoft Opensource
    • LAMP Opensource
    • Java Opensource
You are here: Home › Java Opensource › Mail merge in java for Microsoft Word document – Part I
← How to create user define properties in maven pom.xml
Mail merge in java for Microsoft Word document and convert to PDF without iText – Part II →

Mail merge in java for Microsoft Word document – Part I

June 24, 2013 | Filed under: Java Opensource, Java Technologies, Opensource and tagged with: Java Mail Merge MS Word, Merge MS Word using Java, Merge Word Document using XdocReport

In one of the projects I was working on – we defined template using XSL, passed XML data and then generated PDF using Apache FOP. But it was tough to manage change – for even changing a single dot, the business needed to contact the developer.

We then started searching opensource and commercial friendly API which can merge the template defined in Microsoft Word with variables and produce the merged document. Our search ended with XDocReport which is available in The MIT License (MIT) and with really good documentation.

I did a POC and it came really well on expectations. The salient features I found are:
1. Replacing variables
2. Replacing Image Variables
3. Dynamicity for tabular format data.

I am putting below the java code I have written for the POC and attaching files used in merging along with out put files.

Add below in the pom.xml

 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>docx-to-docx</groupId>
	<artifactId>docx-to-docx</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>docx-to-docx</name>
 
	<description>Merging Microsoft Word DOCX format with variable replacement using xdocreport</description>
 
	<properties>
		<xdocreport.version>0.9.8</xdocreport.version>
	</properties>
 
	<dependencies>
		<dependency>
			<groupId>fr.opensagres.xdocreport</groupId>
			<artifactId>fr.opensagres.xdocreport.core</artifactId>
			<version>${xdocreport.version}</version>
		</dependency>
		<dependency>
			<groupId>fr.opensagres.xdocreport</groupId>
			<artifactId>fr.opensagres.xdocreport.document</artifactId>
			<version>${xdocreport.version}</version>
		</dependency>
		<dependency>
			<groupId>fr.opensagres.xdocreport</groupId>
			<artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
			<version>${xdocreport.version}</version>
		</dependency>
		<dependency>
			<groupId>fr.opensagres.xdocreport</groupId>
			<artifactId>fr.opensagres.xdocreport.converter</artifactId>
			<version>${xdocreport.version}</version>
		</dependency>
		<dependency>
			<groupId>fr.opensagres.xdocreport</groupId>
			<artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
			<version>${xdocreport.version}</version>
		</dependency>
	</dependencies>
 
	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>2.3.2</version>
					<configuration>
						<source>1.6</source>
						<target>1.6</target>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
 
 
</project>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>docx-to-docx</groupId> <artifactId>docx-to-docx</artifactId> <version>0.0.1-SNAPSHOT</version> <name>docx-to-docx</name> <description>Merging Microsoft Word DOCX format with variable replacement using xdocreport</description> <properties> <xdocreport.version>0.9.8</xdocreport.version> </properties> <dependencies> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.xdocreport.core</artifactId> <version>${xdocreport.version}</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.xdocreport.document</artifactId> <version>${xdocreport.version}</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.xdocreport.document.docx</artifactId> <version>${xdocreport.version}</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.xdocreport.converter</artifactId> <version>${xdocreport.version}</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId> <version>${xdocreport.version}</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </pluginManagement> </build> </project>

Created a java file to produce merged document using XdocReport.

/**
 * 
 */
package com.sambhashanam.docx;
 
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
 
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.core.io.internal.ByteArrayOutputStream;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.images.FileImageProvider;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
 
/**
 * @author Dhananjay Jha
 *
 */
public class DocxDocumentMergerAndConverter {
	/**
	 * Takes file path as input and returns the stream opened on it
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	public InputStream loadDocumentAsStream(String filePath) throws IOException{
		//URL url =new File(filePath).toURL();
		URL url =new File(filePath).toURI().toURL();
		InputStream documentTemplateAsStream=null;
		documentTemplateAsStream= url.openStream();
		return documentTemplateAsStream;
	}
	/**
	 * Loads the docx report 
	 * @param documentTemplateAsStream
	 * @param freemarkerOrVelocityTemplateKind
	 * @return
	 * @throws IOException
	 * @throws XDocReportException
	 */
	public IXDocReport loadDocumentAsIDocxReport(InputStream documentTemplateAsStream, TemplateEngineKind freemarkerOrVelocityTemplateKind) throws IOException, XDocReportException{
		IXDocReport xdocReport = XDocReportRegistry.getRegistry().loadReport(documentTemplateAsStream, freemarkerOrVelocityTemplateKind);
		return xdocReport;
	}
	/**
	 * Takes the IXDocReport instance, creates IContext instance out of it and puts variables in the context 
	 * @param report
	 * @param variablesToBeReplaced
	 * @return
	 * @throws XDocReportException
	 */
	public IContext replaceVariabalesInTemplateOtherThanImages(IXDocReport report, Map<String, Object> variablesToBeReplaced) throws XDocReportException{
		IContext context = report.createContext();
		for(Map.Entry<String, Object> variable: variablesToBeReplaced.entrySet()){
			context.put(variable.getKey(), variable.getValue());
		}
		return context;
	}
	/**
	 * Takes Map of image variable name and fileptah of the image to be replaced. Creates IImageprovides and adds the variable in context
	 * @param report
	 * @param variablesToBeReplaced
	 * @param context
	 */
	public void replaceImagesVariabalesInTemplate(IXDocReport report, Map<String, String> variablesToBeReplaced, IContext context){
 
		 FieldsMetadata metadata = new FieldsMetadata();
         for(Map.Entry<String, String> variable: variablesToBeReplaced.entrySet()){
                 metadata.addFieldAsImage(variable.getKey());
                 context.put(variable.getKey(), new FileImageProvider(new File(variable.getValue()),true));
         }
         report.setFieldsMetadata(metadata);
 
	}
	/**
	 * Generates byte array as output from merged template
	 * @param report
	 * @param context
	 * @return
	 * @throws XDocReportException
	 * @throws IOException
	 */
	public byte[] generateMergedOutput(IXDocReport report,IContext context ) throws XDocReportException, IOException{
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		report.process(context, outputStream);
		return outputStream.toByteArray();
	}
	/**
	 * Takes inputs and returns merged output as byte[]
	 * @param templatePath
	 * @param templateEngineKind
	 * @param nonImageVariableMap
	 * @param imageVariablesWithPathMap
	 * @return
	 * @throws IOException
	 * @throws XDocReportException
	 */
	public byte[] mergeAndGenerateOutput(String templatePath, TemplateEngineKind templateEngineKind, Map<String, Object> nonImageVariableMap,Map<String, String> imageVariablesWithPathMap ) throws IOException, XDocReportException{
		InputStream inputStream = loadDocumentAsStream(templatePath);
		IXDocReport xdocReport = loadDocumentAsIDocxReport(inputStream,templateEngineKind);
		IContext context = replaceVariabalesInTemplateOtherThanImages(xdocReport,nonImageVariableMap);
		replaceImagesVariabalesInTemplate(xdocReport, imageVariablesWithPathMap, context);
		byte[] mergedOutput = generateMergedOutput(xdocReport, context); 
		return mergedOutput;
	}
}

/** * */ package com.sambhashanam.docx; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Map; import fr.opensagres.xdocreport.core.XDocReportException; import fr.opensagres.xdocreport.core.io.internal.ByteArrayOutputStream; import fr.opensagres.xdocreport.document.IXDocReport; import fr.opensagres.xdocreport.document.images.FileImageProvider; import fr.opensagres.xdocreport.document.registry.XDocReportRegistry; import fr.opensagres.xdocreport.template.IContext; import fr.opensagres.xdocreport.template.TemplateEngineKind; import fr.opensagres.xdocreport.template.formatter.FieldsMetadata; /** * @author Dhananjay Jha * */ public class DocxDocumentMergerAndConverter { /** * Takes file path as input and returns the stream opened on it * @param filePath * @return * @throws IOException */ public InputStream loadDocumentAsStream(String filePath) throws IOException{ //URL url =new File(filePath).toURL(); URL url =new File(filePath).toURI().toURL(); InputStream documentTemplateAsStream=null; documentTemplateAsStream= url.openStream(); return documentTemplateAsStream; } /** * Loads the docx report * @param documentTemplateAsStream * @param freemarkerOrVelocityTemplateKind * @return * @throws IOException * @throws XDocReportException */ public IXDocReport loadDocumentAsIDocxReport(InputStream documentTemplateAsStream, TemplateEngineKind freemarkerOrVelocityTemplateKind) throws IOException, XDocReportException{ IXDocReport xdocReport = XDocReportRegistry.getRegistry().loadReport(documentTemplateAsStream, freemarkerOrVelocityTemplateKind); return xdocReport; } /** * Takes the IXDocReport instance, creates IContext instance out of it and puts variables in the context * @param report * @param variablesToBeReplaced * @return * @throws XDocReportException */ public IContext replaceVariabalesInTemplateOtherThanImages(IXDocReport report, Map<String, Object> variablesToBeReplaced) throws XDocReportException{ IContext context = report.createContext(); for(Map.Entry<String, Object> variable: variablesToBeReplaced.entrySet()){ context.put(variable.getKey(), variable.getValue()); } return context; } /** * Takes Map of image variable name and fileptah of the image to be replaced. Creates IImageprovides and adds the variable in context * @param report * @param variablesToBeReplaced * @param context */ public void replaceImagesVariabalesInTemplate(IXDocReport report, Map<String, String> variablesToBeReplaced, IContext context){ FieldsMetadata metadata = new FieldsMetadata(); for(Map.Entry<String, String> variable: variablesToBeReplaced.entrySet()){ metadata.addFieldAsImage(variable.getKey()); context.put(variable.getKey(), new FileImageProvider(new File(variable.getValue()),true)); } report.setFieldsMetadata(metadata); } /** * Generates byte array as output from merged template * @param report * @param context * @return * @throws XDocReportException * @throws IOException */ public byte[] generateMergedOutput(IXDocReport report,IContext context ) throws XDocReportException, IOException{ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); report.process(context, outputStream); return outputStream.toByteArray(); } /** * Takes inputs and returns merged output as byte[] * @param templatePath * @param templateEngineKind * @param nonImageVariableMap * @param imageVariablesWithPathMap * @return * @throws IOException * @throws XDocReportException */ public byte[] mergeAndGenerateOutput(String templatePath, TemplateEngineKind templateEngineKind, Map<String, Object> nonImageVariableMap,Map<String, String> imageVariablesWithPathMap ) throws IOException, XDocReportException{ InputStream inputStream = loadDocumentAsStream(templatePath); IXDocReport xdocReport = loadDocumentAsIDocxReport(inputStream,templateEngineKind); IContext context = replaceVariabalesInTemplateOtherThanImages(xdocReport,nonImageVariableMap); replaceImagesVariabalesInTemplate(xdocReport, imageVariablesWithPathMap, context); byte[] mergedOutput = generateMergedOutput(xdocReport, context); return mergedOutput; } }

I tested the code using below test case:

/**
 * 
 */
package test.com.sambhashanam.docx;
 
import static org.junit.Assert.*;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
import org.junit.Test;
 
import com.sambhashanam.docx.DocxDocumentMergerAndConverter;
 
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
 
/**
 * @author Dhananjay Jha
 *
 */
public class DocxDocumentMergerAndConverterTest {
 
 
	/**
	 * Test method for {@link com.sambhashanam.docx.DocxDocumentMergerAndConverter#mergeAndGenerateOutput(java.lang.String, fr.opensagres.xdocreport.template.TemplateEngineKind, java.util.Map, java.util.Map)}.
	 * @throws XDocReportException 
	 * @throws IOException 
	 */
	@Test
	public void testMergeAndGenerateOutput() throws IOException, XDocReportException {
 
		String templatePath = "D:\\junoprojects\\docxtopdf\\docx-template\\ThankYouNote_Template.docx";
 
		Map<String, Object> nonImageVariableMap = new HashMap<String, Object>();
		nonImageVariableMap.put("thank_you_date", "24-June-2013");
		nonImageVariableMap.put("name", "Rajani Jha");
		nonImageVariableMap.put("website", "www.sambhashanam.com");
		nonImageVariableMap.put("author_name", "Dhananjay Jha");
		Map<String, String> imageVariablesWithPathMap =new HashMap<String, String>();
		imageVariablesWithPathMap.put("header_image_logo", "D:\\junoprojects\\docxtopdf\\docx-template\\ScreenShot004.jpg");
 
		DocxDocumentMergerAndConverter docxDocumentMergerAndConverter = new DocxDocumentMergerAndConverter();
		byte[] mergedOutput = docxDocumentMergerAndConverter.mergeAndGenerateOutput(templatePath, TemplateEngineKind.Freemarker, nonImageVariableMap, imageVariablesWithPathMap);
		assertNotNull(mergedOutput);
		FileOutputStream os = new FileOutputStream("D:\\junoprojects\\docxtopdf\\docx-template\\ThankYouNote"+System.nanoTime()+".docx");
		os.write(mergedOutput);
		os.flush();
		os.close();
 
	}
 
}

/** * */ package test.com.sambhashanam.docx; import static org.junit.Assert.*; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.junit.Test; import com.sambhashanam.docx.DocxDocumentMergerAndConverter; import fr.opensagres.xdocreport.core.XDocReportException; import fr.opensagres.xdocreport.template.TemplateEngineKind; /** * @author Dhananjay Jha * */ public class DocxDocumentMergerAndConverterTest { /** * Test method for {@link com.sambhashanam.docx.DocxDocumentMergerAndConverter#mergeAndGenerateOutput(java.lang.String, fr.opensagres.xdocreport.template.TemplateEngineKind, java.util.Map, java.util.Map)}. * @throws XDocReportException * @throws IOException */ @Test public void testMergeAndGenerateOutput() throws IOException, XDocReportException { String templatePath = "D:\\junoprojects\\docxtopdf\\docx-template\\ThankYouNote_Template.docx"; Map<String, Object> nonImageVariableMap = new HashMap<String, Object>(); nonImageVariableMap.put("thank_you_date", "24-June-2013"); nonImageVariableMap.put("name", "Rajani Jha"); nonImageVariableMap.put("website", "www.sambhashanam.com"); nonImageVariableMap.put("author_name", "Dhananjay Jha"); Map<String, String> imageVariablesWithPathMap =new HashMap<String, String>(); imageVariablesWithPathMap.put("header_image_logo", "D:\\junoprojects\\docxtopdf\\docx-template\\ScreenShot004.jpg"); DocxDocumentMergerAndConverter docxDocumentMergerAndConverter = new DocxDocumentMergerAndConverter(); byte[] mergedOutput = docxDocumentMergerAndConverter.mergeAndGenerateOutput(templatePath, TemplateEngineKind.Freemarker, nonImageVariableMap, imageVariablesWithPathMap); assertNotNull(mergedOutput); FileOutputStream os = new FileOutputStream("D:\\junoprojects\\docxtopdf\\docx-template\\ThankYouNote"+System.nanoTime()+".docx"); os.write(mergedOutput); os.flush(); os.close(); } }

I have used this ThankYouNote_Template MS word document as template. And the output was as this ThankYouNote13972222961298.

Here is the glimpse of template and final output Merging-Docx-Using-Java

I will writing my next post soon – Merge Microsoft Word document and Convert to PDF document using without IText- Part II

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • Click to share on Google+ (Opens in new window)

Related

Did you like this article? Share it with your friends!

Tweet

Written by Dhananjay Jha

I am a java professional working with a software firm in Noida as "Manager - Product Engineering". I am always keen to learn and share what I have learnt. More professional details about me are available at Linked In and social details are available at facebook and Google Plus. I share my thought in maithili (my mother tongue) at बताह मैथिल and bataahmaithil

Follow me on Twitter
← How to create user define properties in maven pom.xml
Mail merge in java for Microsoft Word document and convert to PDF without iText – Part II →

48 Responses to "Mail merge in java for Microsoft Word document – Part I"

  1. Mallikharjuna says:
    November 5, 2014 at 5:58 pm

    Hai Dhananjay Jha,

    how to replace table placeholdes in the template document, wheather it is possible or not . please tell me

    Reply
    1. Dhananjay Jha says:
      November 6, 2014 at 3:20 pm

      Hello Mallikharjuna,

      Generating table with dynamic data is major requirement in any real application and is very much possible 🙂
      You may follow the link below –
      https://code.google.com/p/xdocreport/wiki/DocxReportingJavaMainListFieldInTable

      Regards
      DJ

      Reply
  2. Vasyl says:
    November 7, 2014 at 2:02 am

    Thanks for this article. You saved my life

    Reply
  3. Prateek Goyal says:
    March 12, 2015 at 7:28 pm

    Hi Dhananjay,

    I just configured the above project project in my workspace but without configuring Maven (i have imported all the dependencies from the pom.xml in the build path) so after configuring the code i am not getting any compilation error and while executing the code as well i am not getting any error but the output docx which is generated is not having the replaced values mentioned in the code
    Can you help me with the same

    Thanks,
    Prateek

    Reply
    1. Dhananjay Jha says:
      May 30, 2015 at 7:34 pm

      Hi Prateek,

      Sorry for late reply – did you modify the template using MS Word 2003?

      Regards
      Dhananjay

      Reply
  4. Arun says:
    August 1, 2015 at 11:02 am

    I m getting this error while executing

    java.lang.NoClassDefFoundError: fr/opensagres/xdocreport/template/TemplateEngineKind
    java.lang.Class.getDeclaredMethods0(Native Method)
    java.lang.Class.privateGetDeclaredMethods(Class.java:2531)
    java.lang.Class.getMethod0(Class.java:2774)
    java.lang.Class.getMethod(Class.java:1663)

    Reply
    1. Dhananjay Jha says:
      August 1, 2015 at 1:46 pm

      Hello Arun,

      Did you follow exact steps mentioned in this article?

      May you please post your pom.xml? I suspect this is due to missing dependency.

      Regards
      DJ

      Reply
  5. Arun says:
    August 1, 2015 at 4:21 pm

    Hi Dhananjay
    i have imported all the dependencies from the pom.xml in the build path
    and configured the above project in my workspace but without configuring Maven

    Reply
    1. Dhananjay Jha says:
      August 1, 2015 at 7:57 pm

      Hello Arun,

      Seems all the dependencies are not imported.

      Is there any challenge using maven?

      Regards
      DJ

      Reply
      1. Arun says:
        August 3, 2015 at 6:06 pm

        Hi Dhananjay Jha

        After converting my project to maven getting following error

        4.0.0
        MLLQMS
        MLLQMS
        0.0.1-SNAPSHOT
        MLLQMS

        Merging Microsoft Word DOCX format with variable replacement using xdocreport

        0.9.8

        fr.opensagres.xdocreport
        fr.opensagres.xdocreport.core
        ${xdocreport.version}

        fr.opensagres.xdocreport
        fr.opensagres.xdocreport.document
        ${xdocreport.version}

        fr.opensagres.xdocreport
        fr.opensagres.xdocreport.document.docx
        ${xdocreport.version}

        fr.opensagres.xdocreport
        fr.opensagres.xdocreport.converter
        ${xdocreport.version}

        fr.opensagres.xdocreport
        fr.opensagres.xdocreport.template.freemarker
        ${xdocreport.version}

        maven-compiler-plugin
        2.3.2

        1.6
        1.6

        org.eclipse.m2e
        lifecycle-mapping
        1.0.0

        org.apache.maven.plugins

        maven-resources-plugin

        [2.5,)

        testResources

        error
        root cause

        java.lang.NoClassDefFoundError: fr/opensagres/xdocreport/core/XDocReportException
        java.lang.Class.getDeclaredConstructors0(Native Method)
        java.lang.Class.privateGetDeclaredConstructors(Class.java:2493)
        java.lang.Class.getConstructor0(Class.java:2803)
        java.lang.Class.newInstance(Class.java:345)
        org.apache.struts.util.RequestUtils.applicationInstance(RequestUtils.java:231)
        org.apache.struts.action.RequestProcessor.processActionCreate(RequestProcessor.java:326)
        org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:268)
        org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
        org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:507)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        com.microlabs.utilities.FilterLogin.doFilter(FilterLogin.java:78)
        com.microlabs.utilities.FilterLogin.doFilter(FilterLogin.java:78)
        org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
        com.microlabs.utilities.FilterLogin.doFilter(FilterLogin.java:78)

        Regards
        Arun

        Reply
        1. Dhananjay Jha says:
          August 4, 2015 at 9:52 pm

          Hello Arun,

          The xml tags got stripped in POM xml you shared – you may send your pom.xml file offline to me at prashaashak (at) sambhashanam (dot) com for review.

          Regards
          Dhananjay

          Reply
        2. Dhananjay Jha says:
          August 19, 2015 at 11:03 pm

          Glad to know Arun that this solution helped you – you may post your issue and solution here so that others can be benefitted

          Regards
          DJ

          Reply
  6. Selena says:
    October 9, 2015 at 2:37 pm

    May I know what was the solution? Is configuring of Maven required?

    Reply
    1. Dhananjay Jha says:
      October 14, 2015 at 7:00 pm

      To get all the required dependencies – Maven configuration is required.

      Hope that helps.

      Regards
      DJ

      Reply
  7. Lucky says:
    October 12, 2015 at 3:26 pm

    Hi, thanks for your nice tutorial. I would like to ask how to create my own mail merge template in Ms Word ? I’ve tried to create new template but the variable format is : <> & it’s different with yours which is : <> ? And my new template can’t be filled at all using the java software above.

    Please advise. Thanks.

    Regards,
    Lucky from Indonesia

    Reply
    1. Dhananjay Jha says:
      October 13, 2015 at 2:08 pm

      Hello Lucky,

      Please refer below link to design the template.

      https://code.google.com/p/xdocreport/wiki/DocxDesignReport#Create_with_MS_Word

      Hope that helps.

      Regards
      Dhananjay Jha

      Reply
      1. Lucky Wijaya says:
        October 27, 2015 at 8:47 am

        I successfully created my own template file. Thank you sir.

        Reply
  8. Stratis Evaggelinos says:
    October 14, 2015 at 1:56 am

    Great article, best solution for my problem!

    Reply
    1. Dhananjay Jha says:
      May 29, 2016 at 10:19 pm

      I am glad to hear this.

      Regards
      Dhananjay Jha

      Reply
  9. ben says:
    October 29, 2015 at 7:56 am

    hello thanks for your note.i want use mail merging in my java app and create certificates from data of bank. is it work for several doc in one file? i give its one template and table of data and it creates for me several page in word file!!!

    Please advise. Thanks.

    Regards,
    Ben

    Reply
    1. Dhananjay Jha says:
      May 29, 2016 at 10:25 pm

      Hello Ben,

      You may have to go for paid solution by docx4j http://www.docx4java.org/blog/2010/11/merging-word-documents/

      Regards
      Dhananjay Jha

      Reply
  10. vikas says:
    January 9, 2016 at 6:05 am

    Does it have to be run on windows?

    Reply
    1. Dhananjay Jha says:
      January 11, 2016 at 1:11 am

      No. Since MS Word 2007+ follows OOXML standard – it can run on any OS that java supports

      Reply
  11. Deepak says:
    January 19, 2016 at 6:12 pm

    Hi,

    Thanks for the example. I have a question. If we create a mail merge field in word and do not supply data for that we get the ${field_name} in the output docx file, how do we get rid of that? If I do not provide data for a field it should not appear in the output docx file.

    Reply
    1. Dhananjay Jha says:
      January 26, 2016 at 8:25 pm

      Hello Deepak,

      It seems you are not following right approach for creating merge fields. Please refer below link to define it correctly.

      Reply
  12. kd_ca says:
    January 22, 2016 at 12:06 am

    Thank you for posting this sample. Have you used XDocReport in production and how has that worked. Thanks.

    Reply
    1. Dhananjay Jha says:
      January 26, 2016 at 8:26 pm

      Hello kd_ca,

      We used it in production and did not notice any problem

      Reply
  13. Vinay Kaushik says:
    February 4, 2016 at 11:12 am

    I dont know about maven dependencies.
    I only know core java. Is it possible to mail merge without maven dependencies.

    Reply
  14. Vinay Kaushik says:
    February 4, 2016 at 11:22 am

    sir I want to do it without pom.xml . I dont know Maven .I wnat to do it in core java.
    Is it possible without pom .xml

    Reply
    1. Dhananjay Jha says:
      May 29, 2016 at 10:31 pm

      Yes – you have to put all the dependencies locally in your classpath.

      Regards
      Dhananjay Jha

      Reply
  15. Ankit says:
    February 4, 2016 at 5:38 pm

    what if i want to check if my value is “YES” or not?
    I have tried –
    <>
    CONTENTS FOR YES
    <>
    CONTENTS IF NOT YES
    >

    ————————-

    <>
    CONTENTS FOR YES
    <>
    CONTENTS IF NOT YES
    >

    —————————

    <>
    CONTENTS FOR YES
    <>
    CONTENTS IF NOT YES
    >

    <>
    CONTENTS FOR YES
    <>
    CONTENTS IF NOT YES
    >

    If anyone can provide me the solution, Please.

    Reply
  16. Ankit says:
    February 4, 2016 at 5:40 pm

    what if i want to check if my value is “YES” or not?
    I have tried –
    #if(${clientInfo.isLLPSubsidiary} == ‘YES’)
    CONTENTS FOR YES
    #else
    CONTENTS IF NOT YES
    #end

    ————————-

    #if ${clientInfo.isLLPSubsidiary} == ‘YES’
    CONTENTS FOR YES
    #else
    CONTENTS IF NOT YES
    #end

    —————————

    #if ${clientInfo.isLLPSubsidiary} == “YES”
    CONTENTS FOR YES
    #else
    CONTENTS IF NOT YES
    #end

    #if ${clientInfo.isLLPSubsidiary} = “YES”
    CONTENTS FOR YES
    #else
    CONTENTS IF NOT YES
    #end

    If anyone can provide me the solution, Please.

    Reply
    1. Dhananjay Jha says:
      May 29, 2016 at 10:16 pm

      Hello Ankit,

      If you are using freemarker as templating engine – I would suggest to refer http://freemarker.org/docs/ for syntax details.

      Regards
      Dhananjay Jha

      Reply
  17. bhaskar ch says:
    March 30, 2016 at 12:21 pm

    Hello sir… Your code is very useful and more informative.

    We followed all the steps as you mentioned and while running we are getting the below mentioned error. COuld you please update us. Thanks in advance.

    Exception in thread “main” fr.opensagres.xdocreport.core.XDocReportException: Impossible to create report for the input stream. The report loader supports only [] files type.
    at fr.opensagres.xdocreport.document.registry.XDocReportRegistry.createReport(XDocReportRegistry.java:367)
    at fr.opensagres.xdocreport.document.registry.XDocReportRegistry.createReport(XDocReportRegistry.java:347)
    at fr.opensagres.xdocreport.document.registry.XDocReportRegistry.loadReport(XDocReportRegistry.java:313)
    at fr.opensagres.xdocreport.document.registry.XDocReportRegistry.loadReport(XDocReportRegistry.java:304)
    at fr.opensagres.xdocreport.document.registry.XDocReportRegistry.loadReport(XDocReportRegistry.java:289)
    at TestingOfmaven.MavenTest.DocxDocumentMergerAndConverter.loadDocumentAsIDocxReport(DocxDocumentMergerAndConverter.java:41)
    at TestingOfmaven.MavenTest.DocxDocumentMergerAndConverter.mergeAndGenerateOutput(DocxDocumentMergerAndConverter.java:99)
    at TestingOfmaven.MavenTest.DocxDocumentMergerAndConverterTest.testMergeAndGenerateOutput(DocxDocumentMergerAndConverterTest.java:35)
    at TestingOfmaven.MavenTest.MailinatorLogin.main(MailinatorLogin.java:24)

    Reply
    1. Dhananjay Jha says:
      May 29, 2016 at 10:12 pm

      Hello bhaskar,

      Suggest you to copy and execute the example given in this article “AS IS” – once it runs successfully, you may decide to change to suit your needs.

      I have seen people start changing the source code and unable to figure out what went wrong.

      Regards
      Dhananjay Jha

      Reply
  18. Andrei says:
    May 27, 2016 at 7:59 pm

    Why do I need to write parameters as «${param}» instead of ${param} in the .docx template?
    If I write ${param}, I get the following error:

    Error: freemarker.core.ParseException: Syntax error in template “fr.opensagres.xdocreport.document.docx.DocxReport@5906c174!word/document.xml” in line 4, column 766:
    Encountered “<", but was expecting one of:

    “false”
    “true”

    “.”
    “+”
    “-”
    “!”
    “[”
    “(”
    “{”

    Also, what is the syntax if I want to use velocity template engine?

    Reply
    1. Dhananjay Jha says:
      May 29, 2016 at 9:57 pm

      Hello Andrei,

      in «${param}» «» denotes mail merge field while ${param} denotes parameter.

      Please note – you should not insert «» manually in the document but follow the step to add a mail-merge field.

      Regards
      Dhananjay Jha

      Reply
  19. Mayank says:
    September 13, 2016 at 12:07 pm

    Hello Dhananjay Jha….

    I am creating template using freemarkar engine….

    I copied complete code as it is , & it works fine for text placeholder…
    But for image plaaceholder , the is not working…

    Instead of image in output template, I am getting Object of FileImageProvider in output..

    Expected Result : Image

    Actual Result : fr.opensagres.xdocreport.document.images.FileImageProvider@6b09bb57

    Please suggest any solution

    Reply
    1. Dhananjay Jha says:
      October 1, 2016 at 8:59 pm

      Hello Mayank,

      Did you put image at the place mentioned in code?

      Regards
      Dhananjay Jha

      Reply
  20. Leo Nelson says:
    September 17, 2016 at 10:43 am

    hai jha,

    how your program can create dynamic table rows ?

    Reply
    1. Dhananjay Jha says:
      October 1, 2016 at 8:57 pm

      Hello Leo,

      Please refer below link:

      https://code.google.com/p/xdocreport/wiki/DocxReportingJavaMainListFieldInTable

      Regards
      Dhananjay Jha

      Reply
  21. Kamala Kannan, Chellapandi says:
    October 14, 2016 at 1:34 pm

    HI, The post is nice. I have question regarding this. Currently I am working on a web proj. In which i had to replace placeholders in docx file. I have tried some api like apache poi, docx4j. Now my problem is, customer wants to add placeholders inside a Layout box like (TEXT INPUT BOX). By using above api’s , I could not read any text inside those layout boxes, thats where my placeholder is.

    Can you please suggest something or help me on this.?

    Reply
  22. Kamala Kannan, Chellapandi says:
    October 15, 2016 at 12:44 am

    HI,

    I am again. I have tried to use IXDocReport its very nice API. Is there a possibility to use custom placeholders except freemaker and velocity. or Is there any way to change the TemplateEngineKind manually?

    Reply
    1. Dhananjay Jha says:
      January 22, 2017 at 8:49 pm

      Hello Kamala,

      What is practical need to change TemplateEngineKind ?

      Regards
      Dhananjay Kumar Jha

      Reply
  23. Ijaj says:
    March 27, 2017 at 2:33 pm

    I am creating template using Office 10.
    I write ${param}, I get the following error:

    Exception in thread “main” freemarker.core.ParseException: Syntax error in template “fr.opensagres.xdocreport.document.docx.DocxReport@1d0ca25a!word/document.xml” in line 4, column 150:
    Encountered “<", but was expecting one of:

    “false”
    “true”

    “.”
    “+”
    “-”
    “!”
    “[”
    “(”
    “{”

    at freemarker.core.FMParser.generateParseException(FMParser.java:5251)
    at freemarker.core.FMParser.jj_consume_token(FMParser.java:5122)
    at freemarker.core.FMParser.UnaryExpression(FMParser.java:450)

    Reply
    1. Dhananjay Jha says:
      April 1, 2017 at 8:23 pm

      Hey Ijaj,

      Please re-check if you have used MS-Word 2007+ for designing the file.

      May you please share your .docx file? Seems the file is corrupt.

      Regards
      Dhananjay

      Reply
  24. muhammad says:
    December 27, 2018 at 7:50 am

    its helpful tutoriall, very kind of yu mr dhananjay

    Reply
  25. muhammad says:
    December 27, 2018 at 8:34 pm

    but how can i get for simbol <>, ceause always called with same value for each variablesw thankyu

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Authors

  • Dhananjay Jha
  • Manish Kumar
  • Sushil Pandey

Recent Comments

  • muhammad on Mail merge in java for Microsoft Word document – Part I
  • muhammad on Mail merge in java for Microsoft Word document – Part I
  • Dhananjay Jha on Mail merge in java for Microsoft Word document and convert to PDF without iText – Part II
  • Clyde Symonette on Mail merge in java for Microsoft Word document and convert to PDF without iText – Part II
  • Dhananjay Kumar Jha on Mail merge in java for Microsoft Word document and convert to PDF without iText – Part II

Tag Cloud

.net activiti activiti-spring activiti bpmn C# change sender mail id in wordpress class classloader Conver MS Word to PDF disable user wordpress dox4j glassfish http response compression java Java Mail Merge MS Word javascript confirmation link on image jax-ws on tomcat jax-ws webservice Jee JTS junit junit-spring Link on Image with hidden URL link load spring configuration load spring configuration xml junit maven maven build Merge MS Word using Java Merge Word Document using XdocReport OOPS oracle weblogic PDF conversion using docx4j php mail function sample activiti process with human task and service task sending mail with attachment spring-orm spring framework spring hibernate spring hibernate integration spring jpa spring jpa hibernate integration tomcat jax-ws web service wordpress wordpress sender email

Looking for old post?

© 2021 Sambhashanam