zoukankan      html  css  js  c++  java
  • 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

    测试结果图:

    作者: 不二尘
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    k8s pod 定义 文件 yaml
    动态规划(1)
    Angular封装WangEditor富文本组件
    使用Angular CDK实现一个Service弹出Toast组件
    让Angular自定义组件支持form表单验证
    等了半年,m1芯片原生支持的.NET IDE出现了
    eachrt
    dgy
    开源节流
    company
  • 原文地址:https://www.cnblogs.com/chenpt/p/14677093.html
Copyright © 2011-2022 走看看