** This article is participating in the Java Theme Month – Java Debug Notes Event, see the event link for details **

The first thing to note is that the documents generated using Freemaker are still XML documents in nature.

The main steps of using Freemaker to generate Word documents are as follows:

Adding dependencies (step 1) -> making templates (steps 2,3,4,5,6) -> programming (steps 7,8,9,10)

Detailed steps:

  1. Download and import the Freemaker -xx.jar package, or add the Freemaker dependency to maven: pom.xml

  2. Modify existing “document.doc” : change the padding to {{paranames}}

  3. Save the document as xxx_template. XML. You are advised to copy and back up a copy of xxx_template-copy.xml.

  4. Open the XML file with a text editor, notepad++/sublineText, etc., and beautify the XML file with a plugin (notepad++ beautify path: XML Tools -> Pretty print), replace {{parames}} with “${paranames}”, some “{{“, “}}” separate remember to merge or delete

  5. For list, the format is

    <#list listitems as item> ... ${item.para1} ... ${item.para2}... </#list>Copy the code
  6. Save as “xxx_template FTL”

  7. Create template file path package in the project:…. Template. package, whatever package name you like

  8. Create mdoc. Java class from mdoc. Java

    /*** * MDoc class, generate files from templates and data */
    package com.xxxxx.export.doc.template;
    
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.UnsupportedEncodingException;
    import java.io.Writer;
    import java.util.Map;
    
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    import freemarker.template.TemplateException;
    
    public class MDoc {
    	private Configuration configuration = null;
    	public MDoc(a) {
    		configuration = new Configuration(Configuration.getVersion());
    		configuration.setDefaultEncoding("utf-8");
    	}
    	
    	/ * * * *@paramDataMap the data to fill in the template *@paramFileName File path *@paramTemplate Specifies the name of the template file, for example, "xxx.ftl" *@throws UnsupportedEncodingException
    	 */
    	public void createDoc(Map<String, Object> dataMap, String fileName, String template) throws UnsupportedEncodingException {
    		// dataMap The data file to fill in the template
    		// Our template is placed in the same package path as this one
    		configuration.setClassForTemplateLoading(MDoc.class, "/" + MDoc.class.getPackage().getName().replace("."."/"));
    		Template t = null;
    		try {
    			t = configuration.getTemplate(template);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		// Output the file path and name
    		File outFile = new File(fileName);
    		Writer out = null;
    		FileOutputStream fos = null;
    		try {
    			fos = new FileOutputStream(outFile);
    			OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8");
    			// This place is indispensable to the encoding of the stream. It should work when called by main () alone, but if exported by web request, the word document will not open and the package XML file will be wrong. The main reason is that the encoding format is not correct and cannot be parsed.
    			out = new BufferedWriter(oWriter);
    		} catch (FileNotFoundException e1) {
    			e1.printStackTrace();
    		}
     
    		try {
    			t.process(dataMap, out);
    			out.close();
    			fos.close();
    		} catch (TemplateException e) {
    			e.printStackTrace();
    		} catch(IOException e) { e.printStackTrace(); }}}Copy the code
  9. Copy xxx_template. FTL to the same package path.

  10. The key code for calling the method is as follows:

String filepath = "D://.... /filename.doc";
MDoc mdoc = new MDoc();
try {
	mdoc.createDoc(dataMap, filepath, "xxx_template.ftl");
} catch (UnsupportedEncodingException e) {
	LogKit.error("Error exporting word: e =" + e.getMessage());
}
File outputfile = newFile(filepath); .Copy the code

Some additional requirements implementations that may be required:

  1. Insert picture:

    You need to convert the image link to base64 format and place it in the template.

    <! ${pic_index} -->.<! -- Resource index -->
    <#list picUrls as picUrl>
    	<Relationship Id="rId${picUrl_index}Png" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image${memUrl_index}.png"/>
    </#list>
    ...
    <! -- Base64 resources -->
    <#list picUrls as picUrl>
    	<pkg:part pkg:name="/word/media/image${picUrl_index}.png" pkg:contentType="image/png" pkg:compression="store">
    		<pkg:binaryData>${picUrl.imageBase64! "'}</pkg:binaryData>
    	</pkg:part>
    </#list>
    ...
    <! -- reference, place only the key code, use template to create -->
    <a:blip r:embed="rId${picUrl_index}Png" cstate="print">.Copy the code
  2. Wrap:

    paraHaveLineBreak.replaceAll("/n"."<w:br/>")
    Copy the code