Java使用FreeMarker自动生成word文档(可遍历生成多张图片)

Java使用FreeMarker自动生成word文档(可遍历生成多张图片)

  1. 前言:最近项目中后台需要自动生成word文档,我以前也没做过,就百度了下,发现还是用freemarker生成word文档最快,但是试了网上的一些方法,都没成功,最后参考着多篇文章慢慢摸索最终成功了。在这记录一下。
  2. 需要实现的效果图
    Java使用FreeMarker自动生成word文档(可遍历生成多张图片)_第1张图片
  3. 首先,导入Jar包依赖
		
			org.freemarker
			freemarker
			2.3.28
		
  1. 制定模板

Java使用FreeMarker自动生成word文档(可遍历生成多张图片)_第2张图片
注意:这一步图片都先别用占位符,因为用占位符就不知道这是图片了(我这种方式我认为是这样的,因为我试过用图片先用占位符,发现一直生成不了图片)

  1. 将模板另存为xml
    Java使用FreeMarker自动生成word文档(可遍历生成多张图片)_第3张图片
    生成xml时,图片全部被转成base64了,这时候需要删除掉,用占位符${user.photo}
    Java使用FreeMarker自动生成word文档(可遍历生成多张图片)_第4张图片
    在这里插入图片描述
  2. 然后直接重命名,将文件格式改为ftl
  3. 接下来需要修改ftl,因为我需要遍历循环生成标题和图片(重点)
    Java使用FreeMarker自动生成word文档(可遍历生成多张图片)_第5张图片
    Java使用FreeMarker自动生成word文档(可遍历生成多张图片)_第6张图片
    Java使用FreeMarker自动生成word文档(可遍历生成多张图片)_第7张图片
    8.至此,模板已经制作完成,下面写代码
package com.chinobot.util.util;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;

/**
 * Word文档工具类
 */
public class WordUtil {

    /**
     * 使用FreeMarker自动生成Word文档
     * @param dataMap   生成Word文档所需要的数据
     * @param fileName  生成Word文档的全路径名称
     */
    public static void generateWord(Map dataMap, String fileName) throws Exception {
        // 设置FreeMarker的版本和编码格式
        Configuration configuration = new Configuration(new Version("2.3.28"));
        configuration.setDefaultEncoding("UTF-8");

        // 设置FreeMarker生成Word文档所需要的模板的路径
        configuration.setClassForTemplateLoading(WordUtil.class, "/templates/code");
        // 设置FreeMarker生成Word文档所需要的模板
        Template t = configuration.getTemplate("zs.ftl", "UTF-8");
        // 创建一个Word文档的输出流
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(fileName)), "UTF-8"));
        //FreeMarker使用Word模板和数据生成Word文档
        t.process(dataMap, out);
        out.flush();
        out.close();
    }

}

package com.chinobot.util.util;

import org.springframework.util.StringUtils;

import org.apache.commons.codec.binary.Base64;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 图片工具类
 */
public class ImageUtil {

    /**
     * 将图片内容转换成Base64编码的字符串
     * @param imageFile 图片文件的全路径名称
     * @return 转换成Base64编码的图片内容字符串
     */
    public static String getImageBase64String(String imageFile) {
        if (StringUtils.isEmpty(imageFile)) {
            return "";
        }
        File file = new File(imageFile);
        if (!file.exists()) {
            return "";
        }
        InputStream is = null;
        byte[] data = null;
        try {
            is = new FileInputStream(file);
            data = new byte[is.available()];
            is.read(data);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return Base64.encodeBase64String(data);
    }

}
package com.chinobot.util.util;
import com.chinobot.util.util.WordUtil;
import com.chinobot.wordxml.entity.FileXml;
import com.chinobot.wordxml.entity.RecordXml;
import com.chinobot.wordxml.entity.UserXml;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Java使用FreeMarker生成Word文档主程序
 */

public class WordApplication {

    public static void main(String[] args) throws Exception {

        /**
         * 自动生成Word文档
         * 注意:生成的文档的后缀名需要为doc,而不能为docx,否则生成的Word文档会出错
         */
        WordUtil.generateWord(getDate(), "d:\\home\\tem\\user3.doc");
    }


    private static Map getDate(){

        Map dataMap = new HashMap<>();
        UserXml user = new UserXml();
        user.setRealName("李红");
        user.setPhoto(ImageUtil.getImageBase64String("d:\\home\\tem\\1.jpg"));
        user.setDateOfBirth("2020-05-11");
        user.setAge("44");
        user.setNation("汉族");
        user.setGender("女");
        user.setIdNumber("362532199812171215");
        user.setInboundTime("2020-25-12");
        user.setInboundWay("康宁医院");
        user.setInBeds("5号床位");
        user.setPhysicalConditions("健康");
        user.setMentalState("正常");
        user.setAddress("广东省深圳市宝安区西乡街道");
        user.setCensusMessage("广东省深圳市");
        user.setMessageCollect("指纹");
        user.setPushChannel("让爱回家 | i深圳");
        dataMap.put("user",user);

        RecordXml record = new RecordXml();
        record.setTitle("线索记录");
        List messagelist = new ArrayList();
        messagelist.add("第一行");
        messagelist.add("第二行");
        record.setMessageList(messagelist);

        RecordXml record2 = new RecordXml();
        record2.setTitle("回复记录");
        List messagelist2 = new ArrayList();
        messagelist2.add("第三行");
        messagelist2.add("第四行");
        record2.setMessageList(messagelist2);

        List recordList = new ArrayList<>();
        recordList.add(record);
        recordList.add(record2);
        dataMap.put("messList",recordList);

        FileXml file = new FileXml();
        file.setTitle("图1  测试标题");
        file.setPic(ImageUtil.getImageBase64String("d:\\home\\tem\\4.png"));

        FileXml file2 = new FileXml();
        file2.setTitle("图2  测试标题2");
        file2.setPic(ImageUtil.getImageBase64String("d:\\home\\tem\\3.jpg"));
        List fileList = new ArrayList<>();
        fileList.add(file);
        fileList.add(file2);
        dataMap.put("fileList",fileList);

        return dataMap;
    }
}
  1. 至此,就已经结束了,当然以上实体类中的属性必须全部不能为空,否者就会报错。
    解决方案:给为空的一个默认值 ${(user.inStationNumber)!’’}
    集合也需要做判断Java使用FreeMarker自动生成word文档(可遍历生成多张图片)_第8张图片
    结束!

你可能感兴趣的:(Java后台,生成word文档,freemarker,java)