java on ftl template generation html and word (realize online preview function, save)

Problem Description:

The earliest attempt has been made to generate word from XML template. Although the file format is retained a lot, the word generated by this template is transferred to html. It is problematic to use XWPF Document and HWPF Document in pure poi, because word is essentially xml, and XML to HTML is not supported for the time being. Besides the above problems, the language of XML template is not supported. There is very little java to learn. When it comes to template adjustment, it usually takes a lot of effort and is very difficult to change successfully. Based on the above situation, I did not use this method.

Later, we tried to extract document.xml form from zip, and compressed dynamic xml into ZIP source file. However, we found that the cost of maintenance increased, and a word and an xml were needed to maintain. The format adjustment always needed to take into account the word template. Moreover, there were still problems when word was transferred to html, although docx lattice could be generated. Documents of the type, but still unable to meet the needs

Of course, Jacob is also possible, but because Jacob's requirements need to be on windows system, so only pass can be removed.

In order to realize ftl to word and html, edit and modify in rich text after transformation, save and convert to word again, and realize online editing and preview of files, the following operation methods are adopted

1. Generating html templates

The original word is saved as

The format of the generated file is not utf-8. It needs to be transcoded. It can be directly converted from Encoding in notepad++ menu bar to UTF-8 encoding.

Delete the xml code of the green part of the image, and modify <meta http-equiv=Content-Type content= "text/html; charset=gb2312"> the charset is utf-8, and the file name suffix is changed to. ftl format.

The content of ftl can be dynamic if it needs dynamic content, referring to freemark's grammar

2. springboot configuration freemark parsing

The jar that needs to be introduced:

<!-- freemarker -->
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

Configure freemarker in application.properties file

#freemarker
spring.freemarker.template-loader-path=classpath:/templates/
spring.freemarker.charset=utf-8
spring.freemarker.cache=false
spring.freemarker.suffix=.ftl

If the project fails to start, it may be that the jar introduced in spring-boot-starter-freemarker conflicts, duplicate introductions, and duplicate jars need to be excluded.

3. ftl generates html and word

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.StringWriter;
import java.util.Map;
import java.io.FileOutputStream;

import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.springframework.web.util.HtmlUtils;

/**
 * @FileNName: WordUtil
 * @Description: word Operating Tool Class
 * @Author: guoxingliang
 * @Create: 2019-08-16 17:08
 * @Copyright: (c)2018 Year***Company
 */
@Slf4j
public class WordUtil {

    private WordUtil() {}

    /**
     * @param content      Page content
     * @param filePath     Target paths for file generation, such as D:/wordFile/
     * @param fileName     Generated file names, such as test.doc
     * @Desc: Generate word file
     * @Author: guoxingliang
     * @Date: 2018-8-22 05:33:42 p.m.
     */
    public static void createWord(String content, String filePath, String fileName) {
        try {
            //output file
            File outFile = new File(filePath + File.separator + fileName);
            //If the output target folder does not exist, create
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdirs();
            }
            content = HtmlUtils.htmlUnescape(StringEscapeUtils.unescapeHtml(content));
            //Format html
            byte[] by = content.getBytes();
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(by);
            POIFSFileSystem poifsFileSystem = new POIFSFileSystem();
            DirectoryEntry directory = poifsFileSystem.getRoot();
            DocumentEntry documentEntry = directory.createDocument("WordDocument", byteArrayInputStream);
            FileOutputStream fileOutputStream = new FileOutputStream(filePath + File.separator + fileName);
            poifsFileSystem.writeFilesystem(fileOutputStream);
            byteArrayInputStream.close();
            fileOutputStream.close();
        } catch (Exception e) {
            log.error("word create fail, exception:", e);
        }
    }

    /**
     * @param dataMap      word The dynamic data to be displayed in the map set is saved
     * @param templateName word Template name, for example: test.ftl
     * @Desc: Generate html files
     * @Author: guoxingliang
     * @Date: 2018-8-22 05:33:42 p.m.
     */
    public static String createHtml(Map dataMap, String templateName) {
        try {
            //Create configuration instances
            Configuration configuration = new Configuration();
            //Set encoding
            configuration.setDefaultEncoding("UTF-8");
            //ftl template files are placed uniformly under the com.lun.template package
            configuration.setClassForTemplateLoading(WordUtil.class, "/templates");
            //Getting Templates
            Template template = configuration.getTemplate(templateName);
            //Combining Template and Data Model to Generate Files
            StringWriter stringWriter = new StringWriter();
            //Generate html
            template.process(dataMap, stringWriter);
            return stringWriter.toString();
        } catch (Exception e) {
            log.error("html create fail, exception:", e);
        }
        return null;
    }
}

4. html string transcoding

Because there are many special characters in html strings, such as t, n, r and double quotation marks for space return, I have done some code conversion here for the sake of processing.

Encryption:
HtmlConversionUtil.replaceBlank(StringEscapeUtils.escapeHtml(WordUtil.createHtml(dataMap, "agreementJurisdiction.ftl")));
//Decrypt:
StringEscapeUtils.unescapeHtml(htmlStr);

replaceBlank Method:
public static String replaceBlank(String str) {
    String dest = "";
    if (str!=null) {
       Pattern p = Pattern.compile("\t|\r|\n");
       Matcher m = p.matcher(str);
       dest = m.replaceAll("");
    }
    return dest;
}

<!-- StringEscapeUtils Dependencies to be introduced -->
<dependency>
     <groupId>commons-lang</groupId>
     <artifactId>commons-lang</artifactId>
     <version>2.5</version>
</dependency>

 

Note: Although the above method can achieve functions, it has not yet involved the support of complex formats such as picture, header and footer.

Tags: FreeMarker xml Java Spring

Posted on Wed, 18 Sep 2019 23:17:23 -0700 by roice