Java根据FreeMarker模板生成Word(doc)文档(带图片)

前言:

客户需求给定一批word  然后利用代码生成固定格式的word,本例步骤则是 制作模板--读取word--写入模板--生成word

第一步:根据doc文档生成ftl模板

  1:打开文档把需要替换的内容采用" **** "标识  如下图

 

   2:将文档另存为xml格式  然后我们把****替换成freemarker标识,例如我的上述模板替换  ****改为${title}   *****${name}  ******${content}

  此外,在插入图片的地方,会看到一段base64编码后的代码,我们将其替换为${image}

  如果需要循环,则使用:<#list contentLst as  content></#list>  contentLst 是Map<String, Object>中key,值为数组,map为自定义;

  如我本例中的正文需要根据段落来插入  则进行了遍历

  如图

 

   3:将xml文档 改成ftl后缀  则模板就制作完成了

第二步:读取文档,将数据塞入模板重新生成doc

  1:读取ftl模板的代码示例

/**
 * @Author: chenpt
 * @Description:
 * @Date: Created in 2021-04-16 18:12
 * @Modified By:
 */
public class WordUtils {
    //配置信息,代码本身写的还是很可读的,就不过多注解了
    private static Configuration configuration = null;
    //这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
    // private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/templetes/";
    private static final String templateFolder = "D:/test";
    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        try {
            configuration.setDirectoryForTemplateLoading(new File(templateFolder));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

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

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 设置浏览器以下载的方式处理该文件名
            String fileName = title+ DateUtils.formatDateTime(new Date()) + ".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 = "test.doc";
        File f = new File(templateFolder+File.separator+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(String src) {
//        if(src==null||src==""){
//            return "";
//        }
        File file = new File("D:/test/test.png");
        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);
    }

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

        List<String> contentLst = DocUtils.doc2Lst(new File("D:/test/杨浦 .doc"));

        //获得数据
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("title", contentLst.get(0));
        map.put("name", "陈澎涛");
        for(int i=contentLst.size()-1;i>=0;i--){
            if(i==0 || i==1){
                contentLst.remove(i);
            }
        }
        map.put("contentLst",contentLst);
        map.put("file_num", "2021001");
        map.put("username", "陈陈陈");
        map.put("date1", "2021-04-17");
        map.put("department", "上海市");
        map.put("date2", "2021-04-17");
        map.put("image", getImageBase(""));
        try {
            Template freemarkerTemplate = configuration.getTemplate("baitou.ftl");
            WordUtils.createDoc(map,freemarkerTemplate);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
WordUtils

  2:读取doc文档信息

/**
 * @Author: chenpt
 * @Description:
 * @Date: Created in 2021-04-17 15:37
 * @Modified By:
 */
public class DocUtils {
    /**
     * 读取doc文件内容
     * @param fs 想要读取的文件对象
     * @return 返回文件内容
     * @throws IOException
     */
    public static String doc2String(FileInputStream fs) {
        WordExtractor re = null;
        try {
            StringBuilder result = new StringBuilder();
            //获取word的所有文本
            re = new WordExtractor(fs);
            result.append(re.getText());
            return result.toString();
        }catch (Exception e){
            e.getCause();
        }finally {
            try {
                re.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    /**
     * 根据段落读取doc内容  封装成list<段落>
     * @param file 想要读取的文件对象
     * @return 返回文件内容
     * @throws IOException
     */
    public static List<String> doc2Lst(File file) {

        List<String> contentLst = new ArrayList<>();
        WordExtractor re = null;
        try {
            FileInputStream fs = new FileInputStream(file);
            re = new WordExtractor(fs);
            String[] paraTexts = re.getParagraphText();
            for(String s : paraTexts){
                /***去除空格、跳过空行***/
                if(!"".equals(s.trim())){
                    contentLst.add(s.trim());
                }
            }
            return contentLst;
        }catch (Exception e){
            e.getCause();
        }finally {
            try {
                re.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static String doc2String(File file) {
        String res = "";
        try {
            res = doc2String(new FileInputStream(file));
        }catch (Exception e){
            e.printStackTrace();
        }
        return res;
    }

    public static void main(String[] args) {
        File file = new File("D:/test/杨浦 .doc");
        try {

            List<String> strings = doc2Lst(file);
            for (String s : strings){
                System.out.println(s);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
DocUtils

 

测试结果图:

 

posted @ 2021-04-19 15:42  不二尘  阅读(1293)  评论(0编辑  收藏  举报