java实现doc模板实现ftl动态获取数据并生成doc文件(带图片)

一、 制作模板

如下图,我们一般需要给出固定模板,按照模板通过freemarker语法写成图二的格式,然后另存为xml格式,最后通过更改后缀名改为ftl页面。
图解:

  1. 给出模板

在这里插入图片描述
2. 通过freemarker语法把需要从数据库取出的来值抽象化

此处的user为别名

在这里插入图片描述
3. 另存为XML文件
在这里插入图片描述
4. 打开之后的界面
在这里插入图片描述
因为不是很利于阅读和修改,所以我们放在idea或者在线格式化工具中进行格式化。这里我用idea进行格式化。
在这里插入图片描述
5. 然后我们进行编辑,我们使用freemarker语法进行循环取值。

在文件中搜索 ‘<w:body>’ 关键字,在该标签后面 添加 <#list list as user> 在搜索 </w:body> 标签,在该标签前面添加 </#list> 标签。如下图所示:
在这里插入图片描述
注意:在这里插入图片描述
图中红框部分必须为一个整体,如果中间多了一些标签和其他元素,直接删掉即可

  1. 然后我们进行图片处理,直接搜索<w:pict> 标签,我们会看到,下图所示的图片信息(当word另存为xml的时候,其中的图片会以Base64编码形式展示在xml文件的特定位置)
    在这里插入图片描述
    我们需要把<w:binData></w:binData>之间的Base64图片信息改成freemarker语法。这里不需要担心图片的样式问题,你在word上制作模板的时候把图片的样式调整为你想要的即可,结果输出的时候也会是你制作模板的样式。如下图所示:
    在这里插入图片描述
  2. 把全部代码另存为 .ftl 后缀的文件,或者直接改后缀也可以。把文件放在需要的地方。
    在这里插入图片描述

这样我们的模板就算改好了。下来就是代码实现的问题了。

二、 代码实现读取数据库数据 ,并输出到word文档上
  1. 读取数据库,获取数据。代码如下:
   public void geeneratorWord (String id, HttpServletResponse response, HttpServletRequest request) {
        try {
            //桌面
            String filePath="C:/Users/lenovo/Desktop/";
             //ftl 文件名称
            String ftlName="test_ft.ftl";

            HashMap<String, Object> params = new HashMap<String, Object>();
            params.put("userIds", id);
            List<HashMap<String, Object>> data = (List<HashMap<String, Object>>) dao.get("test.sql.generatorWord", params);
            //word 中的数据
            List<HashMap<String, Object>> mapList = new ArrayList<HashMap<String, Object>>();
            //循环取出来的用户信息,有几个用户,生成几个
            for (int i = 0; i < data.size(); i++) {
                HashMap<String, Object> userMap = new HashMap<String, Object>();
                //放user 信息
                userMap.put("user_name", data.get(i).get("user_name"));
                userMap.put("org_name", data.get(i).get("org_name"));
                userMap.put("job_name", data.get(i).get("job_name"));
                userMap.put("code_no", data.get(i).get("code_num"));
                userMap.put("project_name", data.get(i).get("project_name"));

                //头像信息
                String imgAvatar = "";
                //头像存储路径
                String imgAvatarPic = "";
                imgAvatar =(String) data.get(i).get("avatar");

                if (StringUtils.isNotBlank(imgAvatar)) {
                    //存到库的人员头像信息
                    imgAvatarPic = WordUtil.getImageBase(new File(filePath + data.get(i).get("file_name")));
                }else {
                    //人员照片不存在,展示默认照片
                    imgAvatarPic = WordUtil.getImageBase(new File(filePath + "default.png"));
                }

                userMap.put("photo", imgAvatarPic);
			//把用户信息,添加到list中
                mapList.add(userMap);
            }

            HashMap<String, Object> wordList = new HashMap<String, Object>();
            wordList.put("list", mapList);
            
            //生成word文档
            WordUtil.exportMillCertificateWord(response, wordList,ftlName);
            
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
  1. 生成word文档工具类
public class WordUtil {

    private static Configuration configuration = null;
    

    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        try {
            File file = new File("C:/Users/lenovo/Desktop/");
            if(!file.exists()){
                file.mkdirs();
            }
            configuration.setDirectoryForTemplateLoading(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }


    private WordUtil() {
        throw new AssertionError();
    }


    /**
     * @author dzk
     * @param response
     * @param list
     * @throws IOException
     */
    public static void exportMillCertificateWord(HttpServletResponse response, Map list,String ftlName) throws IOException {
        Template freemarkerTemplate = configuration.getTemplate(ftlName);
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(list,freemarkerTemplate);
            fin = new FileInputStream(file);

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 设置浏览器以下载的方式处理该文件名
            String fileName = "temp"+ DateFormatUtils.format(new Date(),"yyyyMMddHHmmss") + ".doc";
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));

            out = response.getOutputStream();
            byte[] buffer = new byte[512];  // 缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中  
            while((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } finally {
            if(fin != null) fin.close();
            if(out != null) out.close();
            if(file != null) file.delete(); // 删除临时文件  
        }
    }

    private static File createDoc(Map<?, ?> dataMap, Template template) {
        String name =  "temp.doc";
        File f = new File(name);
        Template t = template;
        try {
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开  
            Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }


    //获得图片的base64码
    public static String getImageBase(File file) {

        if(!file.exists()) {
            return "";
        }
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(file);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        try {
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }
//	  main 
//    public static void main(String[] args) {
//        /*String path =WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/templetes/";*/
//        System.out.println(WordUtil.class.getResource("").toString());
//    }
}

freemarker版本和commons-lang版本

org.freemarker:freemarker:2.3.29
org.apache.commons:commons-lang3:3.6

  1. 效果图
    在这里插入图片描述

综上,就可以根据模板生成我们想要的word文档啦。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值